diff --git a/cmd/seccompagent/seccompagent.go b/cmd/seccompagent/seccompagent.go index 5d3d37c0..e530df78 100644 --- a/cmd/seccompagent/seccompagent.go +++ b/cmd/seccompagent/seccompagent.go @@ -42,9 +42,9 @@ import ( ) var ( - socketFile string - resolverParam string - logflags string + socketFile string + resolverParam string + logflags string metricsBindAddress string ) @@ -97,6 +97,16 @@ func main() { switch resolverParam { case "none", "": resolver = nil + case "falco": + resolver = func(state *specs.ContainerProcessState) *registry.Registry { + r := registry.New() + podCtx := &kuberesolver.PodContext{ + Pid: state.State.Pid, + Pid1: state.Pid, + } + r.MiddlewareHandlers = append(r.MiddlewareHandlers, falco.NotifyFalco(podCtx)) + return r + } case "demo-basic": // Using the resolver allows to implement different behaviour // depending on the container. For example, you could connect to the diff --git a/falco-plugin/Dockerfile b/falco-plugin/Dockerfile index 4b14dd0c..6cbe227d 100644 --- a/falco-plugin/Dockerfile +++ b/falco-plugin/Dockerfile @@ -8,8 +8,21 @@ RUN cd /src && go mod download COPY ./ /src RUN cd /src && make -C falco-plugin -# Use the following command to get the built files: -# DOCKER_BUILDKIT=1 docker build -f falco-plugin/Dockerfile --output=falco-plugin/ . -FROM scratch AS deploy-source -COPY --from=builder /src/falco-plugin/*.so / +FROM falcosecurity/falco-no-driver:0.35.1 + +SHELL ["/bin/bash", "-c"] + +COPY falco-plugin/falco-config-plugin-snippet.yaml /etc/falco/ +COPY falco-plugin/seccomp_agent_rules.yaml /etc/falco/rules.d/ + +RUN \ + SNIPPET="$(jq -Rs . < /etc/falco/falco-config-plugin-snippet.yaml)" && \ + SNIPPET="${SNIPPET:1}" && \ + SNIPPET="${SNIPPET/%?/}" && \ + sed -i \ + -e '/^plugins:$/a \'"$SNIPPET" \ + -e 's/^load_plugins:.*$/load_plugins: [seccompagent]/' \ + /etc/falco/falco.yaml && \ + rm -f /etc/falco/falco-config-plugin-snippet.yaml +COPY --from=builder /src/falco-plugin/*.so /usr/share/falco/plugins/ diff --git a/falco-plugin/Dockerfile.dockerignore b/falco-plugin/Dockerfile.dockerignore new file mode 100644 index 00000000..dd449725 --- /dev/null +++ b/falco-plugin/Dockerfile.dockerignore @@ -0,0 +1 @@ +*.md diff --git a/falco-plugin/README.md b/falco-plugin/README.md new file mode 100644 index 00000000..e54717bd --- /dev/null +++ b/falco-plugin/README.md @@ -0,0 +1,48 @@ +# seccompagent Falco plugin + +## Build the plugin standalone + +``` +make -C falco-plugin +ls -l falco-plugin/libseccompagent.so +``` + +## Build a Falco container image with the plugin + +``` +export CONTAINER_REPO=${USER}test.azurecr.io/falco-with-seccompagent +export TAG=$CONTAINER_REPO:dev +docker build -f falco-plugin/Dockerfile -t $TAG . +docker push $TAG +``` + +## Run Falco with the plugin + +Start Falco in a container as previously compiled: +``` +docker run --rm -i -t \ + --privileged \ + -v /var/run/docker.sock:/host/var/run/docker.sock \ + -v /run/seccomp-agent-falco-plugin:/run/seccomp-agent-falco-plugin \ + -v /proc:/host/proc:ro \ + $TAG falco --modern-bpf +``` + +Start the Seccomp Agent: +``` +sudo ./seccompagent -resolver=falco -log trace +``` + +Launch a container and run a command: +``` +$ docker run --rm -it \ + --security-opt \ + seccomp=falco-plugin/seccomp-profile-demo.json \ + busybox +/ # mkdir /a +``` + +Falco logs the following: +``` +Notice The seccomp agent detected a mkdir... +``` diff --git a/falco-plugin/falco-config-plugin-snippet.yaml b/falco-plugin/falco-config-plugin-snippet.yaml new file mode 100644 index 00000000..643f1910 --- /dev/null +++ b/falco-plugin/falco-config-plugin-snippet.yaml @@ -0,0 +1,5 @@ + - name: seccompagent + library_path: libseccompagent.so + init_config: + socketFile: /run/seccomp-agent-falco-plugin/seccomp-agent-falco-plugin.sock + flushInterval: 30 diff --git a/falco-plugin/seccomp-profile-demo.json b/falco-plugin/seccomp-profile-demo.json new file mode 100644 index 00000000..2dcbaf20 --- /dev/null +++ b/falco-plugin/seccomp-profile-demo.json @@ -0,0 +1,16 @@ +{ + "defaultAction": "SCMP_ACT_ALLOW", + "architectures": [ + "SCMP_ARCH_X86_64" + ], + "listenerPath": "/run/seccomp-agent.socket", + "listenerMetadata": "MIDDLEWARE=falco", + "syscalls": [ + { + "action": "SCMP_ACT_NOTIFY", + "names": [ + "mkdir" + ] + } + ] +} diff --git a/falco-plugin/seccomp_agent_rules.yaml b/falco-plugin/seccomp_agent_rules.yaml index 37267593..2b38796a 100644 --- a/falco-plugin/seccomp_agent_rules.yaml +++ b/falco-plugin/seccomp_agent_rules.yaml @@ -2,8 +2,19 @@ - rule: Seccomp Agent desc: Seccomp Agent - condition: seccompagent.syscall != "" - output: id=%seccompagent.id pid=%seccompagent.pid syscall=%seccompagent.syscall k8s=(namespace=%seccompagent.k8s.namespace pod=%seccompagent.k8s.pod container=%seccompagent.k8s.container pid=%seccompagent.k8s.pid pidfilter=%seccompagent.k8s.pidfilter) - priority: DEBUG + condition: seccompagent.syscall == "mkdir" + output: > + The seccomp agent detected a mkdir: + id=%seccompagent.id + pid=%seccompagent.pid + syscall=%seccompagent.syscall + k8s=( + namespace=%seccompagent.k8s.namespace + pod=%seccompagent.k8s.pod + container=%seccompagent.k8s.container + pid=%seccompagent.k8s.pid + pidfilter=%seccompagent.k8s.pidfilter + ) + priority: NOTICE source: seccompagent tags: [seccompagent] diff --git a/go.mod b/go.mod index 35704b00..bd430698 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/kinvolk/seccompagent go 1.18 require ( - github.com/falcosecurity/plugin-sdk-go v0.4.0 + github.com/falcosecurity/plugin-sdk-go v0.7.1 github.com/inspektor-gadget/inspektor-gadget v0.12.1 github.com/opencontainers/runc v1.1.0 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 diff --git a/go.sum b/go.sum index 6b899d52..be495193 100644 --- a/go.sum +++ b/go.sum @@ -1,47 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -80,9 +43,10 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/falcosecurity/plugin-sdk-go v0.4.0 h1:gsRgA75JNJ73HzBYMkVnKz/Rze14cEg5IKrpdEO1zKM= -github.com/falcosecurity/plugin-sdk-go v0.4.0/go.mod h1:9IdFIqRwJIFDfKnwTTM6S4mLITNfdjVl+5r4RY0TmRo= +github.com/falcosecurity/plugin-sdk-go v0.7.1 h1:tVi5MdQ9dq6i5f5R29ufhsgKs0gYOXLZQ4d83gEbanE= +github.com/falcosecurity/plugin-sdk-go v0.7.1/go.mod h1:NP+y22DYOS+G3GDXIXNmzf0CBL3nfPPMoQuHvAzfitQ= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -130,6 +94,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -146,8 +111,10 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -166,11 +133,15 @@ github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8= github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= @@ -182,6 +153,7 @@ github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921 h1:58EBmR2dMNL2n/FnbQewK3D14nXr0V9CObDSvMJLq+Y= github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= @@ -189,17 +161,28 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -319,6 +302,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/handlers/falco/falco.go b/pkg/handlers/falco/falco.go index e4ef4f75..a14a1e12 100644 --- a/pkg/handlers/falco/falco.go +++ b/pkg/handlers/falco/falco.go @@ -18,16 +18,17 @@ import ( "context" "time" - pb "github.com/kinvolk/seccompagent/falco-plugin/api" libseccomp "github.com/seccomp/libseccomp-golang" log "github.com/sirupsen/logrus" "google.golang.org/grpc" + pb "github.com/kinvolk/seccompagent/falco-plugin/api" + "github.com/kinvolk/seccompagent/pkg/kuberesolver" "github.com/kinvolk/seccompagent/pkg/registry" ) -const socketfile = "/run/seccomp-agent-falco-plugin.sock" +const socketfile = "/run/seccomp-agent-falco-plugin/seccomp-agent-falco-plugin.sock" func NotifyFalco(podCtx *kuberesolver.PodContext) func(h registry.HandlerFunc) registry.HandlerFunc { return func(h registry.HandlerFunc) registry.HandlerFunc { @@ -77,11 +78,16 @@ func NotifyFalco(podCtx *kuberesolver.PodContext) func(h registry.HandlerFunc) r }).Error("Error in sending event to Falco") } - r := h(fd, req) + var r registry.HandlerResult + if h != nil { + r = h(fd, req) + } else { + r = registry.HandlerResultContinue() + } log.WithFields(log.Fields{ "pod": podCtx, - }).Error("Falco middleware completed") + }).Debug("Falco middleware completed") return r } } diff --git a/vendor/github.com/PuerkitoBio/purell/.gitignore b/vendor/github.com/PuerkitoBio/purell/.gitignore deleted file mode 100644 index 748e4c80..00000000 --- a/vendor/github.com/PuerkitoBio/purell/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.sublime-* -.DS_Store -*.swp -*.swo -tags diff --git a/vendor/github.com/PuerkitoBio/purell/.travis.yml b/vendor/github.com/PuerkitoBio/purell/.travis.yml deleted file mode 100644 index cf31e6af..00000000 --- a/vendor/github.com/PuerkitoBio/purell/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go - -go: - - 1.4.x - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - - "1.10.x" - - "1.11.x" - - tip diff --git a/vendor/github.com/PuerkitoBio/purell/LICENSE b/vendor/github.com/PuerkitoBio/purell/LICENSE deleted file mode 100644 index 4b9986de..00000000 --- a/vendor/github.com/PuerkitoBio/purell/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012, Martin Angers -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 author 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/PuerkitoBio/purell/README.md b/vendor/github.com/PuerkitoBio/purell/README.md deleted file mode 100644 index 07de0c49..00000000 --- a/vendor/github.com/PuerkitoBio/purell/README.md +++ /dev/null @@ -1,188 +0,0 @@ -# Purell - -Purell is a tiny Go library to normalize URLs. It returns a pure URL. Pure-ell. Sanitizer and all. Yeah, I know... - -Based on the [wikipedia paper][wiki] and the [RFC 3986 document][rfc]. - -[![build status](https://travis-ci.org/PuerkitoBio/purell.svg?branch=master)](http://travis-ci.org/PuerkitoBio/purell) - -## Install - -`go get github.com/PuerkitoBio/purell` - -## Changelog - -* **v1.1.1** : Fix failing test due to Go1.12 changes (thanks to @ianlancetaylor). -* **2016-11-14 (v1.1.0)** : IDN: Conform to RFC 5895: Fold character width (thanks to @beeker1121). -* **2016-07-27 (v1.0.0)** : Normalize IDN to ASCII (thanks to @zenovich). -* **2015-02-08** : Add fix for relative paths issue ([PR #5][pr5]) and add fix for unnecessary encoding of reserved characters ([see issue #7][iss7]). -* **v0.2.0** : Add benchmarks, Attempt IDN support. -* **v0.1.0** : Initial release. - -## Examples - -From `example_test.go` (note that in your code, you would import "github.com/PuerkitoBio/purell", and would prefix references to its methods and constants with "purell."): - -```go -package purell - -import ( - "fmt" - "net/url" -) - -func ExampleNormalizeURLString() { - if normalized, err := NormalizeURLString("hTTp://someWEBsite.com:80/Amazing%3f/url/", - FlagLowercaseScheme|FlagLowercaseHost|FlagUppercaseEscapes); err != nil { - panic(err) - } else { - fmt.Print(normalized) - } - // Output: http://somewebsite.com:80/Amazing%3F/url/ -} - -func ExampleMustNormalizeURLString() { - normalized := MustNormalizeURLString("hTTpS://someWEBsite.com:443/Amazing%fa/url/", - FlagsUnsafeGreedy) - fmt.Print(normalized) - - // Output: http://somewebsite.com/Amazing%FA/url -} - -func ExampleNormalizeURL() { - if u, err := url.Parse("Http://SomeUrl.com:8080/a/b/.././c///g?c=3&a=1&b=9&c=0#target"); err != nil { - panic(err) - } else { - normalized := NormalizeURL(u, FlagsUsuallySafeGreedy|FlagRemoveDuplicateSlashes|FlagRemoveFragment) - fmt.Print(normalized) - } - - // Output: http://someurl.com:8080/a/c/g?c=3&a=1&b=9&c=0 -} -``` - -## API - -As seen in the examples above, purell offers three methods, `NormalizeURLString(string, NormalizationFlags) (string, error)`, `MustNormalizeURLString(string, NormalizationFlags) (string)` and `NormalizeURL(*url.URL, NormalizationFlags) (string)`. They all normalize the provided URL based on the specified flags. Here are the available flags: - -```go -const ( - // Safe normalizations - FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1 - FlagLowercaseHost // http://HOST -> http://host - FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF - FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA - FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$ - FlagRemoveDefaultPort // http://host:80 -> http://host - FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path - - // Usually safe normalizations - FlagRemoveTrailingSlash // http://host/path/ -> http://host/path - FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags) - FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c - - // Unsafe normalizations - FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/ - FlagRemoveFragment // http://host/path#fragment -> http://host/path - FlagForceHTTP // https://host -> http://host - FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b - FlagRemoveWWW // http://www.host/ -> http://host/ - FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags) - FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3 - - // Normalizations not in the wikipedia article, required to cover tests cases - // submitted by jehiah - FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147 - FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147 - FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147 - FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path - FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path - - // Convenience set of safe normalizations - FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator - - // For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags, - // while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix". - - // Convenience set of usually safe normalizations (includes FlagsSafe) - FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments - FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments - - // Convenience set of unsafe normalizations (includes FlagsUsuallySafe) - FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery - FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery - - // Convenience set of all available flags - FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator - FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator -) -``` - -For convenience, the set of flags `FlagsSafe`, `FlagsUsuallySafe[Greedy|NonGreedy]`, `FlagsUnsafe[Greedy|NonGreedy]` and `FlagsAll[Greedy|NonGreedy]` are provided for the similarly grouped normalizations on [wikipedia's URL normalization page][wiki]. You can add (using the bitwise OR `|` operator) or remove (using the bitwise AND NOT `&^` operator) individual flags from the sets if required, to build your own custom set. - -The [full godoc reference is available on gopkgdoc][godoc]. - -Some things to note: - -* `FlagDecodeUnnecessaryEscapes`, `FlagEncodeNecessaryEscapes`, `FlagUppercaseEscapes` and `FlagRemoveEmptyQuerySeparator` are always implicitly set, because internally, the URL string is parsed as an URL object, which automatically decodes unnecessary escapes, uppercases and encodes necessary ones, and removes empty query separators (an unnecessary `?` at the end of the url). So this operation cannot **not** be done. For this reason, `FlagRemoveEmptyQuerySeparator` (as well as the other three) has been included in the `FlagsSafe` convenience set, instead of `FlagsUnsafe`, where Wikipedia puts it. - -* The `FlagDecodeUnnecessaryEscapes` decodes the following escapes (*from -> to*): - - %24 -> $ - - %26 -> & - - %2B-%3B -> +,-./0123456789:; - - %3D -> = - - %40-%5A -> @ABCDEFGHIJKLMNOPQRSTUVWXYZ - - %5F -> _ - - %61-%7A -> abcdefghijklmnopqrstuvwxyz - - %7E -> ~ - - -* When the `NormalizeURL` function is used (passing an URL object), this source URL object is modified (that is, after the call, the URL object will be modified to reflect the normalization). - -* The *replace IP with domain name* normalization (`http://208.77.188.166/ → http://www.example.com/`) is obviously not possible for a library without making some network requests. This is not implemented in purell. - -* The *remove unused query string parameters* and *remove default query parameters* are also not implemented, since this is a very case-specific normalization, and it is quite trivial to do with an URL object. - -### Safe vs Usually Safe vs Unsafe - -Purell allows you to control the level of risk you take while normalizing an URL. You can aggressively normalize, play it totally safe, or anything in between. - -Consider the following URL: - -`HTTPS://www.RooT.com/toto/t%45%1f///a/./b/../c/?z=3&w=2&a=4&w=1#invalid` - -Normalizing with the `FlagsSafe` gives: - -`https://www.root.com/toto/tE%1F///a/./b/../c/?z=3&w=2&a=4&w=1#invalid` - -With the `FlagsUsuallySafeGreedy`: - -`https://www.root.com/toto/tE%1F///a/c?z=3&w=2&a=4&w=1#invalid` - -And with `FlagsUnsafeGreedy`: - -`http://root.com/toto/tE%1F/a/c?a=4&w=1&w=2&z=3` - -## TODOs - -* Add a class/default instance to allow specifying custom directory index names? At the moment, removing directory index removes `(^|/)((?:default|index)\.\w{1,4})$`. - -## Thanks / Contributions - -@rogpeppe -@jehiah -@opennota -@pchristopher1275 -@zenovich -@beeker1121 - -## License - -The [BSD 3-Clause license][bsd]. - -[bsd]: http://opensource.org/licenses/BSD-3-Clause -[wiki]: http://en.wikipedia.org/wiki/URL_normalization -[rfc]: http://tools.ietf.org/html/rfc3986#section-6 -[godoc]: http://go.pkgdoc.org/github.com/PuerkitoBio/purell -[pr5]: https://github.com/PuerkitoBio/purell/pull/5 -[iss7]: https://github.com/PuerkitoBio/purell/issues/7 diff --git a/vendor/github.com/PuerkitoBio/purell/purell.go b/vendor/github.com/PuerkitoBio/purell/purell.go deleted file mode 100644 index 6d0fc190..00000000 --- a/vendor/github.com/PuerkitoBio/purell/purell.go +++ /dev/null @@ -1,379 +0,0 @@ -/* -Package purell offers URL normalization as described on the wikipedia page: -http://en.wikipedia.org/wiki/URL_normalization -*/ -package purell - -import ( - "bytes" - "fmt" - "net/url" - "regexp" - "sort" - "strconv" - "strings" - - "github.com/PuerkitoBio/urlesc" - "golang.org/x/net/idna" - "golang.org/x/text/unicode/norm" - "golang.org/x/text/width" -) - -// A set of normalization flags determines how a URL will -// be normalized. -type NormalizationFlags uint - -const ( - // Safe normalizations - FlagLowercaseScheme NormalizationFlags = 1 << iota // HTTP://host -> http://host, applied by default in Go1.1 - FlagLowercaseHost // http://HOST -> http://host - FlagUppercaseEscapes // http://host/t%ef -> http://host/t%EF - FlagDecodeUnnecessaryEscapes // http://host/t%41 -> http://host/tA - FlagEncodeNecessaryEscapes // http://host/!"#$ -> http://host/%21%22#$ - FlagRemoveDefaultPort // http://host:80 -> http://host - FlagRemoveEmptyQuerySeparator // http://host/path? -> http://host/path - - // Usually safe normalizations - FlagRemoveTrailingSlash // http://host/path/ -> http://host/path - FlagAddTrailingSlash // http://host/path -> http://host/path/ (should choose only one of these add/remove trailing slash flags) - FlagRemoveDotSegments // http://host/path/./a/b/../c -> http://host/path/a/c - - // Unsafe normalizations - FlagRemoveDirectoryIndex // http://host/path/index.html -> http://host/path/ - FlagRemoveFragment // http://host/path#fragment -> http://host/path - FlagForceHTTP // https://host -> http://host - FlagRemoveDuplicateSlashes // http://host/path//a///b -> http://host/path/a/b - FlagRemoveWWW // http://www.host/ -> http://host/ - FlagAddWWW // http://host/ -> http://www.host/ (should choose only one of these add/remove WWW flags) - FlagSortQuery // http://host/path?c=3&b=2&a=1&b=1 -> http://host/path?a=1&b=1&b=2&c=3 - - // Normalizations not in the wikipedia article, required to cover tests cases - // submitted by jehiah - FlagDecodeDWORDHost // http://1113982867 -> http://66.102.7.147 - FlagDecodeOctalHost // http://0102.0146.07.0223 -> http://66.102.7.147 - FlagDecodeHexHost // http://0x42660793 -> http://66.102.7.147 - FlagRemoveUnnecessaryHostDots // http://.host../path -> http://host/path - FlagRemoveEmptyPortSeparator // http://host:/path -> http://host/path - - // Convenience set of safe normalizations - FlagsSafe NormalizationFlags = FlagLowercaseHost | FlagLowercaseScheme | FlagUppercaseEscapes | FlagDecodeUnnecessaryEscapes | FlagEncodeNecessaryEscapes | FlagRemoveDefaultPort | FlagRemoveEmptyQuerySeparator - - // For convenience sets, "greedy" uses the "remove trailing slash" and "remove www. prefix" flags, - // while "non-greedy" uses the "add (or keep) the trailing slash" and "add www. prefix". - - // Convenience set of usually safe normalizations (includes FlagsSafe) - FlagsUsuallySafeGreedy NormalizationFlags = FlagsSafe | FlagRemoveTrailingSlash | FlagRemoveDotSegments - FlagsUsuallySafeNonGreedy NormalizationFlags = FlagsSafe | FlagAddTrailingSlash | FlagRemoveDotSegments - - // Convenience set of unsafe normalizations (includes FlagsUsuallySafe) - FlagsUnsafeGreedy NormalizationFlags = FlagsUsuallySafeGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagRemoveWWW | FlagSortQuery - FlagsUnsafeNonGreedy NormalizationFlags = FlagsUsuallySafeNonGreedy | FlagRemoveDirectoryIndex | FlagRemoveFragment | FlagForceHTTP | FlagRemoveDuplicateSlashes | FlagAddWWW | FlagSortQuery - - // Convenience set of all available flags - FlagsAllGreedy = FlagsUnsafeGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator - FlagsAllNonGreedy = FlagsUnsafeNonGreedy | FlagDecodeDWORDHost | FlagDecodeOctalHost | FlagDecodeHexHost | FlagRemoveUnnecessaryHostDots | FlagRemoveEmptyPortSeparator -) - -const ( - defaultHttpPort = ":80" - defaultHttpsPort = ":443" -) - -// Regular expressions used by the normalizations -var rxPort = regexp.MustCompile(`(:\d+)/?$`) -var rxDirIndex = regexp.MustCompile(`(^|/)((?:default|index)\.\w{1,4})$`) -var rxDupSlashes = regexp.MustCompile(`/{2,}`) -var rxDWORDHost = regexp.MustCompile(`^(\d+)((?:\.+)?(?:\:\d*)?)$`) -var rxOctalHost = regexp.MustCompile(`^(0\d*)\.(0\d*)\.(0\d*)\.(0\d*)((?:\.+)?(?:\:\d*)?)$`) -var rxHexHost = regexp.MustCompile(`^0x([0-9A-Fa-f]+)((?:\.+)?(?:\:\d*)?)$`) -var rxHostDots = regexp.MustCompile(`^(.+?)(:\d+)?$`) -var rxEmptyPort = regexp.MustCompile(`:+$`) - -// Map of flags to implementation function. -// FlagDecodeUnnecessaryEscapes has no action, since it is done automatically -// by parsing the string as an URL. Same for FlagUppercaseEscapes and FlagRemoveEmptyQuerySeparator. - -// Since maps have undefined traversing order, make a slice of ordered keys -var flagsOrder = []NormalizationFlags{ - FlagLowercaseScheme, - FlagLowercaseHost, - FlagRemoveDefaultPort, - FlagRemoveDirectoryIndex, - FlagRemoveDotSegments, - FlagRemoveFragment, - FlagForceHTTP, // Must be after remove default port (because https=443/http=80) - FlagRemoveDuplicateSlashes, - FlagRemoveWWW, - FlagAddWWW, - FlagSortQuery, - FlagDecodeDWORDHost, - FlagDecodeOctalHost, - FlagDecodeHexHost, - FlagRemoveUnnecessaryHostDots, - FlagRemoveEmptyPortSeparator, - FlagRemoveTrailingSlash, // These two (add/remove trailing slash) must be last - FlagAddTrailingSlash, -} - -// ... and then the map, where order is unimportant -var flags = map[NormalizationFlags]func(*url.URL){ - FlagLowercaseScheme: lowercaseScheme, - FlagLowercaseHost: lowercaseHost, - FlagRemoveDefaultPort: removeDefaultPort, - FlagRemoveDirectoryIndex: removeDirectoryIndex, - FlagRemoveDotSegments: removeDotSegments, - FlagRemoveFragment: removeFragment, - FlagForceHTTP: forceHTTP, - FlagRemoveDuplicateSlashes: removeDuplicateSlashes, - FlagRemoveWWW: removeWWW, - FlagAddWWW: addWWW, - FlagSortQuery: sortQuery, - FlagDecodeDWORDHost: decodeDWORDHost, - FlagDecodeOctalHost: decodeOctalHost, - FlagDecodeHexHost: decodeHexHost, - FlagRemoveUnnecessaryHostDots: removeUnncessaryHostDots, - FlagRemoveEmptyPortSeparator: removeEmptyPortSeparator, - FlagRemoveTrailingSlash: removeTrailingSlash, - FlagAddTrailingSlash: addTrailingSlash, -} - -// MustNormalizeURLString returns the normalized string, and panics if an error occurs. -// It takes an URL string as input, as well as the normalization flags. -func MustNormalizeURLString(u string, f NormalizationFlags) string { - result, e := NormalizeURLString(u, f) - if e != nil { - panic(e) - } - return result -} - -// NormalizeURLString returns the normalized string, or an error if it can't be parsed into an URL object. -// It takes an URL string as input, as well as the normalization flags. -func NormalizeURLString(u string, f NormalizationFlags) (string, error) { - parsed, err := url.Parse(u) - if err != nil { - return "", err - } - - if f&FlagLowercaseHost == FlagLowercaseHost { - parsed.Host = strings.ToLower(parsed.Host) - } - - // The idna package doesn't fully conform to RFC 5895 - // (https://tools.ietf.org/html/rfc5895), so we do it here. - // Taken from Go 1.8 cycle source, courtesy of bradfitz. - // TODO: Remove when (if?) idna package conforms to RFC 5895. - parsed.Host = width.Fold.String(parsed.Host) - parsed.Host = norm.NFC.String(parsed.Host) - if parsed.Host, err = idna.ToASCII(parsed.Host); err != nil { - return "", err - } - - return NormalizeURL(parsed, f), nil -} - -// NormalizeURL returns the normalized string. -// It takes a parsed URL object as input, as well as the normalization flags. -func NormalizeURL(u *url.URL, f NormalizationFlags) string { - for _, k := range flagsOrder { - if f&k == k { - flags[k](u) - } - } - return urlesc.Escape(u) -} - -func lowercaseScheme(u *url.URL) { - if len(u.Scheme) > 0 { - u.Scheme = strings.ToLower(u.Scheme) - } -} - -func lowercaseHost(u *url.URL) { - if len(u.Host) > 0 { - u.Host = strings.ToLower(u.Host) - } -} - -func removeDefaultPort(u *url.URL) { - if len(u.Host) > 0 { - scheme := strings.ToLower(u.Scheme) - u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string { - if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) { - return "" - } - return val - }) - } -} - -func removeTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if strings.HasSuffix(u.Path, "/") { - u.Path = u.Path[:l-1] - } - } else if l = len(u.Host); l > 0 { - if strings.HasSuffix(u.Host, "/") { - u.Host = u.Host[:l-1] - } - } -} - -func addTrailingSlash(u *url.URL) { - if l := len(u.Path); l > 0 { - if !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } else if l = len(u.Host); l > 0 { - if !strings.HasSuffix(u.Host, "/") { - u.Host += "/" - } - } -} - -func removeDotSegments(u *url.URL) { - if len(u.Path) > 0 { - var dotFree []string - var lastIsDot bool - - sections := strings.Split(u.Path, "/") - for _, s := range sections { - if s == ".." { - if len(dotFree) > 0 { - dotFree = dotFree[:len(dotFree)-1] - } - } else if s != "." { - dotFree = append(dotFree, s) - } - lastIsDot = (s == "." || s == "..") - } - // Special case if host does not end with / and new path does not begin with / - u.Path = strings.Join(dotFree, "/") - if u.Host != "" && !strings.HasSuffix(u.Host, "/") && !strings.HasPrefix(u.Path, "/") { - u.Path = "/" + u.Path - } - // Special case if the last segment was a dot, make sure the path ends with a slash - if lastIsDot && !strings.HasSuffix(u.Path, "/") { - u.Path += "/" - } - } -} - -func removeDirectoryIndex(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDirIndex.ReplaceAllString(u.Path, "$1") - } -} - -func removeFragment(u *url.URL) { - u.Fragment = "" -} - -func forceHTTP(u *url.URL) { - if strings.ToLower(u.Scheme) == "https" { - u.Scheme = "http" - } -} - -func removeDuplicateSlashes(u *url.URL) { - if len(u.Path) > 0 { - u.Path = rxDupSlashes.ReplaceAllString(u.Path, "/") - } -} - -func removeWWW(u *url.URL) { - if len(u.Host) > 0 && strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = u.Host[4:] - } -} - -func addWWW(u *url.URL) { - if len(u.Host) > 0 && !strings.HasPrefix(strings.ToLower(u.Host), "www.") { - u.Host = "www." + u.Host - } -} - -func sortQuery(u *url.URL) { - q := u.Query() - - if len(q) > 0 { - arKeys := make([]string, len(q)) - i := 0 - for k := range q { - arKeys[i] = k - i++ - } - sort.Strings(arKeys) - buf := new(bytes.Buffer) - for _, k := range arKeys { - sort.Strings(q[k]) - for _, v := range q[k] { - if buf.Len() > 0 { - buf.WriteRune('&') - } - buf.WriteString(fmt.Sprintf("%s=%s", k, urlesc.QueryEscape(v))) - } - } - - // Rebuild the raw query string - u.RawQuery = buf.String() - } -} - -func decodeDWORDHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxDWORDHost.FindStringSubmatch(u.Host); len(matches) > 2 { - var parts [4]int64 - - dword, _ := strconv.ParseInt(matches[1], 10, 0) - for i, shift := range []uint{24, 16, 8, 0} { - parts[i] = dword >> shift & 0xFF - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[2]) - } - } -} - -func decodeOctalHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxOctalHost.FindStringSubmatch(u.Host); len(matches) > 5 { - var parts [4]int64 - - for i := 1; i <= 4; i++ { - parts[i-1], _ = strconv.ParseInt(matches[i], 8, 0) - } - u.Host = fmt.Sprintf("%d.%d.%d.%d%s", parts[0], parts[1], parts[2], parts[3], matches[5]) - } - } -} - -func decodeHexHost(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHexHost.FindStringSubmatch(u.Host); len(matches) > 2 { - // Conversion is safe because of regex validation - parsed, _ := strconv.ParseInt(matches[1], 16, 0) - // Set host as DWORD (base 10) encoded host - u.Host = fmt.Sprintf("%d%s", parsed, matches[2]) - // The rest is the same as decoding a DWORD host - decodeDWORDHost(u) - } - } -} - -func removeUnncessaryHostDots(u *url.URL) { - if len(u.Host) > 0 { - if matches := rxHostDots.FindStringSubmatch(u.Host); len(matches) > 1 { - // Trim the leading and trailing dots - u.Host = strings.Trim(matches[1], ".") - if len(matches) > 2 { - u.Host += matches[2] - } - } - } -} - -func removeEmptyPortSeparator(u *url.URL) { - if len(u.Host) > 0 { - u.Host = rxEmptyPort.ReplaceAllString(u.Host, "") - } -} diff --git a/vendor/github.com/PuerkitoBio/urlesc/.travis.yml b/vendor/github.com/PuerkitoBio/urlesc/.travis.yml deleted file mode 100644 index ba6b225f..00000000 --- a/vendor/github.com/PuerkitoBio/urlesc/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go - -go: - - 1.4.x - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - tip - -install: - - go build . - -script: - - go test -v diff --git a/vendor/github.com/PuerkitoBio/urlesc/LICENSE b/vendor/github.com/PuerkitoBio/urlesc/LICENSE deleted file mode 100644 index 74487567..00000000 --- a/vendor/github.com/PuerkitoBio/urlesc/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/PuerkitoBio/urlesc/README.md b/vendor/github.com/PuerkitoBio/urlesc/README.md deleted file mode 100644 index 57aff0a5..00000000 --- a/vendor/github.com/PuerkitoBio/urlesc/README.md +++ /dev/null @@ -1,16 +0,0 @@ -urlesc [![Build Status](https://travis-ci.org/PuerkitoBio/urlesc.svg?branch=master)](https://travis-ci.org/PuerkitoBio/urlesc) [![GoDoc](http://godoc.org/github.com/PuerkitoBio/urlesc?status.svg)](http://godoc.org/github.com/PuerkitoBio/urlesc) -====== - -Package urlesc implements query escaping as per RFC 3986. - -It contains some parts of the net/url package, modified so as to allow -some reserved characters incorrectly escaped by net/url (see [issue 5684](https://github.com/golang/go/issues/5684)). - -## Install - - go get github.com/PuerkitoBio/urlesc - -## License - -Go license (BSD-3-Clause) - diff --git a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go b/vendor/github.com/PuerkitoBio/urlesc/urlesc.go deleted file mode 100644 index 1b846245..00000000 --- a/vendor/github.com/PuerkitoBio/urlesc/urlesc.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package urlesc implements query escaping as per RFC 3986. -// It contains some parts of the net/url package, modified so as to allow -// some reserved characters incorrectly escaped by net/url. -// See https://github.com/golang/go/issues/5684 -package urlesc - -import ( - "bytes" - "net/url" - "strings" -) - -type encoding int - -const ( - encodePath encoding = 1 + iota - encodeUserPassword - encodeQueryComponent - encodeFragment -) - -// Return true if the specified character should be escaped when -// appearing in a URL string, according to RFC 3986. -func shouldEscape(c byte, mode encoding) bool { - // §2.3 Unreserved characters (alphanum) - if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' { - return false - } - - switch c { - case '-', '.', '_', '~': // §2.3 Unreserved characters (mark) - return false - - // §2.2 Reserved characters (reserved) - case ':', '/', '?', '#', '[', ']', '@', // gen-delims - '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // sub-delims - // Different sections of the URL allow a few of - // the reserved characters to appear unescaped. - switch mode { - case encodePath: // §3.3 - // The RFC allows sub-delims and : @. - // '/', '[' and ']' can be used to assign meaning to individual path - // segments. This package only manipulates the path as a whole, - // so we allow those as well. That leaves only ? and # to escape. - return c == '?' || c == '#' - - case encodeUserPassword: // §3.2.1 - // The RFC allows : and sub-delims in - // userinfo. The parsing of userinfo treats ':' as special so we must escape - // all the gen-delims. - return c == ':' || c == '/' || c == '?' || c == '#' || c == '[' || c == ']' || c == '@' - - case encodeQueryComponent: // §3.4 - // The RFC allows / and ?. - return c != '/' && c != '?' - - case encodeFragment: // §4.1 - // The RFC text is silent but the grammar allows - // everything, so escape nothing but # - return c == '#' - } - } - - // Everything else must be escaped. - return true -} - -// QueryEscape escapes the string so it can be safely placed -// inside a URL query. -func QueryEscape(s string) string { - return escape(s, encodeQueryComponent) -} - -func escape(s string, mode encoding) string { - spaceCount, hexCount := 0, 0 - for i := 0; i < len(s); i++ { - c := s[i] - if shouldEscape(c, mode) { - if c == ' ' && mode == encodeQueryComponent { - spaceCount++ - } else { - hexCount++ - } - } - } - - if spaceCount == 0 && hexCount == 0 { - return s - } - - t := make([]byte, len(s)+2*hexCount) - j := 0 - for i := 0; i < len(s); i++ { - switch c := s[i]; { - case c == ' ' && mode == encodeQueryComponent: - t[j] = '+' - j++ - case shouldEscape(c, mode): - t[j] = '%' - t[j+1] = "0123456789ABCDEF"[c>>4] - t[j+2] = "0123456789ABCDEF"[c&15] - j += 3 - default: - t[j] = s[i] - j++ - } - } - return string(t) -} - -var uiReplacer = strings.NewReplacer( - "%21", "!", - "%27", "'", - "%28", "(", - "%29", ")", - "%2A", "*", -) - -// unescapeUserinfo unescapes some characters that need not to be escaped as per RFC3986. -func unescapeUserinfo(s string) string { - return uiReplacer.Replace(s) -} - -// Escape reassembles the URL into a valid URL string. -// The general form of the result is one of: -// -// scheme:opaque -// scheme://userinfo@host/path?query#fragment -// -// If u.Opaque is non-empty, String uses the first form; -// otherwise it uses the second form. -// -// In the second form, the following rules apply: -// - if u.Scheme is empty, scheme: is omitted. -// - if u.User is nil, userinfo@ is omitted. -// - if u.Host is empty, host/ is omitted. -// - if u.Scheme and u.Host are empty and u.User is nil, -// the entire scheme://userinfo@host/ is omitted. -// - if u.Host is non-empty and u.Path begins with a /, -// the form host/path does not add its own /. -// - if u.RawQuery is empty, ?query is omitted. -// - if u.Fragment is empty, #fragment is omitted. -func Escape(u *url.URL) string { - var buf bytes.Buffer - if u.Scheme != "" { - buf.WriteString(u.Scheme) - buf.WriteByte(':') - } - if u.Opaque != "" { - buf.WriteString(u.Opaque) - } else { - if u.Scheme != "" || u.Host != "" || u.User != nil { - buf.WriteString("//") - if ui := u.User; ui != nil { - buf.WriteString(unescapeUserinfo(ui.String())) - buf.WriteByte('@') - } - if h := u.Host; h != "" { - buf.WriteString(h) - } - } - if u.Path != "" && u.Path[0] != '/' && u.Host != "" { - buf.WriteByte('/') - } - buf.WriteString(escape(u.Path, encodePath)) - } - if u.RawQuery != "" { - buf.WriteByte('?') - buf.WriteString(u.RawQuery) - } - if u.Fragment != "" { - buf.WriteByte('#') - buf.WriteString(escape(u.Fragment, encodeFragment)) - } - return buf.String() -} diff --git a/vendor/github.com/beorn7/perks/LICENSE b/vendor/github.com/beorn7/perks/LICENSE deleted file mode 100644 index 339177be..00000000 --- a/vendor/github.com/beorn7/perks/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (C) 2013 Blake Mizerany - -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/beorn7/perks/quantile/exampledata.txt b/vendor/github.com/beorn7/perks/quantile/exampledata.txt deleted file mode 100644 index 1602287d..00000000 --- a/vendor/github.com/beorn7/perks/quantile/exampledata.txt +++ /dev/null @@ -1,2388 +0,0 @@ -8 -5 -26 -12 -5 -235 -13 -6 -28 -30 -3 -3 -3 -3 -5 -2 -33 -7 -2 -4 -7 -12 -14 -5 -8 -3 -10 -4 -5 -3 -6 -6 -209 -20 -3 -10 -14 -3 -4 -6 -8 -5 -11 -7 -3 -2 -3 -3 -212 -5 -222 -4 -10 -10 -5 -6 -3 -8 -3 -10 -254 -220 -2 -3 -5 -24 -5 -4 -222 -7 -3 -3 -223 -8 -15 -12 -14 -14 -3 -2 -2 -3 -13 -3 -11 -4 -4 -6 -5 -7 -13 -5 -3 -5 -2 -5 -3 -5 -2 -7 -15 -17 -14 -3 -6 -6 -3 -17 -5 -4 -7 -6 -4 -4 -8 -6 -8 -3 -9 -3 -6 -3 -4 -5 -3 -3 -660 -4 -6 -10 -3 -6 -3 -2 -5 -13 -2 -4 -4 -10 -4 -8 -4 -3 -7 -9 -9 -3 -10 -37 -3 -13 -4 -12 -3 -6 -10 -8 -5 -21 -2 -3 -8 -3 -2 -3 -3 -4 -12 -2 -4 -8 -8 -4 -3 -2 -20 -1 -6 -32 -2 -11 -6 -18 -3 -8 -11 -3 -212 -3 -4 -2 -6 -7 -12 -11 -3 -2 -16 -10 -6 -4 -6 -3 -2 -7 -3 -2 -2 -2 -2 -5 -6 -4 -3 -10 -3 -4 -6 -5 -3 -4 -4 -5 -6 -4 -3 -4 -4 -5 -7 -5 -5 -3 -2 -7 -2 -4 -12 -4 -5 -6 -2 -4 -4 -8 -4 -15 -13 -7 -16 -5 -3 -23 -5 -5 -7 -3 -2 -9 -8 -7 -5 -8 -11 -4 -10 -76 -4 -47 -4 -3 -2 -7 -4 -2 -3 -37 -10 -4 -2 -20 -5 -4 -4 -10 -10 -4 -3 -7 -23 -240 -7 -13 -5 -5 -3 -3 -2 -5 -4 -2 -8 -7 -19 -2 -23 -8 -7 -2 -5 -3 -8 -3 -8 -13 -5 -5 -5 -2 -3 -23 -4 -9 -8 -4 -3 -3 -5 -220 -2 -3 -4 -6 -14 -3 -53 -6 -2 -5 -18 -6 -3 -219 -6 -5 -2 -5 -3 -6 -5 -15 -4 -3 -17 -3 -2 -4 -7 -2 -3 -3 -4 -4 -3 -2 -664 -6 -3 -23 -5 -5 -16 -5 -8 -2 -4 -2 -24 -12 -3 -2 -3 -5 -8 -3 -5 -4 -3 -14 -3 -5 -8 -2 -3 -7 -9 -4 -2 -3 -6 -8 -4 -3 -4 -6 -5 -3 -3 -6 -3 -19 -4 -4 -6 -3 -6 -3 -5 -22 -5 -4 -4 -3 -8 -11 -4 -9 -7 -6 -13 -4 -4 -4 -6 -17 -9 -3 -3 -3 -4 -3 -221 -5 -11 -3 -4 -2 -12 -6 -3 -5 -7 -5 -7 -4 -9 -7 -14 -37 -19 -217 -16 -3 -5 -2 -2 -7 -19 -7 -6 -7 -4 -24 -5 -11 -4 -7 -7 -9 -13 -3 -4 -3 -6 -28 -4 -4 -5 -5 -2 -5 -6 -4 -4 -6 -10 -5 -4 -3 -2 -3 -3 -6 -5 -5 -4 -3 -2 -3 -7 -4 -6 -18 -16 -8 -16 -4 -5 -8 -6 -9 -13 -1545 -6 -215 -6 -5 -6 -3 -45 -31 -5 -2 -2 -4 -3 -3 -2 -5 -4 -3 -5 -7 -7 -4 -5 -8 -5 -4 -749 -2 -31 -9 -11 -2 -11 -5 -4 -4 -7 -9 -11 -4 -5 -4 -7 -3 -4 -6 -2 -15 -3 -4 -3 -4 -3 -5 -2 -13 -5 -5 -3 -3 -23 -4 -4 -5 -7 -4 -13 -2 -4 -3 -4 -2 -6 -2 -7 -3 -5 -5 -3 -29 -5 -4 -4 -3 -10 -2 -3 -79 -16 -6 -6 -7 -7 -3 -5 -5 -7 -4 -3 -7 -9 -5 -6 -5 -9 -6 -3 -6 -4 -17 -2 -10 -9 -3 -6 -2 -3 -21 -22 -5 -11 -4 -2 -17 -2 -224 -2 -14 -3 -4 -4 -2 -4 -4 -4 -4 -5 -3 -4 -4 -10 -2 -6 -3 -3 -5 -7 -2 -7 -5 -6 -3 -218 -2 -2 -5 -2 -6 -3 -5 -222 -14 -6 -33 -3 -2 -5 -3 -3 -3 -9 -5 -3 -3 -2 -7 -4 -3 -4 -3 -5 -6 -5 -26 -4 -13 -9 -7 -3 -221 -3 -3 -4 -4 -4 -4 -2 -18 -5 -3 -7 -9 -6 -8 -3 -10 -3 -11 -9 -5 -4 -17 -5 -5 -6 -6 -3 -2 -4 -12 -17 -6 -7 -218 -4 -2 -4 -10 -3 -5 -15 -3 -9 -4 -3 -3 -6 -29 -3 -3 -4 -5 -5 -3 -8 -5 -6 -6 -7 -5 -3 -5 -3 -29 -2 -31 -5 -15 -24 -16 -5 -207 -4 -3 -3 -2 -15 -4 -4 -13 -5 -5 -4 -6 -10 -2 -7 -8 -4 -6 -20 -5 -3 -4 -3 -12 -12 -5 -17 -7 -3 -3 -3 -6 -10 -3 -5 -25 -80 -4 -9 -3 -2 -11 -3 -3 -2 -3 -8 -7 -5 -5 -19 -5 -3 -3 -12 -11 -2 -6 -5 -5 -5 -3 -3 -3 -4 -209 -14 -3 -2 -5 -19 -4 -4 -3 -4 -14 -5 -6 -4 -13 -9 -7 -4 -7 -10 -2 -9 -5 -7 -2 -8 -4 -6 -5 -5 -222 -8 -7 -12 -5 -216 -3 -4 -4 -6 -3 -14 -8 -7 -13 -4 -3 -3 -3 -3 -17 -5 -4 -3 -33 -6 -6 -33 -7 -5 -3 -8 -7 -5 -2 -9 -4 -2 -233 -24 -7 -4 -8 -10 -3 -4 -15 -2 -16 -3 -3 -13 -12 -7 -5 -4 -207 -4 -2 -4 -27 -15 -2 -5 -2 -25 -6 -5 -5 -6 -13 -6 -18 -6 -4 -12 -225 -10 -7 -5 -2 -2 -11 -4 -14 -21 -8 -10 -3 -5 -4 -232 -2 -5 -5 -3 -7 -17 -11 -6 -6 -23 -4 -6 -3 -5 -4 -2 -17 -3 -6 -5 -8 -3 -2 -2 -14 -9 -4 -4 -2 -5 -5 -3 -7 -6 -12 -6 -10 -3 -6 -2 -2 -19 -5 -4 -4 -9 -2 -4 -13 -3 -5 -6 -3 -6 -5 -4 -9 -6 -3 -5 -7 -3 -6 -6 -4 -3 -10 -6 -3 -221 -3 -5 -3 -6 -4 -8 -5 -3 -6 -4 -4 -2 -54 -5 -6 -11 -3 -3 -4 -4 -4 -3 -7 -3 -11 -11 -7 -10 -6 -13 -223 -213 -15 -231 -7 -3 -7 -228 -2 -3 -4 -4 -5 -6 -7 -4 -13 -3 -4 -5 -3 -6 -4 -6 -7 -2 -4 -3 -4 -3 -3 -6 -3 -7 -3 -5 -18 -5 -6 -8 -10 -3 -3 -3 -2 -4 -2 -4 -4 -5 -6 -6 -4 -10 -13 -3 -12 -5 -12 -16 -8 -4 -19 -11 -2 -4 -5 -6 -8 -5 -6 -4 -18 -10 -4 -2 -216 -6 -6 -6 -2 -4 -12 -8 -3 -11 -5 -6 -14 -5 -3 -13 -4 -5 -4 -5 -3 -28 -6 -3 -7 -219 -3 -9 -7 -3 -10 -6 -3 -4 -19 -5 -7 -11 -6 -15 -19 -4 -13 -11 -3 -7 -5 -10 -2 -8 -11 -2 -6 -4 -6 -24 -6 -3 -3 -3 -3 -6 -18 -4 -11 -4 -2 -5 -10 -8 -3 -9 -5 -3 -4 -5 -6 -2 -5 -7 -4 -4 -14 -6 -4 -4 -5 -5 -7 -2 -4 -3 -7 -3 -3 -6 -4 -5 -4 -4 -4 -3 -3 -3 -3 -8 -14 -2 -3 -5 -3 -2 -4 -5 -3 -7 -3 -3 -18 -3 -4 -4 -5 -7 -3 -3 -3 -13 -5 -4 -8 -211 -5 -5 -3 -5 -2 -5 -4 -2 -655 -6 -3 -5 -11 -2 -5 -3 -12 -9 -15 -11 -5 -12 -217 -2 -6 -17 -3 -3 -207 -5 -5 -4 -5 -9 -3 -2 -8 -5 -4 -3 -2 -5 -12 -4 -14 -5 -4 -2 -13 -5 -8 -4 -225 -4 -3 -4 -5 -4 -3 -3 -6 -23 -9 -2 -6 -7 -233 -4 -4 -6 -18 -3 -4 -6 -3 -4 -4 -2 -3 -7 -4 -13 -227 -4 -3 -5 -4 -2 -12 -9 -17 -3 -7 -14 -6 -4 -5 -21 -4 -8 -9 -2 -9 -25 -16 -3 -6 -4 -7 -8 -5 -2 -3 -5 -4 -3 -3 -5 -3 -3 -3 -2 -3 -19 -2 -4 -3 -4 -2 -3 -4 -4 -2 -4 -3 -3 -3 -2 -6 -3 -17 -5 -6 -4 -3 -13 -5 -3 -3 -3 -4 -9 -4 -2 -14 -12 -4 -5 -24 -4 -3 -37 -12 -11 -21 -3 -4 -3 -13 -4 -2 -3 -15 -4 -11 -4 -4 -3 -8 -3 -4 -4 -12 -8 -5 -3 -3 -4 -2 -220 -3 -5 -223 -3 -3 -3 -10 -3 -15 -4 -241 -9 -7 -3 -6 -6 -23 -4 -13 -7 -3 -4 -7 -4 -9 -3 -3 -4 -10 -5 -5 -1 -5 -24 -2 -4 -5 -5 -6 -14 -3 -8 -2 -3 -5 -13 -13 -3 -5 -2 -3 -15 -3 -4 -2 -10 -4 -4 -4 -5 -5 -3 -5 -3 -4 -7 -4 -27 -3 -6 -4 -15 -3 -5 -6 -6 -5 -4 -8 -3 -9 -2 -6 -3 -4 -3 -7 -4 -18 -3 -11 -3 -3 -8 -9 -7 -24 -3 -219 -7 -10 -4 -5 -9 -12 -2 -5 -4 -4 -4 -3 -3 -19 -5 -8 -16 -8 -6 -22 -3 -23 -3 -242 -9 -4 -3 -3 -5 -7 -3 -3 -5 -8 -3 -7 -5 -14 -8 -10 -3 -4 -3 -7 -4 -6 -7 -4 -10 -4 -3 -11 -3 -7 -10 -3 -13 -6 -8 -12 -10 -5 -7 -9 -3 -4 -7 -7 -10 -8 -30 -9 -19 -4 -3 -19 -15 -4 -13 -3 -215 -223 -4 -7 -4 -8 -17 -16 -3 -7 -6 -5 -5 -4 -12 -3 -7 -4 -4 -13 -4 -5 -2 -5 -6 -5 -6 -6 -7 -10 -18 -23 -9 -3 -3 -6 -5 -2 -4 -2 -7 -3 -3 -2 -5 -5 -14 -10 -224 -6 -3 -4 -3 -7 -5 -9 -3 -6 -4 -2 -5 -11 -4 -3 -3 -2 -8 -4 -7 -4 -10 -7 -3 -3 -18 -18 -17 -3 -3 -3 -4 -5 -3 -3 -4 -12 -7 -3 -11 -13 -5 -4 -7 -13 -5 -4 -11 -3 -12 -3 -6 -4 -4 -21 -4 -6 -9 -5 -3 -10 -8 -4 -6 -4 -4 -6 -5 -4 -8 -6 -4 -6 -4 -4 -5 -9 -6 -3 -4 -2 -9 -3 -18 -2 -4 -3 -13 -3 -6 -6 -8 -7 -9 -3 -2 -16 -3 -4 -6 -3 -2 -33 -22 -14 -4 -9 -12 -4 -5 -6 -3 -23 -9 -4 -3 -5 -5 -3 -4 -5 -3 -5 -3 -10 -4 -5 -5 -8 -4 -4 -6 -8 -5 -4 -3 -4 -6 -3 -3 -3 -5 -9 -12 -6 -5 -9 -3 -5 -3 -2 -2 -2 -18 -3 -2 -21 -2 -5 -4 -6 -4 -5 -10 -3 -9 -3 -2 -10 -7 -3 -6 -6 -4 -4 -8 -12 -7 -3 -7 -3 -3 -9 -3 -4 -5 -4 -4 -5 -5 -10 -15 -4 -4 -14 -6 -227 -3 -14 -5 -216 -22 -5 -4 -2 -2 -6 -3 -4 -2 -9 -9 -4 -3 -28 -13 -11 -4 -5 -3 -3 -2 -3 -3 -5 -3 -4 -3 -5 -23 -26 -3 -4 -5 -6 -4 -6 -3 -5 -5 -3 -4 -3 -2 -2 -2 -7 -14 -3 -6 -7 -17 -2 -2 -15 -14 -16 -4 -6 -7 -13 -6 -4 -5 -6 -16 -3 -3 -28 -3 -6 -15 -3 -9 -2 -4 -6 -3 -3 -22 -4 -12 -6 -7 -2 -5 -4 -10 -3 -16 -6 -9 -2 -5 -12 -7 -5 -5 -5 -5 -2 -11 -9 -17 -4 -3 -11 -7 -3 -5 -15 -4 -3 -4 -211 -8 -7 -5 -4 -7 -6 -7 -6 -3 -6 -5 -6 -5 -3 -4 -4 -26 -4 -6 -10 -4 -4 -3 -2 -3 -3 -4 -5 -9 -3 -9 -4 -4 -5 -5 -8 -2 -4 -2 -3 -8 -4 -11 -19 -5 -8 -6 -3 -5 -6 -12 -3 -2 -4 -16 -12 -3 -4 -4 -8 -6 -5 -6 -6 -219 -8 -222 -6 -16 -3 -13 -19 -5 -4 -3 -11 -6 -10 -4 -7 -7 -12 -5 -3 -3 -5 -6 -10 -3 -8 -2 -5 -4 -7 -2 -4 -4 -2 -12 -9 -6 -4 -2 -40 -2 -4 -10 -4 -223 -4 -2 -20 -6 -7 -24 -5 -4 -5 -2 -20 -16 -6 -5 -13 -2 -3 -3 -19 -3 -2 -4 -5 -6 -7 -11 -12 -5 -6 -7 -7 -3 -5 -3 -5 -3 -14 -3 -4 -4 -2 -11 -1 -7 -3 -9 -6 -11 -12 -5 -8 -6 -221 -4 -2 -12 -4 -3 -15 -4 -5 -226 -7 -218 -7 -5 -4 -5 -18 -4 -5 -9 -4 -4 -2 -9 -18 -18 -9 -5 -6 -6 -3 -3 -7 -3 -5 -4 -4 -4 -12 -3 -6 -31 -5 -4 -7 -3 -6 -5 -6 -5 -11 -2 -2 -11 -11 -6 -7 -5 -8 -7 -10 -5 -23 -7 -4 -3 -5 -34 -2 -5 -23 -7 -3 -6 -8 -4 -4 -4 -2 -5 -3 -8 -5 -4 -8 -25 -2 -3 -17 -8 -3 -4 -8 -7 -3 -15 -6 -5 -7 -21 -9 -5 -6 -6 -5 -3 -2 -3 -10 -3 -6 -3 -14 -7 -4 -4 -8 -7 -8 -2 -6 -12 -4 -213 -6 -5 -21 -8 -2 -5 -23 -3 -11 -2 -3 -6 -25 -2 -3 -6 -7 -6 -6 -4 -4 -6 -3 -17 -9 -7 -6 -4 -3 -10 -7 -2 -3 -3 -3 -11 -8 -3 -7 -6 -4 -14 -36 -3 -4 -3 -3 -22 -13 -21 -4 -2 -7 -4 -4 -17 -15 -3 -7 -11 -2 -4 -7 -6 -209 -6 -3 -2 -2 -24 -4 -9 -4 -3 -3 -3 -29 -2 -2 -4 -3 -3 -5 -4 -6 -3 -3 -2 -4 diff --git a/vendor/github.com/beorn7/perks/quantile/stream.go b/vendor/github.com/beorn7/perks/quantile/stream.go deleted file mode 100644 index d7d14f8e..00000000 --- a/vendor/github.com/beorn7/perks/quantile/stream.go +++ /dev/null @@ -1,316 +0,0 @@ -// Package quantile computes approximate quantiles over an unbounded data -// stream within low memory and CPU bounds. -// -// A small amount of accuracy is traded to achieve the above properties. -// -// Multiple streams can be merged before calling Query to generate a single set -// of results. This is meaningful when the streams represent the same type of -// data. See Merge and Samples. -// -// For more detailed information about the algorithm used, see: -// -// Effective Computation of Biased Quantiles over Data Streams -// -// http://www.cs.rutgers.edu/~muthu/bquant.pdf -package quantile - -import ( - "math" - "sort" -) - -// Sample holds an observed value and meta information for compression. JSON -// tags have been added for convenience. -type Sample struct { - Value float64 `json:",string"` - Width float64 `json:",string"` - Delta float64 `json:",string"` -} - -// Samples represents a slice of samples. It implements sort.Interface. -type Samples []Sample - -func (a Samples) Len() int { return len(a) } -func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value } -func (a Samples) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -type invariant func(s *stream, r float64) float64 - -// NewLowBiased returns an initialized Stream for low-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the lower ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within (1±Epsilon)*Quantile. -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewLowBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * r - } - return newStream(ƒ) -} - -// NewHighBiased returns an initialized Stream for high-biased quantiles -// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but -// error guarantees can still be given even for the higher ranks of the data -// distribution. -// -// The provided epsilon is a relative error, i.e. the true quantile of a value -// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error -// properties. -func NewHighBiased(epsilon float64) *Stream { - ƒ := func(s *stream, r float64) float64 { - return 2 * epsilon * (s.n - r) - } - return newStream(ƒ) -} - -// NewTargeted returns an initialized Stream concerned with a particular set of -// quantile values that are supplied a priori. Knowing these a priori reduces -// space and computation time. The targets map maps the desired quantiles to -// their absolute errors, i.e. the true quantile of a value returned by a query -// is guaranteed to be within (Quantile±Epsilon). -// -// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties. -func NewTargeted(targetMap map[float64]float64) *Stream { - // Convert map to slice to avoid slow iterations on a map. - // ƒ is called on the hot path, so converting the map to a slice - // beforehand results in significant CPU savings. - targets := targetMapToSlice(targetMap) - - ƒ := func(s *stream, r float64) float64 { - var m = math.MaxFloat64 - var f float64 - for _, t := range targets { - if t.quantile*s.n <= r { - f = (2 * t.epsilon * r) / t.quantile - } else { - f = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile) - } - if f < m { - m = f - } - } - return m - } - return newStream(ƒ) -} - -type target struct { - quantile float64 - epsilon float64 -} - -func targetMapToSlice(targetMap map[float64]float64) []target { - targets := make([]target, 0, len(targetMap)) - - for quantile, epsilon := range targetMap { - t := target{ - quantile: quantile, - epsilon: epsilon, - } - targets = append(targets, t) - } - - return targets -} - -// Stream computes quantiles for a stream of float64s. It is not thread-safe by -// design. Take care when using across multiple goroutines. -type Stream struct { - *stream - b Samples - sorted bool -} - -func newStream(ƒ invariant) *Stream { - x := &stream{ƒ: ƒ} - return &Stream{x, make(Samples, 0, 500), true} -} - -// Insert inserts v into the stream. -func (s *Stream) Insert(v float64) { - s.insert(Sample{Value: v, Width: 1}) -} - -func (s *Stream) insert(sample Sample) { - s.b = append(s.b, sample) - s.sorted = false - if len(s.b) == cap(s.b) { - s.flush() - } -} - -// Query returns the computed qth percentiles value. If s was created with -// NewTargeted, and q is not in the set of quantiles provided a priori, Query -// will return an unspecified result. -func (s *Stream) Query(q float64) float64 { - if !s.flushed() { - // Fast path when there hasn't been enough data for a flush; - // this also yields better accuracy for small sets of data. - l := len(s.b) - if l == 0 { - return 0 - } - i := int(math.Ceil(float64(l) * q)) - if i > 0 { - i -= 1 - } - s.maybeSort() - return s.b[i].Value - } - s.flush() - return s.stream.query(q) -} - -// Merge merges samples into the underlying streams samples. This is handy when -// merging multiple streams from separate threads, database shards, etc. -// -// ATTENTION: This method is broken and does not yield correct results. The -// underlying algorithm is not capable of merging streams correctly. -func (s *Stream) Merge(samples Samples) { - sort.Sort(samples) - s.stream.merge(samples) -} - -// Reset reinitializes and clears the list reusing the samples buffer memory. -func (s *Stream) Reset() { - s.stream.reset() - s.b = s.b[:0] -} - -// Samples returns stream samples held by s. -func (s *Stream) Samples() Samples { - if !s.flushed() { - return s.b - } - s.flush() - return s.stream.samples() -} - -// Count returns the total number of samples observed in the stream -// since initialization. -func (s *Stream) Count() int { - return len(s.b) + s.stream.count() -} - -func (s *Stream) flush() { - s.maybeSort() - s.stream.merge(s.b) - s.b = s.b[:0] -} - -func (s *Stream) maybeSort() { - if !s.sorted { - s.sorted = true - sort.Sort(s.b) - } -} - -func (s *Stream) flushed() bool { - return len(s.stream.l) > 0 -} - -type stream struct { - n float64 - l []Sample - ƒ invariant -} - -func (s *stream) reset() { - s.l = s.l[:0] - s.n = 0 -} - -func (s *stream) insert(v float64) { - s.merge(Samples{{v, 1, 0}}) -} - -func (s *stream) merge(samples Samples) { - // TODO(beorn7): This tries to merge not only individual samples, but - // whole summaries. The paper doesn't mention merging summaries at - // all. Unittests show that the merging is inaccurate. Find out how to - // do merges properly. - var r float64 - i := 0 - for _, sample := range samples { - for ; i < len(s.l); i++ { - c := s.l[i] - if c.Value > sample.Value { - // Insert at position i. - s.l = append(s.l, Sample{}) - copy(s.l[i+1:], s.l[i:]) - s.l[i] = Sample{ - sample.Value, - sample.Width, - math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1), - // TODO(beorn7): How to calculate delta correctly? - } - i++ - goto inserted - } - r += c.Width - } - s.l = append(s.l, Sample{sample.Value, sample.Width, 0}) - i++ - inserted: - s.n += sample.Width - r += sample.Width - } - s.compress() -} - -func (s *stream) count() int { - return int(s.n) -} - -func (s *stream) query(q float64) float64 { - t := math.Ceil(q * s.n) - t += math.Ceil(s.ƒ(s, t) / 2) - p := s.l[0] - var r float64 - for _, c := range s.l[1:] { - r += p.Width - if r+c.Width+c.Delta > t { - return p.Value - } - p = c - } - return p.Value -} - -func (s *stream) compress() { - if len(s.l) < 2 { - return - } - x := s.l[len(s.l)-1] - xi := len(s.l) - 1 - r := s.n - 1 - x.Width - - for i := len(s.l) - 2; i >= 0; i-- { - c := s.l[i] - if c.Width+x.Width+x.Delta <= s.ƒ(s, r) { - x.Width += c.Width - s.l[xi] = x - // Remove element at i. - copy(s.l[i:], s.l[i+1:]) - s.l = s.l[:len(s.l)-1] - xi -= 1 - } else { - x = c - xi = i - } - r -= c.Width - } -} - -func (s *stream) samples() Samples { - samples := make(Samples, len(s.l)) - copy(samples, s.l) - return samples -} diff --git a/vendor/github.com/cespare/xxhash/v2/LICENSE.txt b/vendor/github.com/cespare/xxhash/v2/LICENSE.txt deleted file mode 100644 index 24b53065..00000000 --- a/vendor/github.com/cespare/xxhash/v2/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2016 Caleb Spare - -MIT License - -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/cespare/xxhash/v2/README.md b/vendor/github.com/cespare/xxhash/v2/README.md deleted file mode 100644 index 8bf0e5b7..00000000 --- a/vendor/github.com/cespare/xxhash/v2/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# xxhash - -[![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2) -[![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml) - -xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a -high-quality hashing algorithm that is much faster than anything in the Go -standard library. - -This package provides a straightforward API: - -``` -func Sum64(b []byte) uint64 -func Sum64String(s string) uint64 -type Digest struct{ ... } - func New() *Digest -``` - -The `Digest` type implements hash.Hash64. Its key methods are: - -``` -func (*Digest) Write([]byte) (int, error) -func (*Digest) WriteString(string) (int, error) -func (*Digest) Sum64() uint64 -``` - -The package is written with optimized pure Go and also contains even faster -assembly implementations for amd64 and arm64. If desired, the `purego` build tag -opts into using the Go code even on those architectures. - -[xxHash]: http://cyan4973.github.io/xxHash/ - -## Compatibility - -This package is in a module and the latest code is in version 2 of the module. -You need a version of Go with at least "minimal module compatibility" to use -github.com/cespare/xxhash/v2: - -* 1.9.7+ for Go 1.9 -* 1.10.3+ for Go 1.10 -* Go 1.11 or later - -I recommend using the latest release of Go. - -## Benchmarks - -Here are some quick benchmarks comparing the pure-Go and assembly -implementations of Sum64. - -| input size | purego | asm | -| ---------- | --------- | --------- | -| 4 B | 1.3 GB/s | 1.2 GB/s | -| 16 B | 2.9 GB/s | 3.5 GB/s | -| 100 B | 6.9 GB/s | 8.1 GB/s | -| 4 KB | 11.7 GB/s | 16.7 GB/s | -| 10 MB | 12.0 GB/s | 17.3 GB/s | - -These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C -CPU using the following commands under Go 1.19.2: - -``` -benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$') -benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$') -``` - -## Projects using this package - -- [InfluxDB](https://github.com/influxdata/influxdb) -- [Prometheus](https://github.com/prometheus/prometheus) -- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics) -- [FreeCache](https://github.com/coocood/freecache) -- [FastCache](https://github.com/VictoriaMetrics/fastcache) diff --git a/vendor/github.com/cespare/xxhash/v2/testall.sh b/vendor/github.com/cespare/xxhash/v2/testall.sh deleted file mode 100644 index 94b9c443..00000000 --- a/vendor/github.com/cespare/xxhash/v2/testall.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -eu -o pipefail - -# Small convenience script for running the tests with various combinations of -# arch/tags. This assumes we're running on amd64 and have qemu available. - -go test ./... -go test -tags purego ./... -GOARCH=arm64 go test -GOARCH=arm64 go test -tags purego diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash.go b/vendor/github.com/cespare/xxhash/v2/xxhash.go deleted file mode 100644 index a9e0d45c..00000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash.go +++ /dev/null @@ -1,228 +0,0 @@ -// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described -// at http://cyan4973.github.io/xxHash/. -package xxhash - -import ( - "encoding/binary" - "errors" - "math/bits" -) - -const ( - prime1 uint64 = 11400714785074694791 - prime2 uint64 = 14029467366897019727 - prime3 uint64 = 1609587929392839161 - prime4 uint64 = 9650029242287828579 - prime5 uint64 = 2870177450012600261 -) - -// Store the primes in an array as well. -// -// The consts are used when possible in Go code to avoid MOVs but we need a -// contiguous array of the assembly code. -var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5} - -// Digest implements hash.Hash64. -type Digest struct { - v1 uint64 - v2 uint64 - v3 uint64 - v4 uint64 - total uint64 - mem [32]byte - n int // how much of mem is used -} - -// New creates a new Digest that computes the 64-bit xxHash algorithm. -func New() *Digest { - var d Digest - d.Reset() - return &d -} - -// Reset clears the Digest's state so that it can be reused. -func (d *Digest) Reset() { - d.v1 = primes[0] + prime2 - d.v2 = prime2 - d.v3 = 0 - d.v4 = -primes[0] - d.total = 0 - d.n = 0 -} - -// Size always returns 8 bytes. -func (d *Digest) Size() int { return 8 } - -// BlockSize always returns 32 bytes. -func (d *Digest) BlockSize() int { return 32 } - -// Write adds more data to d. It always returns len(b), nil. -func (d *Digest) Write(b []byte) (n int, err error) { - n = len(b) - d.total += uint64(n) - - memleft := d.mem[d.n&(len(d.mem)-1):] - - if d.n+n < 32 { - // This new data doesn't even fill the current block. - copy(memleft, b) - d.n += n - return - } - - if d.n > 0 { - // Finish off the partial block. - c := copy(memleft, b) - d.v1 = round(d.v1, u64(d.mem[0:8])) - d.v2 = round(d.v2, u64(d.mem[8:16])) - d.v3 = round(d.v3, u64(d.mem[16:24])) - d.v4 = round(d.v4, u64(d.mem[24:32])) - b = b[c:] - d.n = 0 - } - - if len(b) >= 32 { - // One or more full blocks left. - nw := writeBlocks(d, b) - b = b[nw:] - } - - // Store any remaining partial block. - copy(d.mem[:], b) - d.n = len(b) - - return -} - -// Sum appends the current hash to b and returns the resulting slice. -func (d *Digest) Sum(b []byte) []byte { - s := d.Sum64() - return append( - b, - byte(s>>56), - byte(s>>48), - byte(s>>40), - byte(s>>32), - byte(s>>24), - byte(s>>16), - byte(s>>8), - byte(s), - ) -} - -// Sum64 returns the current hash. -func (d *Digest) Sum64() uint64 { - var h uint64 - - if d.total >= 32 { - v1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4 - h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) - h = mergeRound(h, v1) - h = mergeRound(h, v2) - h = mergeRound(h, v3) - h = mergeRound(h, v4) - } else { - h = d.v3 + prime5 - } - - h += d.total - - b := d.mem[:d.n&(len(d.mem)-1)] - for ; len(b) >= 8; b = b[8:] { - k1 := round(0, u64(b[:8])) - h ^= k1 - h = rol27(h)*prime1 + prime4 - } - if len(b) >= 4 { - h ^= uint64(u32(b[:4])) * prime1 - h = rol23(h)*prime2 + prime3 - b = b[4:] - } - for ; len(b) > 0; b = b[1:] { - h ^= uint64(b[0]) * prime5 - h = rol11(h) * prime1 - } - - h ^= h >> 33 - h *= prime2 - h ^= h >> 29 - h *= prime3 - h ^= h >> 32 - - return h -} - -const ( - magic = "xxh\x06" - marshaledSize = len(magic) + 8*5 + 32 -) - -// MarshalBinary implements the encoding.BinaryMarshaler interface. -func (d *Digest) MarshalBinary() ([]byte, error) { - b := make([]byte, 0, marshaledSize) - b = append(b, magic...) - b = appendUint64(b, d.v1) - b = appendUint64(b, d.v2) - b = appendUint64(b, d.v3) - b = appendUint64(b, d.v4) - b = appendUint64(b, d.total) - b = append(b, d.mem[:d.n]...) - b = b[:len(b)+len(d.mem)-d.n] - return b, nil -} - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (d *Digest) UnmarshalBinary(b []byte) error { - if len(b) < len(magic) || string(b[:len(magic)]) != magic { - return errors.New("xxhash: invalid hash state identifier") - } - if len(b) != marshaledSize { - return errors.New("xxhash: invalid hash state size") - } - b = b[len(magic):] - b, d.v1 = consumeUint64(b) - b, d.v2 = consumeUint64(b) - b, d.v3 = consumeUint64(b) - b, d.v4 = consumeUint64(b) - b, d.total = consumeUint64(b) - copy(d.mem[:], b) - d.n = int(d.total % uint64(len(d.mem))) - return nil -} - -func appendUint64(b []byte, x uint64) []byte { - var a [8]byte - binary.LittleEndian.PutUint64(a[:], x) - return append(b, a[:]...) -} - -func consumeUint64(b []byte) ([]byte, uint64) { - x := u64(b) - return b[8:], x -} - -func u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) } -func u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) } - -func round(acc, input uint64) uint64 { - acc += input * prime2 - acc = rol31(acc) - acc *= prime1 - return acc -} - -func mergeRound(acc, val uint64) uint64 { - val = round(0, val) - acc ^= val - acc = acc*prime1 + prime4 - return acc -} - -func rol1(x uint64) uint64 { return bits.RotateLeft64(x, 1) } -func rol7(x uint64) uint64 { return bits.RotateLeft64(x, 7) } -func rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) } -func rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) } -func rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) } -func rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) } -func rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) } -func rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) } diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s deleted file mode 100644 index 3e8b1325..00000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s +++ /dev/null @@ -1,209 +0,0 @@ -//go:build !appengine && gc && !purego -// +build !appengine -// +build gc -// +build !purego - -#include "textflag.h" - -// Registers: -#define h AX -#define d AX -#define p SI // pointer to advance through b -#define n DX -#define end BX // loop end -#define v1 R8 -#define v2 R9 -#define v3 R10 -#define v4 R11 -#define x R12 -#define prime1 R13 -#define prime2 R14 -#define prime4 DI - -#define round(acc, x) \ - IMULQ prime2, x \ - ADDQ x, acc \ - ROLQ $31, acc \ - IMULQ prime1, acc - -// round0 performs the operation x = round(0, x). -#define round0(x) \ - IMULQ prime2, x \ - ROLQ $31, x \ - IMULQ prime1, x - -// mergeRound applies a merge round on the two registers acc and x. -// It assumes that prime1, prime2, and prime4 have been loaded. -#define mergeRound(acc, x) \ - round0(x) \ - XORQ x, acc \ - IMULQ prime1, acc \ - ADDQ prime4, acc - -// blockLoop processes as many 32-byte blocks as possible, -// updating v1, v2, v3, and v4. It assumes that there is at least one block -// to process. -#define blockLoop() \ -loop: \ - MOVQ +0(p), x \ - round(v1, x) \ - MOVQ +8(p), x \ - round(v2, x) \ - MOVQ +16(p), x \ - round(v3, x) \ - MOVQ +24(p), x \ - round(v4, x) \ - ADDQ $32, p \ - CMPQ p, end \ - JLE loop - -// func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 - // Load fixed primes. - MOVQ ·primes+0(SB), prime1 - MOVQ ·primes+8(SB), prime2 - MOVQ ·primes+24(SB), prime4 - - // Load slice. - MOVQ b_base+0(FP), p - MOVQ b_len+8(FP), n - LEAQ (p)(n*1), end - - // The first loop limit will be len(b)-32. - SUBQ $32, end - - // Check whether we have at least one block. - CMPQ n, $32 - JLT noBlocks - - // Set up initial state (v1, v2, v3, v4). - MOVQ prime1, v1 - ADDQ prime2, v1 - MOVQ prime2, v2 - XORQ v3, v3 - XORQ v4, v4 - SUBQ prime1, v4 - - blockLoop() - - MOVQ v1, h - ROLQ $1, h - MOVQ v2, x - ROLQ $7, x - ADDQ x, h - MOVQ v3, x - ROLQ $12, x - ADDQ x, h - MOVQ v4, x - ROLQ $18, x - ADDQ x, h - - mergeRound(h, v1) - mergeRound(h, v2) - mergeRound(h, v3) - mergeRound(h, v4) - - JMP afterBlocks - -noBlocks: - MOVQ ·primes+32(SB), h - -afterBlocks: - ADDQ n, h - - ADDQ $24, end - CMPQ p, end - JG try4 - -loop8: - MOVQ (p), x - ADDQ $8, p - round0(x) - XORQ x, h - ROLQ $27, h - IMULQ prime1, h - ADDQ prime4, h - - CMPQ p, end - JLE loop8 - -try4: - ADDQ $4, end - CMPQ p, end - JG try1 - - MOVL (p), x - ADDQ $4, p - IMULQ prime1, x - XORQ x, h - - ROLQ $23, h - IMULQ prime2, h - ADDQ ·primes+16(SB), h - -try1: - ADDQ $4, end - CMPQ p, end - JGE finalize - -loop1: - MOVBQZX (p), x - ADDQ $1, p - IMULQ ·primes+32(SB), x - XORQ x, h - ROLQ $11, h - IMULQ prime1, h - - CMPQ p, end - JL loop1 - -finalize: - MOVQ h, x - SHRQ $33, x - XORQ x, h - IMULQ prime2, h - MOVQ h, x - SHRQ $29, x - XORQ x, h - IMULQ ·primes+16(SB), h - MOVQ h, x - SHRQ $32, x - XORQ x, h - - MOVQ h, ret+24(FP) - RET - -// func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 - // Load fixed primes needed for round. - MOVQ ·primes+0(SB), prime1 - MOVQ ·primes+8(SB), prime2 - - // Load slice. - MOVQ b_base+8(FP), p - MOVQ b_len+16(FP), n - LEAQ (p)(n*1), end - SUBQ $32, end - - // Load vN from d. - MOVQ s+0(FP), d - MOVQ 0(d), v1 - MOVQ 8(d), v2 - MOVQ 16(d), v3 - MOVQ 24(d), v4 - - // We don't need to check the loop condition here; this function is - // always called with at least one block of data to process. - blockLoop() - - // Copy vN back to d. - MOVQ v1, 0(d) - MOVQ v2, 8(d) - MOVQ v3, 16(d) - MOVQ v4, 24(d) - - // The number of bytes written is p minus the old base pointer. - SUBQ b_base+8(FP), p - MOVQ p, ret+32(FP) - - RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s b/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s deleted file mode 100644 index 7e3145a2..00000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s +++ /dev/null @@ -1,183 +0,0 @@ -//go:build !appengine && gc && !purego -// +build !appengine -// +build gc -// +build !purego - -#include "textflag.h" - -// Registers: -#define digest R1 -#define h R2 // return value -#define p R3 // input pointer -#define n R4 // input length -#define nblocks R5 // n / 32 -#define prime1 R7 -#define prime2 R8 -#define prime3 R9 -#define prime4 R10 -#define prime5 R11 -#define v1 R12 -#define v2 R13 -#define v3 R14 -#define v4 R15 -#define x1 R20 -#define x2 R21 -#define x3 R22 -#define x4 R23 - -#define round(acc, x) \ - MADD prime2, acc, x, acc \ - ROR $64-31, acc \ - MUL prime1, acc - -// round0 performs the operation x = round(0, x). -#define round0(x) \ - MUL prime2, x \ - ROR $64-31, x \ - MUL prime1, x - -#define mergeRound(acc, x) \ - round0(x) \ - EOR x, acc \ - MADD acc, prime4, prime1, acc - -// blockLoop processes as many 32-byte blocks as possible, -// updating v1, v2, v3, and v4. It assumes that n >= 32. -#define blockLoop() \ - LSR $5, n, nblocks \ - PCALIGN $16 \ - loop: \ - LDP.P 16(p), (x1, x2) \ - LDP.P 16(p), (x3, x4) \ - round(v1, x1) \ - round(v2, x2) \ - round(v3, x3) \ - round(v4, x4) \ - SUB $1, nblocks \ - CBNZ nblocks, loop - -// func Sum64(b []byte) uint64 -TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32 - LDP b_base+0(FP), (p, n) - - LDP ·primes+0(SB), (prime1, prime2) - LDP ·primes+16(SB), (prime3, prime4) - MOVD ·primes+32(SB), prime5 - - CMP $32, n - CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 } - BLT afterLoop - - ADD prime1, prime2, v1 - MOVD prime2, v2 - MOVD $0, v3 - NEG prime1, v4 - - blockLoop() - - ROR $64-1, v1, x1 - ROR $64-7, v2, x2 - ADD x1, x2 - ROR $64-12, v3, x3 - ROR $64-18, v4, x4 - ADD x3, x4 - ADD x2, x4, h - - mergeRound(h, v1) - mergeRound(h, v2) - mergeRound(h, v3) - mergeRound(h, v4) - -afterLoop: - ADD n, h - - TBZ $4, n, try8 - LDP.P 16(p), (x1, x2) - - round0(x1) - - // NOTE: here and below, sequencing the EOR after the ROR (using a - // rotated register) is worth a small but measurable speedup for small - // inputs. - ROR $64-27, h - EOR x1 @> 64-27, h, h - MADD h, prime4, prime1, h - - round0(x2) - ROR $64-27, h - EOR x2 @> 64-27, h, h - MADD h, prime4, prime1, h - -try8: - TBZ $3, n, try4 - MOVD.P 8(p), x1 - - round0(x1) - ROR $64-27, h - EOR x1 @> 64-27, h, h - MADD h, prime4, prime1, h - -try4: - TBZ $2, n, try2 - MOVWU.P 4(p), x2 - - MUL prime1, x2 - ROR $64-23, h - EOR x2 @> 64-23, h, h - MADD h, prime3, prime2, h - -try2: - TBZ $1, n, try1 - MOVHU.P 2(p), x3 - AND $255, x3, x1 - LSR $8, x3, x2 - - MUL prime5, x1 - ROR $64-11, h - EOR x1 @> 64-11, h, h - MUL prime1, h - - MUL prime5, x2 - ROR $64-11, h - EOR x2 @> 64-11, h, h - MUL prime1, h - -try1: - TBZ $0, n, finalize - MOVBU (p), x4 - - MUL prime5, x4 - ROR $64-11, h - EOR x4 @> 64-11, h, h - MUL prime1, h - -finalize: - EOR h >> 33, h - MUL prime2, h - EOR h >> 29, h - MUL prime3, h - EOR h >> 32, h - - MOVD h, ret+24(FP) - RET - -// func writeBlocks(d *Digest, b []byte) int -TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40 - LDP ·primes+0(SB), (prime1, prime2) - - // Load state. Assume v[1-4] are stored contiguously. - MOVD d+0(FP), digest - LDP 0(digest), (v1, v2) - LDP 16(digest), (v3, v4) - - LDP b_base+8(FP), (p, n) - - blockLoop() - - // Store updated state. - STP (v1, v2), 0(digest) - STP (v3, v4), 16(digest) - - BIC $31, n - MOVD n, ret+32(FP) - RET diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go b/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go deleted file mode 100644 index 9216e0a4..00000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build (amd64 || arm64) && !appengine && gc && !purego -// +build amd64 arm64 -// +build !appengine -// +build gc -// +build !purego - -package xxhash - -// Sum64 computes the 64-bit xxHash digest of b. -// -//go:noescape -func Sum64(b []byte) uint64 - -//go:noescape -func writeBlocks(d *Digest, b []byte) int diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go b/vendor/github.com/cespare/xxhash/v2/xxhash_other.go deleted file mode 100644 index 26df13bb..00000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_other.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build (!amd64 && !arm64) || appengine || !gc || purego -// +build !amd64,!arm64 appengine !gc purego - -package xxhash - -// Sum64 computes the 64-bit xxHash digest of b. -func Sum64(b []byte) uint64 { - // A simpler version would be - // d := New() - // d.Write(b) - // return d.Sum64() - // but this is faster, particularly for small inputs. - - n := len(b) - var h uint64 - - if n >= 32 { - v1 := primes[0] + prime2 - v2 := prime2 - v3 := uint64(0) - v4 := -primes[0] - for len(b) >= 32 { - v1 = round(v1, u64(b[0:8:len(b)])) - v2 = round(v2, u64(b[8:16:len(b)])) - v3 = round(v3, u64(b[16:24:len(b)])) - v4 = round(v4, u64(b[24:32:len(b)])) - b = b[32:len(b):len(b)] - } - h = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) - h = mergeRound(h, v1) - h = mergeRound(h, v2) - h = mergeRound(h, v3) - h = mergeRound(h, v4) - } else { - h = prime5 - } - - h += uint64(n) - - for ; len(b) >= 8; b = b[8:] { - k1 := round(0, u64(b[:8])) - h ^= k1 - h = rol27(h)*prime1 + prime4 - } - if len(b) >= 4 { - h ^= uint64(u32(b[:4])) * prime1 - h = rol23(h)*prime2 + prime3 - b = b[4:] - } - for ; len(b) > 0; b = b[1:] { - h ^= uint64(b[0]) * prime5 - h = rol11(h) * prime1 - } - - h ^= h >> 33 - h *= prime2 - h ^= h >> 29 - h *= prime3 - h ^= h >> 32 - - return h -} - -func writeBlocks(d *Digest, b []byte) int { - v1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4 - n := len(b) - for len(b) >= 32 { - v1 = round(v1, u64(b[0:8:len(b)])) - v2 = round(v2, u64(b[8:16:len(b)])) - v3 = round(v3, u64(b[16:24:len(b)])) - v4 = round(v4, u64(b[24:32:len(b)])) - b = b[32:len(b):len(b)] - } - d.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4 - return n - len(b) -} diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go deleted file mode 100644 index e86f1b5f..00000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build appengine -// +build appengine - -// This file contains the safe implementations of otherwise unsafe-using code. - -package xxhash - -// Sum64String computes the 64-bit xxHash digest of s. -func Sum64String(s string) uint64 { - return Sum64([]byte(s)) -} - -// WriteString adds more data to d. It always returns len(s), nil. -func (d *Digest) WriteString(s string) (n int, err error) { - return d.Write([]byte(s)) -} diff --git a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go b/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go deleted file mode 100644 index 1c1638fd..00000000 --- a/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go +++ /dev/null @@ -1,58 +0,0 @@ -//go:build !appengine -// +build !appengine - -// This file encapsulates usage of unsafe. -// xxhash_safe.go contains the safe implementations. - -package xxhash - -import ( - "unsafe" -) - -// In the future it's possible that compiler optimizations will make these -// XxxString functions unnecessary by realizing that calls such as -// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205. -// If that happens, even if we keep these functions they can be replaced with -// the trivial safe code. - -// NOTE: The usual way of doing an unsafe string-to-[]byte conversion is: -// -// var b []byte -// bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) -// bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data -// bh.Len = len(s) -// bh.Cap = len(s) -// -// Unfortunately, as of Go 1.15.3 the inliner's cost model assigns a high enough -// weight to this sequence of expressions that any function that uses it will -// not be inlined. Instead, the functions below use a different unsafe -// conversion designed to minimize the inliner weight and allow both to be -// inlined. There is also a test (TestInlining) which verifies that these are -// inlined. -// -// See https://github.com/golang/go/issues/42739 for discussion. - -// Sum64String computes the 64-bit xxHash digest of s. -// It may be faster than Sum64([]byte(s)) by avoiding a copy. -func Sum64String(s string) uint64 { - b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})) - return Sum64(b) -} - -// WriteString adds more data to d. It always returns len(s), nil. -// It may be faster than Write([]byte(s)) by avoiding a copy. -func (d *Digest) WriteString(s string) (n int, err error) { - d.Write(*(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))) - // d.Write always returns len(s), nil. - // Ignoring the return output and returning these fixed values buys a - // savings of 6 in the inliner's cost model. - return len(s), nil -} - -// sliceHeader is similar to reflect.SliceHeader, but it assumes that the layout -// of the first two words is the same as the layout of a string. -type sliceHeader struct { - s string - cap int -} diff --git a/vendor/github.com/cilium/ebpf/.clang-format b/vendor/github.com/cilium/ebpf/.clang-format deleted file mode 100644 index 4eb94b1b..00000000 --- a/vendor/github.com/cilium/ebpf/.clang-format +++ /dev/null @@ -1,17 +0,0 @@ ---- -Language: Cpp -BasedOnStyle: LLVM -AlignAfterOpenBracket: DontAlign -AlignConsecutiveAssignments: true -AlignEscapedNewlines: DontAlign -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: false -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortFunctionsOnASingleLine: false -BreakBeforeBraces: Attach -IndentWidth: 4 -KeepEmptyLinesAtTheStartOfBlocks: false -TabWidth: 4 -UseTab: ForContinuationAndIndentation -ColumnLimit: 1000 -... diff --git a/vendor/github.com/cilium/ebpf/.gitignore b/vendor/github.com/cilium/ebpf/.gitignore deleted file mode 100644 index b46162b8..00000000 --- a/vendor/github.com/cilium/ebpf/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib -*.o -!*_bpf*.o - -# 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/cilium/ebpf/.golangci.yaml b/vendor/github.com/cilium/ebpf/.golangci.yaml deleted file mode 100644 index dc62dd6d..00000000 --- a/vendor/github.com/cilium/ebpf/.golangci.yaml +++ /dev/null @@ -1,28 +0,0 @@ ---- -issues: - exclude-rules: - # syscall param structs will have unused fields in Go code. - - path: syscall.*.go - linters: - - structcheck - -linters: - disable-all: true - enable: - - deadcode - - errcheck - - goimports - - gosimple - - govet - - ineffassign - - misspell - - staticcheck - - structcheck - - typecheck - - unused - - varcheck - - # Could be enabled later: - # - gocyclo - # - maligned - # - gosec diff --git a/vendor/github.com/cilium/ebpf/ARCHITECTURE.md b/vendor/github.com/cilium/ebpf/ARCHITECTURE.md deleted file mode 100644 index 8cd7e248..00000000 --- a/vendor/github.com/cilium/ebpf/ARCHITECTURE.md +++ /dev/null @@ -1,86 +0,0 @@ -Architecture of the library -=== - - ELF -> Specifications -> Objects -> Links - -ELF ---- - -BPF is usually produced by using Clang to compile a subset of C. Clang outputs -an ELF file which contains program byte code (aka BPF), but also metadata for -maps used by the program. The metadata follows the conventions set by libbpf -shipped with the kernel. Certain ELF sections have special meaning -and contain structures defined by libbpf. Newer versions of clang emit -additional metadata in BPF Type Format (aka BTF). - -The library aims to be compatible with libbpf so that moving from a C toolchain -to a Go one creates little friction. To that end, the [ELF reader](elf_reader.go) -is tested against the Linux selftests and avoids introducing custom behaviour -if possible. - -The output of the ELF reader is a `CollectionSpec` which encodes -all of the information contained in the ELF in a form that is easy to work with -in Go. - -### BTF - -The BPF Type Format describes more than just the types used by a BPF program. It -includes debug aids like which source line corresponds to which instructions and -what global variables are used. - -[BTF parsing](internal/btf/) lives in a separate internal package since exposing -it would mean an additional maintenance burden, and because the API still -has sharp corners. The most important concept is the `btf.Type` interface, which -also describes things that aren't really types like `.rodata` or `.bss` sections. -`btf.Type`s can form cyclical graphs, which can easily lead to infinite loops if -one is not careful. Hopefully a safe pattern to work with `btf.Type` emerges as -we write more code that deals with it. - -Specifications ---- - -`CollectionSpec`, `ProgramSpec` and `MapSpec` are blueprints for in-kernel -objects and contain everything necessary to execute the relevant `bpf(2)` -syscalls. Since the ELF reader outputs a `CollectionSpec` it's possible to -modify clang-compiled BPF code, for example to rewrite constants. At the same -time the [asm](asm/) package provides an assembler that can be used to generate -`ProgramSpec` on the fly. - -Creating a spec should never require any privileges or be restricted in any way, -for example by only allowing programs in native endianness. This ensures that -the library stays flexible. - -Objects ---- - -`Program` and `Map` are the result of loading specs into the kernel. Sometimes -loading a spec will fail because the kernel is too old, or a feature is not -enabled. There are multiple ways the library deals with that: - -* Fallback: older kernels don't allow naming programs and maps. The library - automatically detects support for names, and omits them during load if - necessary. This works since name is primarily a debug aid. - -* Sentinel error: sometimes it's possible to detect that a feature isn't available. - In that case the library will return an error wrapping `ErrNotSupported`. - This is also useful to skip tests that can't run on the current kernel. - -Once program and map objects are loaded they expose the kernel's low-level API, -e.g. `NextKey`. Often this API is awkward to use in Go, so there are safer -wrappers on top of the low-level API, like `MapIterator`. The low-level API is -useful when our higher-level API doesn't support a particular use case. - -Links ---- - -BPF can be attached to many different points in the kernel and newer BPF hooks -tend to use bpf_link to do so. Older hooks unfortunately use a combination of -syscalls, netlink messages, etc. Adding support for a new link type should not -pull in large dependencies like netlink, so XDP programs or tracepoints are -out of scope. - -Each bpf_link_type has one corresponding Go type, e.g. `link.tracing` corresponds -to BPF_LINK_TRACING. In general, these types should be unexported as long as they -don't export methods outside of the Link interface. Each Go type may have multiple -exported constructors. For example `AttachTracing` and `AttachLSM` create a -tracing link, but are distinct functions since they may require different arguments. diff --git a/vendor/github.com/cilium/ebpf/CODE_OF_CONDUCT.md b/vendor/github.com/cilium/ebpf/CODE_OF_CONDUCT.md deleted file mode 100644 index 8e42838c..00000000 --- a/vendor/github.com/cilium/ebpf/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers 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, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at nathanjsweet at gmail dot com or i at lmb dot io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/cilium/ebpf/CONTRIBUTING.md b/vendor/github.com/cilium/ebpf/CONTRIBUTING.md deleted file mode 100644 index 0d29eae8..00000000 --- a/vendor/github.com/cilium/ebpf/CONTRIBUTING.md +++ /dev/null @@ -1,40 +0,0 @@ -# How to contribute - -Development is on [GitHub](https://github.com/cilium/ebpf) and contributions in -the form of pull requests and issues reporting bugs or suggesting new features -are welcome. Please take a look at [the architecture](ARCHITECTURE.md) to get -a better understanding for the high-level goals. - -New features must be accompanied by tests. Before starting work on any large -feature, please [join](https://ebpf.io/slack) the -[#ebpf-go](https://cilium.slack.com/messages/ebpf-go) channel on Slack to -discuss the design first. - -When submitting pull requests, consider writing details about what problem you -are solving and why the proposed approach solves that problem in commit messages -and/or pull request description to help future library users and maintainers to -reason about the proposed changes. - -## Running the tests - -Many of the tests require privileges to set resource limits and load eBPF code. -The easiest way to obtain these is to run the tests with `sudo`. - -To test the current package with your local kernel you can simply run: -``` -go test -exec sudo ./... -``` - -To test the current package with a different kernel version you can use the [run-tests.sh](run-tests.sh) script. -It requires [virtme](https://github.com/amluto/virtme) and qemu to be installed. - -Examples: - -```bash -# Run all tests on a 5.4 kernel -./run-tests.sh 5.4 - -# Run a subset of tests: -./run-tests.sh 5.4 go test ./link -``` - diff --git a/vendor/github.com/cilium/ebpf/LICENSE b/vendor/github.com/cilium/ebpf/LICENSE deleted file mode 100644 index c637ae99..00000000 --- a/vendor/github.com/cilium/ebpf/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -MIT License - -Copyright (c) 2017 Nathan Sweet -Copyright (c) 2018, 2019 Cloudflare -Copyright (c) 2019 Authors of Cilium - -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/cilium/ebpf/MAINTAINERS.md b/vendor/github.com/cilium/ebpf/MAINTAINERS.md deleted file mode 100644 index 9c18e7e7..00000000 --- a/vendor/github.com/cilium/ebpf/MAINTAINERS.md +++ /dev/null @@ -1,8 +0,0 @@ -# Maintainers - - * [Lorenz Bauer] - * [Timo Beckers] (Isovalent) - - -[Lorenz Bauer]: https://github.com/lmb -[Timo Beckers]: https://github.com/ti-mo diff --git a/vendor/github.com/cilium/ebpf/Makefile b/vendor/github.com/cilium/ebpf/Makefile deleted file mode 100644 index 2d5f04c3..00000000 --- a/vendor/github.com/cilium/ebpf/Makefile +++ /dev/null @@ -1,110 +0,0 @@ -# The development version of clang is distributed as the 'clang' binary, -# while stable/released versions have a version number attached. -# Pin the default clang to a stable version. -CLANG ?= clang-14 -STRIP ?= llvm-strip-14 -OBJCOPY ?= llvm-objcopy-14 -CFLAGS := -O2 -g -Wall -Werror $(CFLAGS) - -CI_KERNEL_URL ?= https://github.com/cilium/ci-kernels/raw/master/ - -# Obtain an absolute path to the directory of the Makefile. -# Assume the Makefile is in the root of the repository. -REPODIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) -UIDGID := $(shell stat -c '%u:%g' ${REPODIR}) - -# Prefer podman if installed, otherwise use docker. -# Note: Setting the var at runtime will always override. -CONTAINER_ENGINE ?= $(if $(shell command -v podman), podman, docker) -CONTAINER_RUN_ARGS ?= $(if $(filter ${CONTAINER_ENGINE}, podman), --log-driver=none, --user "${UIDGID}") - -IMAGE := $(shell cat ${REPODIR}/testdata/docker/IMAGE) -VERSION := $(shell cat ${REPODIR}/testdata/docker/VERSION) - - -# clang <8 doesn't tag relocs properly (STT_NOTYPE) -# clang 9 is the first version emitting BTF -TARGETS := \ - testdata/loader-clang-7 \ - testdata/loader-clang-9 \ - testdata/loader-$(CLANG) \ - testdata/btf_map_init \ - testdata/invalid_map \ - testdata/raw_tracepoint \ - testdata/invalid_map_static \ - testdata/invalid_btf_map_init \ - testdata/strings \ - testdata/freplace \ - testdata/iproute2_map_compat \ - testdata/map_spin_lock \ - testdata/subprog_reloc \ - testdata/fwd_decl \ - btf/testdata/relocs \ - btf/testdata/relocs_read \ - btf/testdata/relocs_read_tgt - -.PHONY: all clean container-all container-shell generate - -.DEFAULT_TARGET = container-all - -# Build all ELF binaries using a containerized LLVM toolchain. -container-all: - ${CONTAINER_ENGINE} run --rm ${CONTAINER_RUN_ARGS} \ - -v "${REPODIR}":/ebpf -w /ebpf --env MAKEFLAGS \ - --env CFLAGS="-fdebug-prefix-map=/ebpf=." \ - --env HOME="/tmp" \ - "${IMAGE}:${VERSION}" \ - $(MAKE) all - -# (debug) Drop the user into a shell inside the container as root. -container-shell: - ${CONTAINER_ENGINE} run --rm -ti \ - -v "${REPODIR}":/ebpf -w /ebpf \ - "${IMAGE}:${VERSION}" - -clean: - -$(RM) testdata/*.elf - -$(RM) btf/testdata/*.elf - -format: - find . -type f -name "*.c" | xargs clang-format -i - -all: format $(addsuffix -el.elf,$(TARGETS)) $(addsuffix -eb.elf,$(TARGETS)) generate - ln -srf testdata/loader-$(CLANG)-el.elf testdata/loader-el.elf - ln -srf testdata/loader-$(CLANG)-eb.elf testdata/loader-eb.elf - -# $BPF_CLANG is used in go:generate invocations. -generate: export BPF_CLANG := $(CLANG) -generate: export BPF_CFLAGS := $(CFLAGS) -generate: - go generate ./cmd/bpf2go/test - go generate ./internal/sys - cd examples/ && go generate ./... - -testdata/loader-%-el.elf: testdata/loader.c - $* $(CFLAGS) -target bpfel -c $< -o $@ - $(STRIP) -g $@ - -testdata/loader-%-eb.elf: testdata/loader.c - $* $(CFLAGS) -target bpfeb -c $< -o $@ - $(STRIP) -g $@ - -%-el.elf: %.c - $(CLANG) $(CFLAGS) -target bpfel -c $< -o $@ - $(STRIP) -g $@ - -%-eb.elf : %.c - $(CLANG) $(CFLAGS) -target bpfeb -c $< -o $@ - $(STRIP) -g $@ - -.PHONY: generate-btf -generate-btf: KERNEL_VERSION?=5.18 -generate-btf: - $(eval TMP := $(shell mktemp -d)) - curl -fL "$(CI_KERNEL_URL)/linux-$(KERNEL_VERSION).bz" -o "$(TMP)/bzImage" - ./testdata/extract-vmlinux "$(TMP)/bzImage" > "$(TMP)/vmlinux" - $(OBJCOPY) --dump-section .BTF=/dev/stdout "$(TMP)/vmlinux" /dev/null | gzip > "btf/testdata/vmlinux.btf.gz" - curl -fL "$(CI_KERNEL_URL)/linux-$(KERNEL_VERSION)-selftests-bpf.tgz" -o "$(TMP)/selftests.tgz" - tar -xf "$(TMP)/selftests.tgz" --to-stdout tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.ko | \ - $(OBJCOPY) --dump-section .BTF="btf/testdata/btf_testmod.btf" - /dev/null - $(RM) -r "$(TMP)" diff --git a/vendor/github.com/cilium/ebpf/README.md b/vendor/github.com/cilium/ebpf/README.md deleted file mode 100644 index 3e490de7..00000000 --- a/vendor/github.com/cilium/ebpf/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# eBPF - -[![PkgGoDev](https://pkg.go.dev/badge/github.com/cilium/ebpf)](https://pkg.go.dev/github.com/cilium/ebpf) - -![HoneyGopher](.github/images/cilium-ebpf.png) - -eBPF is a pure Go library that provides utilities for loading, compiling, and -debugging eBPF programs. It has minimal external dependencies and is intended to -be used in long running processes. - -The library is maintained by [Cloudflare](https://www.cloudflare.com) and -[Cilium](https://www.cilium.io). - -See [ebpf.io](https://ebpf.io) for other projects from the eBPF ecosystem. - -## Getting Started - -A small collection of Go and eBPF programs that serve as examples for building -your own tools can be found under [examples/](examples/). - -Contributions are highly encouraged, as they highlight certain use cases of -eBPF and the library, and help shape the future of the project. - -## Getting Help - -Please -[join](https://ebpf.io/slack) the -[#ebpf-go](https://cilium.slack.com/messages/ebpf-go) channel on Slack if you -have questions regarding the library. - -## Packages - -This library includes the following packages: - -* [asm](https://pkg.go.dev/github.com/cilium/ebpf/asm) contains a basic - assembler, allowing you to write eBPF assembly instructions directly - within your Go code. (You don't need to use this if you prefer to write your eBPF program in C.) -* [cmd/bpf2go](https://pkg.go.dev/github.com/cilium/ebpf/cmd/bpf2go) allows - compiling and embedding eBPF programs written in C within Go code. As well as - compiling the C code, it auto-generates Go code for loading and manipulating - the eBPF program and map objects. -* [link](https://pkg.go.dev/github.com/cilium/ebpf/link) allows attaching eBPF - to various hooks -* [perf](https://pkg.go.dev/github.com/cilium/ebpf/perf) allows reading from a - `PERF_EVENT_ARRAY` -* [ringbuf](https://pkg.go.dev/github.com/cilium/ebpf/ringbuf) allows reading from a - `BPF_MAP_TYPE_RINGBUF` map -* [features](https://pkg.go.dev/github.com/cilium/ebpf/features) implements the equivalent - of `bpftool feature probe` for discovering BPF-related kernel features using native Go. -* [rlimit](https://pkg.go.dev/github.com/cilium/ebpf/rlimit) provides a convenient API to lift - the `RLIMIT_MEMLOCK` constraint on kernels before 5.11. - -## Requirements - -* A version of Go that is [supported by - upstream](https://golang.org/doc/devel/release.html#policy) -* Linux >= 4.9. CI is run against kernel.org LTS releases. 4.4 should work but is - not tested against. - -## Regenerating Testdata - -Run `make` in the root of this repository to rebuild testdata in all -subpackages. This requires Docker, as it relies on a standardized build -environment to keep the build output stable. - -It is possible to regenerate data using Podman by overriding the `CONTAINER_*` -variables: `CONTAINER_ENGINE=podman CONTAINER_RUN_ARGS= make`. - -The toolchain image build files are kept in [testdata/docker/](testdata/docker/). - -## License - -MIT - -### eBPF Gopher - -The eBPF honeygopher is based on the Go gopher designed by Renee French. diff --git a/vendor/github.com/cilium/ebpf/asm/alu.go b/vendor/github.com/cilium/ebpf/asm/alu.go deleted file mode 100644 index 70ccc4d1..00000000 --- a/vendor/github.com/cilium/ebpf/asm/alu.go +++ /dev/null @@ -1,149 +0,0 @@ -package asm - -//go:generate stringer -output alu_string.go -type=Source,Endianness,ALUOp - -// Source of ALU / ALU64 / Branch operations -// -// msb lsb -// +----+-+---+ -// |op |S|cls| -// +----+-+---+ -type Source uint8 - -const sourceMask OpCode = 0x08 - -// Source bitmask -const ( - // InvalidSource is returned by getters when invoked - // on non ALU / branch OpCodes. - InvalidSource Source = 0xff - // ImmSource src is from constant - ImmSource Source = 0x00 - // RegSource src is from register - RegSource Source = 0x08 -) - -// The Endianness of a byte swap instruction. -type Endianness uint8 - -const endianMask = sourceMask - -// Endian flags -const ( - InvalidEndian Endianness = 0xff - // Convert to little endian - LE Endianness = 0x00 - // Convert to big endian - BE Endianness = 0x08 -) - -// ALUOp are ALU / ALU64 operations -// -// msb lsb -// +----+-+---+ -// |OP |s|cls| -// +----+-+---+ -type ALUOp uint8 - -const aluMask OpCode = 0xf0 - -const ( - // InvalidALUOp is returned by getters when invoked - // on non ALU OpCodes - InvalidALUOp ALUOp = 0xff - // Add - addition - Add ALUOp = 0x00 - // Sub - subtraction - Sub ALUOp = 0x10 - // Mul - multiplication - Mul ALUOp = 0x20 - // Div - division - Div ALUOp = 0x30 - // Or - bitwise or - Or ALUOp = 0x40 - // And - bitwise and - And ALUOp = 0x50 - // LSh - bitwise shift left - LSh ALUOp = 0x60 - // RSh - bitwise shift right - RSh ALUOp = 0x70 - // Neg - sign/unsign signing bit - Neg ALUOp = 0x80 - // Mod - modulo - Mod ALUOp = 0x90 - // Xor - bitwise xor - Xor ALUOp = 0xa0 - // Mov - move value from one place to another - Mov ALUOp = 0xb0 - // ArSh - arithmatic shift - ArSh ALUOp = 0xc0 - // Swap - endian conversions - Swap ALUOp = 0xd0 -) - -// HostTo converts from host to another endianness. -func HostTo(endian Endianness, dst Register, size Size) Instruction { - var imm int64 - switch size { - case Half: - imm = 16 - case Word: - imm = 32 - case DWord: - imm = 64 - default: - return Instruction{OpCode: InvalidOpCode} - } - - return Instruction{ - OpCode: OpCode(ALUClass).SetALUOp(Swap).SetSource(Source(endian)), - Dst: dst, - Constant: imm, - } -} - -// Op returns the OpCode for an ALU operation with a given source. -func (op ALUOp) Op(source Source) OpCode { - return OpCode(ALU64Class).SetALUOp(op).SetSource(source) -} - -// Reg emits `dst (op) src`. -func (op ALUOp) Reg(dst, src Register) Instruction { - return Instruction{ - OpCode: op.Op(RegSource), - Dst: dst, - Src: src, - } -} - -// Imm emits `dst (op) value`. -func (op ALUOp) Imm(dst Register, value int32) Instruction { - return Instruction{ - OpCode: op.Op(ImmSource), - Dst: dst, - Constant: int64(value), - } -} - -// Op32 returns the OpCode for a 32-bit ALU operation with a given source. -func (op ALUOp) Op32(source Source) OpCode { - return OpCode(ALUClass).SetALUOp(op).SetSource(source) -} - -// Reg32 emits `dst (op) src`, zeroing the upper 32 bit of dst. -func (op ALUOp) Reg32(dst, src Register) Instruction { - return Instruction{ - OpCode: op.Op32(RegSource), - Dst: dst, - Src: src, - } -} - -// Imm32 emits `dst (op) value`, zeroing the upper 32 bit of dst. -func (op ALUOp) Imm32(dst Register, value int32) Instruction { - return Instruction{ - OpCode: op.Op32(ImmSource), - Dst: dst, - Constant: int64(value), - } -} diff --git a/vendor/github.com/cilium/ebpf/asm/alu_string.go b/vendor/github.com/cilium/ebpf/asm/alu_string.go deleted file mode 100644 index 72d3fe62..00000000 --- a/vendor/github.com/cilium/ebpf/asm/alu_string.go +++ /dev/null @@ -1,107 +0,0 @@ -// Code generated by "stringer -output alu_string.go -type=Source,Endianness,ALUOp"; DO NOT EDIT. - -package asm - -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[InvalidSource-255] - _ = x[ImmSource-0] - _ = x[RegSource-8] -} - -const ( - _Source_name_0 = "ImmSource" - _Source_name_1 = "RegSource" - _Source_name_2 = "InvalidSource" -) - -func (i Source) String() string { - switch { - case i == 0: - return _Source_name_0 - case i == 8: - return _Source_name_1 - case i == 255: - return _Source_name_2 - default: - return "Source(" + 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[InvalidEndian-255] - _ = x[LE-0] - _ = x[BE-8] -} - -const ( - _Endianness_name_0 = "LE" - _Endianness_name_1 = "BE" - _Endianness_name_2 = "InvalidEndian" -) - -func (i Endianness) String() string { - switch { - case i == 0: - return _Endianness_name_0 - case i == 8: - return _Endianness_name_1 - case i == 255: - return _Endianness_name_2 - default: - return "Endianness(" + 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[InvalidALUOp-255] - _ = x[Add-0] - _ = x[Sub-16] - _ = x[Mul-32] - _ = x[Div-48] - _ = x[Or-64] - _ = x[And-80] - _ = x[LSh-96] - _ = x[RSh-112] - _ = x[Neg-128] - _ = x[Mod-144] - _ = x[Xor-160] - _ = x[Mov-176] - _ = x[ArSh-192] - _ = x[Swap-208] -} - -const _ALUOp_name = "AddSubMulDivOrAndLShRShNegModXorMovArShSwapInvalidALUOp" - -var _ALUOp_map = map[ALUOp]string{ - 0: _ALUOp_name[0:3], - 16: _ALUOp_name[3:6], - 32: _ALUOp_name[6:9], - 48: _ALUOp_name[9:12], - 64: _ALUOp_name[12:14], - 80: _ALUOp_name[14:17], - 96: _ALUOp_name[17:20], - 112: _ALUOp_name[20:23], - 128: _ALUOp_name[23:26], - 144: _ALUOp_name[26:29], - 160: _ALUOp_name[29:32], - 176: _ALUOp_name[32:35], - 192: _ALUOp_name[35:39], - 208: _ALUOp_name[39:43], - 255: _ALUOp_name[43:55], -} - -func (i ALUOp) String() string { - if str, ok := _ALUOp_map[i]; ok { - return str - } - return "ALUOp(" + strconv.FormatInt(int64(i), 10) + ")" -} diff --git a/vendor/github.com/cilium/ebpf/asm/doc.go b/vendor/github.com/cilium/ebpf/asm/doc.go deleted file mode 100644 index 7031bdc2..00000000 --- a/vendor/github.com/cilium/ebpf/asm/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package asm is an assembler for eBPF bytecode. -package asm diff --git a/vendor/github.com/cilium/ebpf/asm/func.go b/vendor/github.com/cilium/ebpf/asm/func.go deleted file mode 100644 index a14e9e2c..00000000 --- a/vendor/github.com/cilium/ebpf/asm/func.go +++ /dev/null @@ -1,242 +0,0 @@ -package asm - -//go:generate stringer -output func_string.go -type=BuiltinFunc - -// BuiltinFunc is a built-in eBPF function. -type BuiltinFunc int32 - -func (_ BuiltinFunc) Max() BuiltinFunc { - return maxBuiltinFunc - 1 -} - -// eBPF built-in functions -// -// You can regenerate this list using the following gawk script: -// -// /FN\(.+\),/ { -// match($1, /\((.+)\)/, r) -// split(r[1], p, "_") -// printf "Fn" -// for (i in p) { -// printf "%s%s", toupper(substr(p[i], 1, 1)), substr(p[i], 2) -// } -// print "" -// } -// -// The script expects include/uapi/linux/bpf.h as it's input. -const ( - FnUnspec BuiltinFunc = iota - FnMapLookupElem - FnMapUpdateElem - FnMapDeleteElem - FnProbeRead - FnKtimeGetNs - FnTracePrintk - FnGetPrandomU32 - FnGetSmpProcessorId - FnSkbStoreBytes - FnL3CsumReplace - FnL4CsumReplace - FnTailCall - FnCloneRedirect - FnGetCurrentPidTgid - FnGetCurrentUidGid - FnGetCurrentComm - FnGetCgroupClassid - FnSkbVlanPush - FnSkbVlanPop - FnSkbGetTunnelKey - FnSkbSetTunnelKey - FnPerfEventRead - FnRedirect - FnGetRouteRealm - FnPerfEventOutput - FnSkbLoadBytes - FnGetStackid - FnCsumDiff - FnSkbGetTunnelOpt - FnSkbSetTunnelOpt - FnSkbChangeProto - FnSkbChangeType - FnSkbUnderCgroup - FnGetHashRecalc - FnGetCurrentTask - FnProbeWriteUser - FnCurrentTaskUnderCgroup - FnSkbChangeTail - FnSkbPullData - FnCsumUpdate - FnSetHashInvalid - FnGetNumaNodeId - FnSkbChangeHead - FnXdpAdjustHead - FnProbeReadStr - FnGetSocketCookie - FnGetSocketUid - FnSetHash - FnSetsockopt - FnSkbAdjustRoom - FnRedirectMap - FnSkRedirectMap - FnSockMapUpdate - FnXdpAdjustMeta - FnPerfEventReadValue - FnPerfProgReadValue - FnGetsockopt - FnOverrideReturn - FnSockOpsCbFlagsSet - FnMsgRedirectMap - FnMsgApplyBytes - FnMsgCorkBytes - FnMsgPullData - FnBind - FnXdpAdjustTail - FnSkbGetXfrmState - FnGetStack - FnSkbLoadBytesRelative - FnFibLookup - FnSockHashUpdate - FnMsgRedirectHash - FnSkRedirectHash - FnLwtPushEncap - FnLwtSeg6StoreBytes - FnLwtSeg6AdjustSrh - FnLwtSeg6Action - FnRcRepeat - FnRcKeydown - FnSkbCgroupId - FnGetCurrentCgroupId - FnGetLocalStorage - FnSkSelectReuseport - FnSkbAncestorCgroupId - FnSkLookupTcp - FnSkLookupUdp - FnSkRelease - FnMapPushElem - FnMapPopElem - FnMapPeekElem - FnMsgPushData - FnMsgPopData - FnRcPointerRel - FnSpinLock - FnSpinUnlock - FnSkFullsock - FnTcpSock - FnSkbEcnSetCe - FnGetListenerSock - FnSkcLookupTcp - FnTcpCheckSyncookie - FnSysctlGetName - FnSysctlGetCurrentValue - FnSysctlGetNewValue - FnSysctlSetNewValue - FnStrtol - FnStrtoul - FnSkStorageGet - FnSkStorageDelete - FnSendSignal - FnTcpGenSyncookie - FnSkbOutput - FnProbeReadUser - FnProbeReadKernel - FnProbeReadUserStr - FnProbeReadKernelStr - FnTcpSendAck - FnSendSignalThread - FnJiffies64 - FnReadBranchRecords - FnGetNsCurrentPidTgid - FnXdpOutput - FnGetNetnsCookie - FnGetCurrentAncestorCgroupId - FnSkAssign - FnKtimeGetBootNs - FnSeqPrintf - FnSeqWrite - FnSkCgroupId - FnSkAncestorCgroupId - FnRingbufOutput - FnRingbufReserve - FnRingbufSubmit - FnRingbufDiscard - FnRingbufQuery - FnCsumLevel - FnSkcToTcp6Sock - FnSkcToTcpSock - FnSkcToTcpTimewaitSock - FnSkcToTcpRequestSock - FnSkcToUdp6Sock - FnGetTaskStack - FnLoadHdrOpt - FnStoreHdrOpt - FnReserveHdrOpt - FnInodeStorageGet - FnInodeStorageDelete - FnDPath - FnCopyFromUser - FnSnprintfBtf - FnSeqPrintfBtf - FnSkbCgroupClassid - FnRedirectNeigh - FnPerCpuPtr - FnThisCpuPtr - FnRedirectPeer - FnTaskStorageGet - FnTaskStorageDelete - FnGetCurrentTaskBtf - FnBprmOptsSet - FnKtimeGetCoarseNs - FnImaInodeHash - FnSockFromFile - FnCheckMtu - FnForEachMapElem - FnSnprintf - FnSysBpf - FnBtfFindByNameKind - FnSysClose - FnTimerInit - FnTimerSetCallback - FnTimerStart - FnTimerCancel - FnGetFuncIp - FnGetAttachCookie - FnTaskPtRegs - FnGetBranchSnapshot - FnTraceVprintk - FnSkcToUnixSock - FnKallsymsLookupName - FnFindVma - FnLoop - FnStrncmp - FnGetFuncArg - FnGetFuncRet - FnGetFuncArgCnt - FnGetRetval - FnSetRetval - FnXdpGetBuffLen - FnXdpLoadBytes - FnXdpStoreBytes - FnCopyFromUserTask - FnSkbSetTstamp - FnImaFileHash - FnKptrXchg - FnMapLookupPercpuElem - FnSkcToMptcpSock - FnDynptrFromMem - FnRingbufReserveDynptr - FnRingbufSubmitDynptr - FnRingbufDiscardDynptr - FnDynptrRead - FnDynptrWrite - FnDynptrData - - maxBuiltinFunc -) - -// Call emits a function call. -func (fn BuiltinFunc) Call() Instruction { - return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(Call), - Constant: int64(fn), - } -} diff --git a/vendor/github.com/cilium/ebpf/asm/func_string.go b/vendor/github.com/cilium/ebpf/asm/func_string.go deleted file mode 100644 index b7431b7f..00000000 --- a/vendor/github.com/cilium/ebpf/asm/func_string.go +++ /dev/null @@ -1,227 +0,0 @@ -// Code generated by "stringer -output func_string.go -type=BuiltinFunc"; DO NOT EDIT. - -package asm - -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[FnUnspec-0] - _ = x[FnMapLookupElem-1] - _ = x[FnMapUpdateElem-2] - _ = x[FnMapDeleteElem-3] - _ = x[FnProbeRead-4] - _ = x[FnKtimeGetNs-5] - _ = x[FnTracePrintk-6] - _ = x[FnGetPrandomU32-7] - _ = x[FnGetSmpProcessorId-8] - _ = x[FnSkbStoreBytes-9] - _ = x[FnL3CsumReplace-10] - _ = x[FnL4CsumReplace-11] - _ = x[FnTailCall-12] - _ = x[FnCloneRedirect-13] - _ = x[FnGetCurrentPidTgid-14] - _ = x[FnGetCurrentUidGid-15] - _ = x[FnGetCurrentComm-16] - _ = x[FnGetCgroupClassid-17] - _ = x[FnSkbVlanPush-18] - _ = x[FnSkbVlanPop-19] - _ = x[FnSkbGetTunnelKey-20] - _ = x[FnSkbSetTunnelKey-21] - _ = x[FnPerfEventRead-22] - _ = x[FnRedirect-23] - _ = x[FnGetRouteRealm-24] - _ = x[FnPerfEventOutput-25] - _ = x[FnSkbLoadBytes-26] - _ = x[FnGetStackid-27] - _ = x[FnCsumDiff-28] - _ = x[FnSkbGetTunnelOpt-29] - _ = x[FnSkbSetTunnelOpt-30] - _ = x[FnSkbChangeProto-31] - _ = x[FnSkbChangeType-32] - _ = x[FnSkbUnderCgroup-33] - _ = x[FnGetHashRecalc-34] - _ = x[FnGetCurrentTask-35] - _ = x[FnProbeWriteUser-36] - _ = x[FnCurrentTaskUnderCgroup-37] - _ = x[FnSkbChangeTail-38] - _ = x[FnSkbPullData-39] - _ = x[FnCsumUpdate-40] - _ = x[FnSetHashInvalid-41] - _ = x[FnGetNumaNodeId-42] - _ = x[FnSkbChangeHead-43] - _ = x[FnXdpAdjustHead-44] - _ = x[FnProbeReadStr-45] - _ = x[FnGetSocketCookie-46] - _ = x[FnGetSocketUid-47] - _ = x[FnSetHash-48] - _ = x[FnSetsockopt-49] - _ = x[FnSkbAdjustRoom-50] - _ = x[FnRedirectMap-51] - _ = x[FnSkRedirectMap-52] - _ = x[FnSockMapUpdate-53] - _ = x[FnXdpAdjustMeta-54] - _ = x[FnPerfEventReadValue-55] - _ = x[FnPerfProgReadValue-56] - _ = x[FnGetsockopt-57] - _ = x[FnOverrideReturn-58] - _ = x[FnSockOpsCbFlagsSet-59] - _ = x[FnMsgRedirectMap-60] - _ = x[FnMsgApplyBytes-61] - _ = x[FnMsgCorkBytes-62] - _ = x[FnMsgPullData-63] - _ = x[FnBind-64] - _ = x[FnXdpAdjustTail-65] - _ = x[FnSkbGetXfrmState-66] - _ = x[FnGetStack-67] - _ = x[FnSkbLoadBytesRelative-68] - _ = x[FnFibLookup-69] - _ = x[FnSockHashUpdate-70] - _ = x[FnMsgRedirectHash-71] - _ = x[FnSkRedirectHash-72] - _ = x[FnLwtPushEncap-73] - _ = x[FnLwtSeg6StoreBytes-74] - _ = x[FnLwtSeg6AdjustSrh-75] - _ = x[FnLwtSeg6Action-76] - _ = x[FnRcRepeat-77] - _ = x[FnRcKeydown-78] - _ = x[FnSkbCgroupId-79] - _ = x[FnGetCurrentCgroupId-80] - _ = x[FnGetLocalStorage-81] - _ = x[FnSkSelectReuseport-82] - _ = x[FnSkbAncestorCgroupId-83] - _ = x[FnSkLookupTcp-84] - _ = x[FnSkLookupUdp-85] - _ = x[FnSkRelease-86] - _ = x[FnMapPushElem-87] - _ = x[FnMapPopElem-88] - _ = x[FnMapPeekElem-89] - _ = x[FnMsgPushData-90] - _ = x[FnMsgPopData-91] - _ = x[FnRcPointerRel-92] - _ = x[FnSpinLock-93] - _ = x[FnSpinUnlock-94] - _ = x[FnSkFullsock-95] - _ = x[FnTcpSock-96] - _ = x[FnSkbEcnSetCe-97] - _ = x[FnGetListenerSock-98] - _ = x[FnSkcLookupTcp-99] - _ = x[FnTcpCheckSyncookie-100] - _ = x[FnSysctlGetName-101] - _ = x[FnSysctlGetCurrentValue-102] - _ = x[FnSysctlGetNewValue-103] - _ = x[FnSysctlSetNewValue-104] - _ = x[FnStrtol-105] - _ = x[FnStrtoul-106] - _ = x[FnSkStorageGet-107] - _ = x[FnSkStorageDelete-108] - _ = x[FnSendSignal-109] - _ = x[FnTcpGenSyncookie-110] - _ = x[FnSkbOutput-111] - _ = x[FnProbeReadUser-112] - _ = x[FnProbeReadKernel-113] - _ = x[FnProbeReadUserStr-114] - _ = x[FnProbeReadKernelStr-115] - _ = x[FnTcpSendAck-116] - _ = x[FnSendSignalThread-117] - _ = x[FnJiffies64-118] - _ = x[FnReadBranchRecords-119] - _ = x[FnGetNsCurrentPidTgid-120] - _ = x[FnXdpOutput-121] - _ = x[FnGetNetnsCookie-122] - _ = x[FnGetCurrentAncestorCgroupId-123] - _ = x[FnSkAssign-124] - _ = x[FnKtimeGetBootNs-125] - _ = x[FnSeqPrintf-126] - _ = x[FnSeqWrite-127] - _ = x[FnSkCgroupId-128] - _ = x[FnSkAncestorCgroupId-129] - _ = x[FnRingbufOutput-130] - _ = x[FnRingbufReserve-131] - _ = x[FnRingbufSubmit-132] - _ = x[FnRingbufDiscard-133] - _ = x[FnRingbufQuery-134] - _ = x[FnCsumLevel-135] - _ = x[FnSkcToTcp6Sock-136] - _ = x[FnSkcToTcpSock-137] - _ = x[FnSkcToTcpTimewaitSock-138] - _ = x[FnSkcToTcpRequestSock-139] - _ = x[FnSkcToUdp6Sock-140] - _ = x[FnGetTaskStack-141] - _ = x[FnLoadHdrOpt-142] - _ = x[FnStoreHdrOpt-143] - _ = x[FnReserveHdrOpt-144] - _ = x[FnInodeStorageGet-145] - _ = x[FnInodeStorageDelete-146] - _ = x[FnDPath-147] - _ = x[FnCopyFromUser-148] - _ = x[FnSnprintfBtf-149] - _ = x[FnSeqPrintfBtf-150] - _ = x[FnSkbCgroupClassid-151] - _ = x[FnRedirectNeigh-152] - _ = x[FnPerCpuPtr-153] - _ = x[FnThisCpuPtr-154] - _ = x[FnRedirectPeer-155] - _ = x[FnTaskStorageGet-156] - _ = x[FnTaskStorageDelete-157] - _ = x[FnGetCurrentTaskBtf-158] - _ = x[FnBprmOptsSet-159] - _ = x[FnKtimeGetCoarseNs-160] - _ = x[FnImaInodeHash-161] - _ = x[FnSockFromFile-162] - _ = x[FnCheckMtu-163] - _ = x[FnForEachMapElem-164] - _ = x[FnSnprintf-165] - _ = x[FnSysBpf-166] - _ = x[FnBtfFindByNameKind-167] - _ = x[FnSysClose-168] - _ = x[FnTimerInit-169] - _ = x[FnTimerSetCallback-170] - _ = x[FnTimerStart-171] - _ = x[FnTimerCancel-172] - _ = x[FnGetFuncIp-173] - _ = x[FnGetAttachCookie-174] - _ = x[FnTaskPtRegs-175] - _ = x[FnGetBranchSnapshot-176] - _ = x[FnTraceVprintk-177] - _ = x[FnSkcToUnixSock-178] - _ = x[FnKallsymsLookupName-179] - _ = x[FnFindVma-180] - _ = x[FnLoop-181] - _ = x[FnStrncmp-182] - _ = x[FnGetFuncArg-183] - _ = x[FnGetFuncRet-184] - _ = x[FnGetFuncArgCnt-185] - _ = x[FnGetRetval-186] - _ = x[FnSetRetval-187] - _ = x[FnXdpGetBuffLen-188] - _ = x[FnXdpLoadBytes-189] - _ = x[FnXdpStoreBytes-190] - _ = x[FnCopyFromUserTask-191] - _ = x[FnSkbSetTstamp-192] - _ = x[FnImaFileHash-193] - _ = x[FnKptrXchg-194] - _ = x[FnMapLookupPercpuElem-195] - _ = x[FnSkcToMptcpSock-196] - _ = x[FnDynptrFromMem-197] - _ = x[FnRingbufReserveDynptr-198] - _ = x[FnRingbufSubmitDynptr-199] - _ = x[FnRingbufDiscardDynptr-200] - _ = x[FnDynptrRead-201] - _ = x[FnDynptrWrite-202] - _ = x[FnDynptrData-203] - _ = x[maxBuiltinFunc-204] -} - -const _BuiltinFunc_name = "FnUnspecFnMapLookupElemFnMapUpdateElemFnMapDeleteElemFnProbeReadFnKtimeGetNsFnTracePrintkFnGetPrandomU32FnGetSmpProcessorIdFnSkbStoreBytesFnL3CsumReplaceFnL4CsumReplaceFnTailCallFnCloneRedirectFnGetCurrentPidTgidFnGetCurrentUidGidFnGetCurrentCommFnGetCgroupClassidFnSkbVlanPushFnSkbVlanPopFnSkbGetTunnelKeyFnSkbSetTunnelKeyFnPerfEventReadFnRedirectFnGetRouteRealmFnPerfEventOutputFnSkbLoadBytesFnGetStackidFnCsumDiffFnSkbGetTunnelOptFnSkbSetTunnelOptFnSkbChangeProtoFnSkbChangeTypeFnSkbUnderCgroupFnGetHashRecalcFnGetCurrentTaskFnProbeWriteUserFnCurrentTaskUnderCgroupFnSkbChangeTailFnSkbPullDataFnCsumUpdateFnSetHashInvalidFnGetNumaNodeIdFnSkbChangeHeadFnXdpAdjustHeadFnProbeReadStrFnGetSocketCookieFnGetSocketUidFnSetHashFnSetsockoptFnSkbAdjustRoomFnRedirectMapFnSkRedirectMapFnSockMapUpdateFnXdpAdjustMetaFnPerfEventReadValueFnPerfProgReadValueFnGetsockoptFnOverrideReturnFnSockOpsCbFlagsSetFnMsgRedirectMapFnMsgApplyBytesFnMsgCorkBytesFnMsgPullDataFnBindFnXdpAdjustTailFnSkbGetXfrmStateFnGetStackFnSkbLoadBytesRelativeFnFibLookupFnSockHashUpdateFnMsgRedirectHashFnSkRedirectHashFnLwtPushEncapFnLwtSeg6StoreBytesFnLwtSeg6AdjustSrhFnLwtSeg6ActionFnRcRepeatFnRcKeydownFnSkbCgroupIdFnGetCurrentCgroupIdFnGetLocalStorageFnSkSelectReuseportFnSkbAncestorCgroupIdFnSkLookupTcpFnSkLookupUdpFnSkReleaseFnMapPushElemFnMapPopElemFnMapPeekElemFnMsgPushDataFnMsgPopDataFnRcPointerRelFnSpinLockFnSpinUnlockFnSkFullsockFnTcpSockFnSkbEcnSetCeFnGetListenerSockFnSkcLookupTcpFnTcpCheckSyncookieFnSysctlGetNameFnSysctlGetCurrentValueFnSysctlGetNewValueFnSysctlSetNewValueFnStrtolFnStrtoulFnSkStorageGetFnSkStorageDeleteFnSendSignalFnTcpGenSyncookieFnSkbOutputFnProbeReadUserFnProbeReadKernelFnProbeReadUserStrFnProbeReadKernelStrFnTcpSendAckFnSendSignalThreadFnJiffies64FnReadBranchRecordsFnGetNsCurrentPidTgidFnXdpOutputFnGetNetnsCookieFnGetCurrentAncestorCgroupIdFnSkAssignFnKtimeGetBootNsFnSeqPrintfFnSeqWriteFnSkCgroupIdFnSkAncestorCgroupIdFnRingbufOutputFnRingbufReserveFnRingbufSubmitFnRingbufDiscardFnRingbufQueryFnCsumLevelFnSkcToTcp6SockFnSkcToTcpSockFnSkcToTcpTimewaitSockFnSkcToTcpRequestSockFnSkcToUdp6SockFnGetTaskStackFnLoadHdrOptFnStoreHdrOptFnReserveHdrOptFnInodeStorageGetFnInodeStorageDeleteFnDPathFnCopyFromUserFnSnprintfBtfFnSeqPrintfBtfFnSkbCgroupClassidFnRedirectNeighFnPerCpuPtrFnThisCpuPtrFnRedirectPeerFnTaskStorageGetFnTaskStorageDeleteFnGetCurrentTaskBtfFnBprmOptsSetFnKtimeGetCoarseNsFnImaInodeHashFnSockFromFileFnCheckMtuFnForEachMapElemFnSnprintfFnSysBpfFnBtfFindByNameKindFnSysCloseFnTimerInitFnTimerSetCallbackFnTimerStartFnTimerCancelFnGetFuncIpFnGetAttachCookieFnTaskPtRegsFnGetBranchSnapshotFnTraceVprintkFnSkcToUnixSockFnKallsymsLookupNameFnFindVmaFnLoopFnStrncmpFnGetFuncArgFnGetFuncRetFnGetFuncArgCntFnGetRetvalFnSetRetvalFnXdpGetBuffLenFnXdpLoadBytesFnXdpStoreBytesFnCopyFromUserTaskFnSkbSetTstampFnImaFileHashFnKptrXchgFnMapLookupPercpuElemFnSkcToMptcpSockFnDynptrFromMemFnRingbufReserveDynptrFnRingbufSubmitDynptrFnRingbufDiscardDynptrFnDynptrReadFnDynptrWriteFnDynptrDatamaxBuiltinFunc" - -var _BuiltinFunc_index = [...]uint16{0, 8, 23, 38, 53, 64, 76, 89, 104, 123, 138, 153, 168, 178, 193, 212, 230, 246, 264, 277, 289, 306, 323, 338, 348, 363, 380, 394, 406, 416, 433, 450, 466, 481, 497, 512, 528, 544, 568, 583, 596, 608, 624, 639, 654, 669, 683, 700, 714, 723, 735, 750, 763, 778, 793, 808, 828, 847, 859, 875, 894, 910, 925, 939, 952, 958, 973, 990, 1000, 1022, 1033, 1049, 1066, 1082, 1096, 1115, 1133, 1148, 1158, 1169, 1182, 1202, 1219, 1238, 1259, 1272, 1285, 1296, 1309, 1321, 1334, 1347, 1359, 1373, 1383, 1395, 1407, 1416, 1429, 1446, 1460, 1479, 1494, 1517, 1536, 1555, 1563, 1572, 1586, 1603, 1615, 1632, 1643, 1658, 1675, 1693, 1713, 1725, 1743, 1754, 1773, 1794, 1805, 1821, 1849, 1859, 1875, 1886, 1896, 1908, 1928, 1943, 1959, 1974, 1990, 2004, 2015, 2030, 2044, 2066, 2087, 2102, 2116, 2128, 2141, 2156, 2173, 2193, 2200, 2214, 2227, 2241, 2259, 2274, 2285, 2297, 2311, 2327, 2346, 2365, 2378, 2396, 2410, 2424, 2434, 2450, 2460, 2468, 2487, 2497, 2508, 2526, 2538, 2551, 2562, 2579, 2591, 2610, 2624, 2639, 2659, 2668, 2674, 2683, 2695, 2707, 2722, 2733, 2744, 2759, 2773, 2788, 2806, 2820, 2833, 2843, 2864, 2880, 2895, 2917, 2938, 2960, 2972, 2985, 2997, 3011} - -func (i BuiltinFunc) String() string { - if i < 0 || i >= BuiltinFunc(len(_BuiltinFunc_index)-1) { - return "BuiltinFunc(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _BuiltinFunc_name[_BuiltinFunc_index[i]:_BuiltinFunc_index[i+1]] -} diff --git a/vendor/github.com/cilium/ebpf/asm/instruction.go b/vendor/github.com/cilium/ebpf/asm/instruction.go deleted file mode 100644 index f17d88b5..00000000 --- a/vendor/github.com/cilium/ebpf/asm/instruction.go +++ /dev/null @@ -1,859 +0,0 @@ -package asm - -import ( - "crypto/sha1" - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "io" - "math" - "sort" - "strings" - - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// InstructionSize is the size of a BPF instruction in bytes -const InstructionSize = 8 - -// RawInstructionOffset is an offset in units of raw BPF instructions. -type RawInstructionOffset uint64 - -var ErrUnreferencedSymbol = errors.New("unreferenced symbol") -var ErrUnsatisfiedMapReference = errors.New("unsatisfied map reference") -var ErrUnsatisfiedProgramReference = errors.New("unsatisfied program reference") - -// Bytes returns the offset of an instruction in bytes. -func (rio RawInstructionOffset) Bytes() uint64 { - return uint64(rio) * InstructionSize -} - -// Instruction is a single eBPF instruction. -type Instruction struct { - OpCode OpCode - Dst Register - Src Register - Offset int16 - Constant int64 - - // Metadata contains optional metadata about this instruction. - Metadata Metadata -} - -// Unmarshal decodes a BPF instruction. -func (ins *Instruction) Unmarshal(r io.Reader, bo binary.ByteOrder) (uint64, error) { - data := make([]byte, InstructionSize) - if _, err := io.ReadFull(r, data); err != nil { - return 0, err - } - - ins.OpCode = OpCode(data[0]) - - regs := data[1] - switch bo { - case binary.LittleEndian: - ins.Dst, ins.Src = Register(regs&0xF), Register(regs>>4) - case binary.BigEndian: - ins.Dst, ins.Src = Register(regs>>4), Register(regs&0xf) - } - - ins.Offset = int16(bo.Uint16(data[2:4])) - // Convert to int32 before widening to int64 - // to ensure the signed bit is carried over. - ins.Constant = int64(int32(bo.Uint32(data[4:8]))) - - if !ins.OpCode.IsDWordLoad() { - return InstructionSize, nil - } - - // Pull another instruction from the stream to retrieve the second - // half of the 64-bit immediate value. - if _, err := io.ReadFull(r, data); err != nil { - // No Wrap, to avoid io.EOF clash - return 0, errors.New("64bit immediate is missing second half") - } - - // Require that all fields other than the value are zero. - if bo.Uint32(data[0:4]) != 0 { - return 0, errors.New("64bit immediate has non-zero fields") - } - - cons1 := uint32(ins.Constant) - cons2 := int32(bo.Uint32(data[4:8])) - ins.Constant = int64(cons2)<<32 | int64(cons1) - - return 2 * InstructionSize, nil -} - -// Marshal encodes a BPF instruction. -func (ins Instruction) Marshal(w io.Writer, bo binary.ByteOrder) (uint64, error) { - if ins.OpCode == InvalidOpCode { - return 0, errors.New("invalid opcode") - } - - isDWordLoad := ins.OpCode.IsDWordLoad() - - cons := int32(ins.Constant) - if isDWordLoad { - // Encode least significant 32bit first for 64bit operations. - cons = int32(uint32(ins.Constant)) - } - - regs, err := newBPFRegisters(ins.Dst, ins.Src, bo) - if err != nil { - return 0, fmt.Errorf("can't marshal registers: %s", err) - } - - data := make([]byte, InstructionSize) - data[0] = byte(ins.OpCode) - data[1] = byte(regs) - bo.PutUint16(data[2:4], uint16(ins.Offset)) - bo.PutUint32(data[4:8], uint32(cons)) - if _, err := w.Write(data); err != nil { - return 0, err - } - - if !isDWordLoad { - return InstructionSize, nil - } - - // The first half of the second part of a double-wide instruction - // must be zero. The second half carries the value. - bo.PutUint32(data[0:4], 0) - bo.PutUint32(data[4:8], uint32(ins.Constant>>32)) - if _, err := w.Write(data); err != nil { - return 0, err - } - - return 2 * InstructionSize, nil -} - -// AssociateMap associates a Map with this Instruction. -// -// Implicitly clears the Instruction's Reference field. -// -// Returns an error if the Instruction is not a map load. -func (ins *Instruction) AssociateMap(m FDer) error { - if !ins.IsLoadFromMap() { - return errors.New("not a load from a map") - } - - ins.Metadata.Set(referenceMeta{}, nil) - ins.Metadata.Set(mapMeta{}, m) - - return nil -} - -// RewriteMapPtr changes an instruction to use a new map fd. -// -// Returns an error if the instruction doesn't load a map. -// -// Deprecated: use AssociateMap instead. If you cannot provide a Map, -// wrap an fd in a type implementing FDer. -func (ins *Instruction) RewriteMapPtr(fd int) error { - if !ins.IsLoadFromMap() { - return errors.New("not a load from a map") - } - - ins.encodeMapFD(fd) - - return nil -} - -func (ins *Instruction) encodeMapFD(fd int) { - // Preserve the offset value for direct map loads. - offset := uint64(ins.Constant) & (math.MaxUint32 << 32) - rawFd := uint64(uint32(fd)) - ins.Constant = int64(offset | rawFd) -} - -// MapPtr returns the map fd for this instruction. -// -// The result is undefined if the instruction is not a load from a map, -// see IsLoadFromMap. -// -// Deprecated: use Map() instead. -func (ins *Instruction) MapPtr() int { - // If there is a map associated with the instruction, return its FD. - if fd := ins.Metadata.Get(mapMeta{}); fd != nil { - return fd.(FDer).FD() - } - - // Fall back to the fd stored in the Constant field - return ins.mapFd() -} - -// mapFd returns the map file descriptor stored in the 32 least significant -// bits of ins' Constant field. -func (ins *Instruction) mapFd() int { - return int(int32(ins.Constant)) -} - -// RewriteMapOffset changes the offset of a direct load from a map. -// -// Returns an error if the instruction is not a direct load. -func (ins *Instruction) RewriteMapOffset(offset uint32) error { - if !ins.OpCode.IsDWordLoad() { - return fmt.Errorf("%s is not a 64 bit load", ins.OpCode) - } - - if ins.Src != PseudoMapValue { - return errors.New("not a direct load from a map") - } - - fd := uint64(ins.Constant) & math.MaxUint32 - ins.Constant = int64(uint64(offset)<<32 | fd) - return nil -} - -func (ins *Instruction) mapOffset() uint32 { - return uint32(uint64(ins.Constant) >> 32) -} - -// IsLoadFromMap returns true if the instruction loads from a map. -// -// This covers both loading the map pointer and direct map value loads. -func (ins *Instruction) IsLoadFromMap() bool { - return ins.OpCode == LoadImmOp(DWord) && (ins.Src == PseudoMapFD || ins.Src == PseudoMapValue) -} - -// IsFunctionCall returns true if the instruction calls another BPF function. -// -// This is not the same thing as a BPF helper call. -func (ins *Instruction) IsFunctionCall() bool { - return ins.OpCode.JumpOp() == Call && ins.Src == PseudoCall -} - -// IsLoadOfFunctionPointer returns true if the instruction loads a function pointer. -func (ins *Instruction) IsLoadOfFunctionPointer() bool { - return ins.OpCode.IsDWordLoad() && ins.Src == PseudoFunc -} - -// IsFunctionReference returns true if the instruction references another BPF -// function, either by invoking a Call jump operation or by loading a function -// pointer. -func (ins *Instruction) IsFunctionReference() bool { - return ins.IsFunctionCall() || ins.IsLoadOfFunctionPointer() -} - -// IsBuiltinCall returns true if the instruction is a built-in call, i.e. BPF helper call. -func (ins *Instruction) IsBuiltinCall() bool { - return ins.OpCode.JumpOp() == Call && ins.Src == R0 && ins.Dst == R0 -} - -// IsConstantLoad returns true if the instruction loads a constant of the -// given size. -func (ins *Instruction) IsConstantLoad(size Size) bool { - return ins.OpCode == LoadImmOp(size) && ins.Src == R0 && ins.Offset == 0 -} - -// Format implements fmt.Formatter. -func (ins Instruction) Format(f fmt.State, c rune) { - if c != 'v' { - fmt.Fprintf(f, "{UNRECOGNIZED: %c}", c) - return - } - - op := ins.OpCode - - if op == InvalidOpCode { - fmt.Fprint(f, "INVALID") - return - } - - // Omit trailing space for Exit - if op.JumpOp() == Exit { - fmt.Fprint(f, op) - return - } - - if ins.IsLoadFromMap() { - fd := ins.mapFd() - m := ins.Map() - switch ins.Src { - case PseudoMapFD: - if m != nil { - fmt.Fprintf(f, "LoadMapPtr dst: %s map: %s", ins.Dst, m) - } else { - fmt.Fprintf(f, "LoadMapPtr dst: %s fd: %d", ins.Dst, fd) - } - - case PseudoMapValue: - if m != nil { - fmt.Fprintf(f, "LoadMapValue dst: %s, map: %s off: %d", ins.Dst, m, ins.mapOffset()) - } else { - fmt.Fprintf(f, "LoadMapValue dst: %s, fd: %d off: %d", ins.Dst, fd, ins.mapOffset()) - } - } - - goto ref - } - - fmt.Fprintf(f, "%v ", op) - switch cls := op.Class(); { - case cls.isLoadOrStore(): - switch op.Mode() { - case ImmMode: - fmt.Fprintf(f, "dst: %s imm: %d", ins.Dst, ins.Constant) - case AbsMode: - fmt.Fprintf(f, "imm: %d", ins.Constant) - case IndMode: - fmt.Fprintf(f, "dst: %s src: %s imm: %d", ins.Dst, ins.Src, ins.Constant) - case MemMode: - fmt.Fprintf(f, "dst: %s src: %s off: %d imm: %d", ins.Dst, ins.Src, ins.Offset, ins.Constant) - case XAddMode: - fmt.Fprintf(f, "dst: %s src: %s", ins.Dst, ins.Src) - } - - case cls.IsALU(): - fmt.Fprintf(f, "dst: %s ", ins.Dst) - if op.ALUOp() == Swap || op.Source() == ImmSource { - fmt.Fprintf(f, "imm: %d", ins.Constant) - } else { - fmt.Fprintf(f, "src: %s", ins.Src) - } - - case cls.IsJump(): - switch jop := op.JumpOp(); jop { - case Call: - if ins.Src == PseudoCall { - // bpf-to-bpf call - fmt.Fprint(f, ins.Constant) - } else { - fmt.Fprint(f, BuiltinFunc(ins.Constant)) - } - - default: - fmt.Fprintf(f, "dst: %s off: %d ", ins.Dst, ins.Offset) - if op.Source() == ImmSource { - fmt.Fprintf(f, "imm: %d", ins.Constant) - } else { - fmt.Fprintf(f, "src: %s", ins.Src) - } - } - } - -ref: - if ins.Reference() != "" { - fmt.Fprintf(f, " <%s>", ins.Reference()) - } -} - -func (ins Instruction) equal(other Instruction) bool { - return ins.OpCode == other.OpCode && - ins.Dst == other.Dst && - ins.Src == other.Src && - ins.Offset == other.Offset && - ins.Constant == other.Constant -} - -// Size returns the amount of bytes ins would occupy in binary form. -func (ins Instruction) Size() uint64 { - return uint64(InstructionSize * ins.OpCode.rawInstructions()) -} - -type symbolMeta struct{} - -// WithSymbol marks the Instruction as a Symbol, which other Instructions -// can point to using corresponding calls to WithReference. -func (ins Instruction) WithSymbol(name string) Instruction { - ins.Metadata.Set(symbolMeta{}, name) - return ins -} - -// Sym creates a symbol. -// -// Deprecated: use WithSymbol instead. -func (ins Instruction) Sym(name string) Instruction { - return ins.WithSymbol(name) -} - -// Symbol returns the value ins has been marked with using WithSymbol, -// otherwise returns an empty string. A symbol is often an Instruction -// at the start of a function body. -func (ins Instruction) Symbol() string { - sym, _ := ins.Metadata.Get(symbolMeta{}).(string) - return sym -} - -type referenceMeta struct{} - -// WithReference makes ins reference another Symbol or map by name. -func (ins Instruction) WithReference(ref string) Instruction { - ins.Metadata.Set(referenceMeta{}, ref) - return ins -} - -// Reference returns the Symbol or map name referenced by ins, if any. -func (ins Instruction) Reference() string { - ref, _ := ins.Metadata.Get(referenceMeta{}).(string) - return ref -} - -type mapMeta struct{} - -// Map returns the Map referenced by ins, if any. -// An Instruction will contain a Map if e.g. it references an existing, -// pinned map that was opened during ELF loading. -func (ins Instruction) Map() FDer { - fd, _ := ins.Metadata.Get(mapMeta{}).(FDer) - return fd -} - -type sourceMeta struct{} - -// WithSource adds source information about the Instruction. -func (ins Instruction) WithSource(src fmt.Stringer) Instruction { - ins.Metadata.Set(sourceMeta{}, src) - return ins -} - -// Source returns source information about the Instruction. The field is -// present when the compiler emits BTF line info about the Instruction and -// usually contains the line of source code responsible for it. -func (ins Instruction) Source() fmt.Stringer { - str, _ := ins.Metadata.Get(sourceMeta{}).(fmt.Stringer) - return str -} - -// A Comment can be passed to Instruction.WithSource to add a comment -// to an instruction. -type Comment string - -func (s Comment) String() string { - return string(s) -} - -// FDer represents a resource tied to an underlying file descriptor. -// Used as a stand-in for e.g. ebpf.Map since that type cannot be -// imported here and FD() is the only method we rely on. -type FDer interface { - FD() int -} - -// Instructions is an eBPF program. -type Instructions []Instruction - -// Unmarshal unmarshals an Instructions from a binary instruction stream. -// All instructions in insns are replaced by instructions decoded from r. -func (insns *Instructions) Unmarshal(r io.Reader, bo binary.ByteOrder) error { - if len(*insns) > 0 { - *insns = nil - } - - var offset uint64 - for { - var ins Instruction - n, err := ins.Unmarshal(r, bo) - if errors.Is(err, io.EOF) { - break - } - if err != nil { - return fmt.Errorf("offset %d: %w", offset, err) - } - - *insns = append(*insns, ins) - offset += n - } - - return nil -} - -// Name returns the name of the function insns belongs to, if any. -func (insns Instructions) Name() string { - if len(insns) == 0 { - return "" - } - return insns[0].Symbol() -} - -func (insns Instructions) String() string { - return fmt.Sprint(insns) -} - -// Size returns the amount of bytes insns would occupy in binary form. -func (insns Instructions) Size() uint64 { - var sum uint64 - for _, ins := range insns { - sum += ins.Size() - } - return sum -} - -// AssociateMap updates all Instructions that Reference the given symbol -// to point to an existing Map m instead. -// -// Returns ErrUnreferencedSymbol error if no references to symbol are found -// in insns. If symbol is anything else than the symbol name of map (e.g. -// a bpf2bpf subprogram), an error is returned. -func (insns Instructions) AssociateMap(symbol string, m FDer) error { - if symbol == "" { - return errors.New("empty symbol") - } - - var found bool - for i := range insns { - ins := &insns[i] - if ins.Reference() != symbol { - continue - } - - if err := ins.AssociateMap(m); err != nil { - return err - } - - found = true - } - - if !found { - return fmt.Errorf("symbol %s: %w", symbol, ErrUnreferencedSymbol) - } - - return nil -} - -// RewriteMapPtr rewrites all loads of a specific map pointer to a new fd. -// -// Returns ErrUnreferencedSymbol if the symbol isn't used. -// -// Deprecated: use AssociateMap instead. -func (insns Instructions) RewriteMapPtr(symbol string, fd int) error { - if symbol == "" { - return errors.New("empty symbol") - } - - var found bool - for i := range insns { - ins := &insns[i] - if ins.Reference() != symbol { - continue - } - - if !ins.IsLoadFromMap() { - return errors.New("not a load from a map") - } - - ins.encodeMapFD(fd) - - found = true - } - - if !found { - return fmt.Errorf("symbol %s: %w", symbol, ErrUnreferencedSymbol) - } - - return nil -} - -// SymbolOffsets returns the set of symbols and their offset in -// the instructions. -func (insns Instructions) SymbolOffsets() (map[string]int, error) { - offsets := make(map[string]int) - - for i, ins := range insns { - if ins.Symbol() == "" { - continue - } - - if _, ok := offsets[ins.Symbol()]; ok { - return nil, fmt.Errorf("duplicate symbol %s", ins.Symbol()) - } - - offsets[ins.Symbol()] = i - } - - return offsets, nil -} - -// FunctionReferences returns a set of symbol names these Instructions make -// bpf-to-bpf calls to. -func (insns Instructions) FunctionReferences() []string { - calls := make(map[string]struct{}) - for _, ins := range insns { - if ins.Constant != -1 { - // BPF-to-BPF calls have -1 constants. - continue - } - - if ins.Reference() == "" { - continue - } - - if !ins.IsFunctionReference() { - continue - } - - calls[ins.Reference()] = struct{}{} - } - - result := make([]string, 0, len(calls)) - for call := range calls { - result = append(result, call) - } - - sort.Strings(result) - return result -} - -// ReferenceOffsets returns the set of references and their offset in -// the instructions. -func (insns Instructions) ReferenceOffsets() map[string][]int { - offsets := make(map[string][]int) - - for i, ins := range insns { - if ins.Reference() == "" { - continue - } - - offsets[ins.Reference()] = append(offsets[ins.Reference()], i) - } - - return offsets -} - -// Format implements fmt.Formatter. -// -// You can control indentation of symbols by -// specifying a width. Setting a precision controls the indentation of -// instructions. -// The default character is a tab, which can be overridden by specifying -// the ' ' space flag. -func (insns Instructions) Format(f fmt.State, c rune) { - if c != 's' && c != 'v' { - fmt.Fprintf(f, "{UNKNOWN FORMAT '%c'}", c) - return - } - - // Precision is better in this case, because it allows - // specifying 0 padding easily. - padding, ok := f.Precision() - if !ok { - padding = 1 - } - - indent := strings.Repeat("\t", padding) - if f.Flag(' ') { - indent = strings.Repeat(" ", padding) - } - - symPadding, ok := f.Width() - if !ok { - symPadding = padding - 1 - } - if symPadding < 0 { - symPadding = 0 - } - - symIndent := strings.Repeat("\t", symPadding) - if f.Flag(' ') { - symIndent = strings.Repeat(" ", symPadding) - } - - // Guess how many digits we need at most, by assuming that all instructions - // are double wide. - highestOffset := len(insns) * 2 - offsetWidth := int(math.Ceil(math.Log10(float64(highestOffset)))) - - iter := insns.Iterate() - for iter.Next() { - if iter.Ins.Symbol() != "" { - fmt.Fprintf(f, "%s%s:\n", symIndent, iter.Ins.Symbol()) - } - if src := iter.Ins.Source(); src != nil { - line := strings.TrimSpace(src.String()) - if line != "" { - fmt.Fprintf(f, "%s%*s; %s\n", indent, offsetWidth, " ", line) - } - } - fmt.Fprintf(f, "%s%*d: %v\n", indent, offsetWidth, iter.Offset, iter.Ins) - } -} - -// Marshal encodes a BPF program into the kernel format. -// -// insns may be modified if there are unresolved jumps or bpf2bpf calls. -// -// Returns ErrUnsatisfiedProgramReference if there is a Reference Instruction -// without a matching Symbol Instruction within insns. -func (insns Instructions) Marshal(w io.Writer, bo binary.ByteOrder) error { - if err := insns.encodeFunctionReferences(); err != nil { - return err - } - - if err := insns.encodeMapPointers(); err != nil { - return err - } - - for i, ins := range insns { - if _, err := ins.Marshal(w, bo); err != nil { - return fmt.Errorf("instruction %d: %w", i, err) - } - } - return nil -} - -// Tag calculates the kernel tag for a series of instructions. -// -// It mirrors bpf_prog_calc_tag in the kernel and so can be compared -// to ProgramInfo.Tag to figure out whether a loaded program matches -// certain instructions. -func (insns Instructions) Tag(bo binary.ByteOrder) (string, error) { - h := sha1.New() - for i, ins := range insns { - if ins.IsLoadFromMap() { - ins.Constant = 0 - } - _, err := ins.Marshal(h, bo) - if err != nil { - return "", fmt.Errorf("instruction %d: %w", i, err) - } - } - return hex.EncodeToString(h.Sum(nil)[:unix.BPF_TAG_SIZE]), nil -} - -// encodeFunctionReferences populates the Offset (or Constant, depending on -// the instruction type) field of instructions with a Reference field to point -// to the offset of the corresponding instruction with a matching Symbol field. -// -// Only Reference Instructions that are either jumps or BPF function references -// (calls or function pointer loads) are populated. -// -// Returns ErrUnsatisfiedProgramReference if there is a Reference Instruction -// without at least one corresponding Symbol Instruction within insns. -func (insns Instructions) encodeFunctionReferences() error { - // Index the offsets of instructions tagged as a symbol. - symbolOffsets := make(map[string]RawInstructionOffset) - iter := insns.Iterate() - for iter.Next() { - ins := iter.Ins - - if ins.Symbol() == "" { - continue - } - - if _, ok := symbolOffsets[ins.Symbol()]; ok { - return fmt.Errorf("duplicate symbol %s", ins.Symbol()) - } - - symbolOffsets[ins.Symbol()] = iter.Offset - } - - // Find all instructions tagged as references to other symbols. - // Depending on the instruction type, populate their constant or offset - // fields to point to the symbol they refer to within the insn stream. - iter = insns.Iterate() - for iter.Next() { - i := iter.Index - offset := iter.Offset - ins := iter.Ins - - if ins.Reference() == "" { - continue - } - - switch { - case ins.IsFunctionReference() && ins.Constant == -1: - symOffset, ok := symbolOffsets[ins.Reference()] - if !ok { - return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference) - } - - ins.Constant = int64(symOffset - offset - 1) - - case ins.OpCode.Class().IsJump() && ins.Offset == -1: - symOffset, ok := symbolOffsets[ins.Reference()] - if !ok { - return fmt.Errorf("%s at insn %d: symbol %q: %w", ins.OpCode, i, ins.Reference(), ErrUnsatisfiedProgramReference) - } - - ins.Offset = int16(symOffset - offset - 1) - } - } - - return nil -} - -// encodeMapPointers finds all Map Instructions and encodes their FDs -// into their Constant fields. -func (insns Instructions) encodeMapPointers() error { - iter := insns.Iterate() - for iter.Next() { - ins := iter.Ins - - if !ins.IsLoadFromMap() { - continue - } - - m := ins.Map() - if m == nil { - continue - } - - fd := m.FD() - if fd < 0 { - return fmt.Errorf("map %s: %w", m, sys.ErrClosedFd) - } - - ins.encodeMapFD(m.FD()) - } - - return nil -} - -// Iterate allows iterating a BPF program while keeping track of -// various offsets. -// -// Modifying the instruction slice will lead to undefined behaviour. -func (insns Instructions) Iterate() *InstructionIterator { - return &InstructionIterator{insns: insns} -} - -// InstructionIterator iterates over a BPF program. -type InstructionIterator struct { - insns Instructions - // The instruction in question. - Ins *Instruction - // The index of the instruction in the original instruction slice. - Index int - // The offset of the instruction in raw BPF instructions. This accounts - // for double-wide instructions. - Offset RawInstructionOffset -} - -// Next returns true as long as there are any instructions remaining. -func (iter *InstructionIterator) Next() bool { - if len(iter.insns) == 0 { - return false - } - - if iter.Ins != nil { - iter.Index++ - iter.Offset += RawInstructionOffset(iter.Ins.OpCode.rawInstructions()) - } - iter.Ins = &iter.insns[0] - iter.insns = iter.insns[1:] - return true -} - -type bpfRegisters uint8 - -func newBPFRegisters(dst, src Register, bo binary.ByteOrder) (bpfRegisters, error) { - switch bo { - case binary.LittleEndian: - return bpfRegisters((src << 4) | (dst & 0xF)), nil - case binary.BigEndian: - return bpfRegisters((dst << 4) | (src & 0xF)), nil - default: - return 0, fmt.Errorf("unrecognized ByteOrder %T", bo) - } -} - -// IsUnreferencedSymbol returns true if err was caused by -// an unreferenced symbol. -// -// Deprecated: use errors.Is(err, asm.ErrUnreferencedSymbol). -func IsUnreferencedSymbol(err error) bool { - return errors.Is(err, ErrUnreferencedSymbol) -} diff --git a/vendor/github.com/cilium/ebpf/asm/jump.go b/vendor/github.com/cilium/ebpf/asm/jump.go deleted file mode 100644 index e31e42ca..00000000 --- a/vendor/github.com/cilium/ebpf/asm/jump.go +++ /dev/null @@ -1,127 +0,0 @@ -package asm - -//go:generate stringer -output jump_string.go -type=JumpOp - -// JumpOp affect control flow. -// -// msb lsb -// +----+-+---+ -// |OP |s|cls| -// +----+-+---+ -type JumpOp uint8 - -const jumpMask OpCode = aluMask - -const ( - // InvalidJumpOp is returned by getters when invoked - // on non branch OpCodes - InvalidJumpOp JumpOp = 0xff - // Ja jumps by offset unconditionally - Ja JumpOp = 0x00 - // JEq jumps by offset if r == imm - JEq JumpOp = 0x10 - // JGT jumps by offset if r > imm - JGT JumpOp = 0x20 - // JGE jumps by offset if r >= imm - JGE JumpOp = 0x30 - // JSet jumps by offset if r & imm - JSet JumpOp = 0x40 - // JNE jumps by offset if r != imm - JNE JumpOp = 0x50 - // JSGT jumps by offset if signed r > signed imm - JSGT JumpOp = 0x60 - // JSGE jumps by offset if signed r >= signed imm - JSGE JumpOp = 0x70 - // Call builtin or user defined function from imm - Call JumpOp = 0x80 - // Exit ends execution, with value in r0 - Exit JumpOp = 0x90 - // JLT jumps by offset if r < imm - JLT JumpOp = 0xa0 - // JLE jumps by offset if r <= imm - JLE JumpOp = 0xb0 - // JSLT jumps by offset if signed r < signed imm - JSLT JumpOp = 0xc0 - // JSLE jumps by offset if signed r <= signed imm - JSLE JumpOp = 0xd0 -) - -// Return emits an exit instruction. -// -// Requires a return value in R0. -func Return() Instruction { - return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(Exit), - } -} - -// Op returns the OpCode for a given jump source. -func (op JumpOp) Op(source Source) OpCode { - return OpCode(JumpClass).SetJumpOp(op).SetSource(source) -} - -// Imm compares 64 bit dst to 64 bit value (sign extended), and adjusts PC by offset if the condition is fulfilled. -func (op JumpOp) Imm(dst Register, value int32, label string) Instruction { - return Instruction{ - OpCode: op.opCode(JumpClass, ImmSource), - Dst: dst, - Offset: -1, - Constant: int64(value), - }.WithReference(label) -} - -// Imm32 compares 32 bit dst to 32 bit value, and adjusts PC by offset if the condition is fulfilled. -// Requires kernel 5.1. -func (op JumpOp) Imm32(dst Register, value int32, label string) Instruction { - return Instruction{ - OpCode: op.opCode(Jump32Class, ImmSource), - Dst: dst, - Offset: -1, - Constant: int64(value), - }.WithReference(label) -} - -// Reg compares 64 bit dst to 64 bit src, and adjusts PC by offset if the condition is fulfilled. -func (op JumpOp) Reg(dst, src Register, label string) Instruction { - return Instruction{ - OpCode: op.opCode(JumpClass, RegSource), - Dst: dst, - Src: src, - Offset: -1, - }.WithReference(label) -} - -// Reg32 compares 32 bit dst to 32 bit src, and adjusts PC by offset if the condition is fulfilled. -// Requires kernel 5.1. -func (op JumpOp) Reg32(dst, src Register, label string) Instruction { - return Instruction{ - OpCode: op.opCode(Jump32Class, RegSource), - Dst: dst, - Src: src, - Offset: -1, - }.WithReference(label) -} - -func (op JumpOp) opCode(class Class, source Source) OpCode { - if op == Exit || op == Call || op == Ja { - return InvalidOpCode - } - - return OpCode(class).SetJumpOp(op).SetSource(source) -} - -// Label adjusts PC to the address of the label. -func (op JumpOp) Label(label string) Instruction { - if op == Call { - return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(Call), - Src: PseudoCall, - Constant: -1, - }.WithReference(label) - } - - return Instruction{ - OpCode: OpCode(JumpClass).SetJumpOp(op), - Offset: -1, - }.WithReference(label) -} diff --git a/vendor/github.com/cilium/ebpf/asm/jump_string.go b/vendor/github.com/cilium/ebpf/asm/jump_string.go deleted file mode 100644 index 85a4aaff..00000000 --- a/vendor/github.com/cilium/ebpf/asm/jump_string.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by "stringer -output jump_string.go -type=JumpOp"; DO NOT EDIT. - -package asm - -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[InvalidJumpOp-255] - _ = x[Ja-0] - _ = x[JEq-16] - _ = x[JGT-32] - _ = x[JGE-48] - _ = x[JSet-64] - _ = x[JNE-80] - _ = x[JSGT-96] - _ = x[JSGE-112] - _ = x[Call-128] - _ = x[Exit-144] - _ = x[JLT-160] - _ = x[JLE-176] - _ = x[JSLT-192] - _ = x[JSLE-208] -} - -const _JumpOp_name = "JaJEqJGTJGEJSetJNEJSGTJSGECallExitJLTJLEJSLTJSLEInvalidJumpOp" - -var _JumpOp_map = map[JumpOp]string{ - 0: _JumpOp_name[0:2], - 16: _JumpOp_name[2:5], - 32: _JumpOp_name[5:8], - 48: _JumpOp_name[8:11], - 64: _JumpOp_name[11:15], - 80: _JumpOp_name[15:18], - 96: _JumpOp_name[18:22], - 112: _JumpOp_name[22:26], - 128: _JumpOp_name[26:30], - 144: _JumpOp_name[30:34], - 160: _JumpOp_name[34:37], - 176: _JumpOp_name[37:40], - 192: _JumpOp_name[40:44], - 208: _JumpOp_name[44:48], - 255: _JumpOp_name[48:61], -} - -func (i JumpOp) String() string { - if str, ok := _JumpOp_map[i]; ok { - return str - } - return "JumpOp(" + strconv.FormatInt(int64(i), 10) + ")" -} diff --git a/vendor/github.com/cilium/ebpf/asm/load_store.go b/vendor/github.com/cilium/ebpf/asm/load_store.go deleted file mode 100644 index 85ed286b..00000000 --- a/vendor/github.com/cilium/ebpf/asm/load_store.go +++ /dev/null @@ -1,204 +0,0 @@ -package asm - -//go:generate stringer -output load_store_string.go -type=Mode,Size - -// Mode for load and store operations -// -// msb lsb -// +---+--+---+ -// |MDE|sz|cls| -// +---+--+---+ -type Mode uint8 - -const modeMask OpCode = 0xe0 - -const ( - // InvalidMode is returned by getters when invoked - // on non load / store OpCodes - InvalidMode Mode = 0xff - // ImmMode - immediate value - ImmMode Mode = 0x00 - // AbsMode - immediate value + offset - AbsMode Mode = 0x20 - // IndMode - indirect (imm+src) - IndMode Mode = 0x40 - // MemMode - load from memory - MemMode Mode = 0x60 - // XAddMode - add atomically across processors. - XAddMode Mode = 0xc0 -) - -// Size of load and store operations -// -// msb lsb -// +---+--+---+ -// |mde|SZ|cls| -// +---+--+---+ -type Size uint8 - -const sizeMask OpCode = 0x18 - -const ( - // InvalidSize is returned by getters when invoked - // on non load / store OpCodes - InvalidSize Size = 0xff - // DWord - double word; 64 bits - DWord Size = 0x18 - // Word - word; 32 bits - Word Size = 0x00 - // Half - half-word; 16 bits - Half Size = 0x08 - // Byte - byte; 8 bits - Byte Size = 0x10 -) - -// Sizeof returns the size in bytes. -func (s Size) Sizeof() int { - switch s { - case DWord: - return 8 - case Word: - return 4 - case Half: - return 2 - case Byte: - return 1 - default: - return -1 - } -} - -// LoadMemOp returns the OpCode to load a value of given size from memory. -func LoadMemOp(size Size) OpCode { - return OpCode(LdXClass).SetMode(MemMode).SetSize(size) -} - -// LoadMem emits `dst = *(size *)(src + offset)`. -func LoadMem(dst, src Register, offset int16, size Size) Instruction { - return Instruction{ - OpCode: LoadMemOp(size), - Dst: dst, - Src: src, - Offset: offset, - } -} - -// LoadImmOp returns the OpCode to load an immediate of given size. -// -// As of kernel 4.20, only DWord size is accepted. -func LoadImmOp(size Size) OpCode { - return OpCode(LdClass).SetMode(ImmMode).SetSize(size) -} - -// LoadImm emits `dst = (size)value`. -// -// As of kernel 4.20, only DWord size is accepted. -func LoadImm(dst Register, value int64, size Size) Instruction { - return Instruction{ - OpCode: LoadImmOp(size), - Dst: dst, - Constant: value, - } -} - -// LoadMapPtr stores a pointer to a map in dst. -func LoadMapPtr(dst Register, fd int) Instruction { - if fd < 0 { - return Instruction{OpCode: InvalidOpCode} - } - - return Instruction{ - OpCode: LoadImmOp(DWord), - Dst: dst, - Src: PseudoMapFD, - Constant: int64(uint32(fd)), - } -} - -// LoadMapValue stores a pointer to the value at a certain offset of a map. -func LoadMapValue(dst Register, fd int, offset uint32) Instruction { - if fd < 0 { - return Instruction{OpCode: InvalidOpCode} - } - - fdAndOffset := (uint64(offset) << 32) | uint64(uint32(fd)) - return Instruction{ - OpCode: LoadImmOp(DWord), - Dst: dst, - Src: PseudoMapValue, - Constant: int64(fdAndOffset), - } -} - -// LoadIndOp returns the OpCode for loading a value of given size from an sk_buff. -func LoadIndOp(size Size) OpCode { - return OpCode(LdClass).SetMode(IndMode).SetSize(size) -} - -// LoadInd emits `dst = ntoh(*(size *)(((sk_buff *)R6)->data + src + offset))`. -func LoadInd(dst, src Register, offset int32, size Size) Instruction { - return Instruction{ - OpCode: LoadIndOp(size), - Dst: dst, - Src: src, - Constant: int64(offset), - } -} - -// LoadAbsOp returns the OpCode for loading a value of given size from an sk_buff. -func LoadAbsOp(size Size) OpCode { - return OpCode(LdClass).SetMode(AbsMode).SetSize(size) -} - -// LoadAbs emits `r0 = ntoh(*(size *)(((sk_buff *)R6)->data + offset))`. -func LoadAbs(offset int32, size Size) Instruction { - return Instruction{ - OpCode: LoadAbsOp(size), - Dst: R0, - Constant: int64(offset), - } -} - -// StoreMemOp returns the OpCode for storing a register of given size in memory. -func StoreMemOp(size Size) OpCode { - return OpCode(StXClass).SetMode(MemMode).SetSize(size) -} - -// StoreMem emits `*(size *)(dst + offset) = src` -func StoreMem(dst Register, offset int16, src Register, size Size) Instruction { - return Instruction{ - OpCode: StoreMemOp(size), - Dst: dst, - Src: src, - Offset: offset, - } -} - -// StoreImmOp returns the OpCode for storing an immediate of given size in memory. -func StoreImmOp(size Size) OpCode { - return OpCode(StClass).SetMode(MemMode).SetSize(size) -} - -// StoreImm emits `*(size *)(dst + offset) = value`. -func StoreImm(dst Register, offset int16, value int64, size Size) Instruction { - return Instruction{ - OpCode: StoreImmOp(size), - Dst: dst, - Offset: offset, - Constant: value, - } -} - -// StoreXAddOp returns the OpCode to atomically add a register to a value in memory. -func StoreXAddOp(size Size) OpCode { - return OpCode(StXClass).SetMode(XAddMode).SetSize(size) -} - -// StoreXAdd atomically adds src to *dst. -func StoreXAdd(dst, src Register, size Size) Instruction { - return Instruction{ - OpCode: StoreXAddOp(size), - Dst: dst, - Src: src, - } -} diff --git a/vendor/github.com/cilium/ebpf/asm/load_store_string.go b/vendor/github.com/cilium/ebpf/asm/load_store_string.go deleted file mode 100644 index 76d29a07..00000000 --- a/vendor/github.com/cilium/ebpf/asm/load_store_string.go +++ /dev/null @@ -1,80 +0,0 @@ -// Code generated by "stringer -output load_store_string.go -type=Mode,Size"; DO NOT EDIT. - -package asm - -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[InvalidMode-255] - _ = x[ImmMode-0] - _ = x[AbsMode-32] - _ = x[IndMode-64] - _ = x[MemMode-96] - _ = x[XAddMode-192] -} - -const ( - _Mode_name_0 = "ImmMode" - _Mode_name_1 = "AbsMode" - _Mode_name_2 = "IndMode" - _Mode_name_3 = "MemMode" - _Mode_name_4 = "XAddMode" - _Mode_name_5 = "InvalidMode" -) - -func (i Mode) String() string { - switch { - case i == 0: - return _Mode_name_0 - case i == 32: - return _Mode_name_1 - case i == 64: - return _Mode_name_2 - case i == 96: - return _Mode_name_3 - case i == 192: - return _Mode_name_4 - case i == 255: - return _Mode_name_5 - default: - return "Mode(" + 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[InvalidSize-255] - _ = x[DWord-24] - _ = x[Word-0] - _ = x[Half-8] - _ = x[Byte-16] -} - -const ( - _Size_name_0 = "Word" - _Size_name_1 = "Half" - _Size_name_2 = "Byte" - _Size_name_3 = "DWord" - _Size_name_4 = "InvalidSize" -) - -func (i Size) String() string { - switch { - case i == 0: - return _Size_name_0 - case i == 8: - return _Size_name_1 - case i == 16: - return _Size_name_2 - case i == 24: - return _Size_name_3 - case i == 255: - return _Size_name_4 - default: - return "Size(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/vendor/github.com/cilium/ebpf/asm/metadata.go b/vendor/github.com/cilium/ebpf/asm/metadata.go deleted file mode 100644 index dd368a93..00000000 --- a/vendor/github.com/cilium/ebpf/asm/metadata.go +++ /dev/null @@ -1,80 +0,0 @@ -package asm - -// Metadata contains metadata about an instruction. -type Metadata struct { - head *metaElement -} - -type metaElement struct { - next *metaElement - key, value interface{} -} - -// Find the element containing key. -// -// Returns nil if there is no such element. -func (m *Metadata) find(key interface{}) *metaElement { - for e := m.head; e != nil; e = e.next { - if e.key == key { - return e - } - } - return nil -} - -// Remove an element from the linked list. -// -// Copies as many elements of the list as necessary to remove r, but doesn't -// perform a full copy. -func (m *Metadata) remove(r *metaElement) { - current := &m.head - for e := m.head; e != nil; e = e.next { - if e == r { - // We've found the element we want to remove. - *current = e.next - - // No need to copy the tail. - return - } - - // There is another element in front of the one we want to remove. - // We have to copy it to be able to change metaElement.next. - cpy := &metaElement{key: e.key, value: e.value} - *current = cpy - current = &cpy.next - } -} - -// Set a key to a value. -// -// If value is nil, the key is removed. Avoids modifying old metadata by -// copying if necessary. -func (m *Metadata) Set(key, value interface{}) { - if e := m.find(key); e != nil { - if e.value == value { - // Key is present and the value is the same. Nothing to do. - return - } - - // Key is present with a different value. Create a copy of the list - // which doesn't have the element in it. - m.remove(e) - } - - // m.head is now a linked list that doesn't contain key. - if value == nil { - return - } - - m.head = &metaElement{key: key, value: value, next: m.head} -} - -// Get the value of a key. -// -// Returns nil if no value with the given key is present. -func (m *Metadata) Get(key interface{}) interface{} { - if e := m.find(key); e != nil { - return e.value - } - return nil -} diff --git a/vendor/github.com/cilium/ebpf/asm/opcode.go b/vendor/github.com/cilium/ebpf/asm/opcode.go deleted file mode 100644 index b11917e1..00000000 --- a/vendor/github.com/cilium/ebpf/asm/opcode.go +++ /dev/null @@ -1,271 +0,0 @@ -package asm - -import ( - "fmt" - "strings" -) - -//go:generate stringer -output opcode_string.go -type=Class - -// Class of operations -// -// msb lsb -// +---+--+---+ -// | ?? |CLS| -// +---+--+---+ -type Class uint8 - -const classMask OpCode = 0x07 - -const ( - // LdClass loads immediate values into registers. - // Also used for non-standard load operations from cBPF. - LdClass Class = 0x00 - // LdXClass loads memory into registers. - LdXClass Class = 0x01 - // StClass stores immediate values to memory. - StClass Class = 0x02 - // StXClass stores registers to memory. - StXClass Class = 0x03 - // ALUClass describes arithmetic operators. - ALUClass Class = 0x04 - // JumpClass describes jump operators. - JumpClass Class = 0x05 - // Jump32Class describes jump operators with 32-bit comparisons. - // Requires kernel 5.1. - Jump32Class Class = 0x06 - // ALU64Class describes arithmetic operators in 64-bit mode. - ALU64Class Class = 0x07 -) - -// IsLoad checks if this is either LdClass or LdXClass. -func (cls Class) IsLoad() bool { - return cls == LdClass || cls == LdXClass -} - -// IsStore checks if this is either StClass or StXClass. -func (cls Class) IsStore() bool { - return cls == StClass || cls == StXClass -} - -func (cls Class) isLoadOrStore() bool { - return cls.IsLoad() || cls.IsStore() -} - -// IsALU checks if this is either ALUClass or ALU64Class. -func (cls Class) IsALU() bool { - return cls == ALUClass || cls == ALU64Class -} - -// IsJump checks if this is either JumpClass or Jump32Class. -func (cls Class) IsJump() bool { - return cls == JumpClass || cls == Jump32Class -} - -func (cls Class) isJumpOrALU() bool { - return cls.IsJump() || cls.IsALU() -} - -// OpCode is a packed eBPF opcode. -// -// Its encoding is defined by a Class value: -// -// msb lsb -// +----+-+---+ -// | ???? |CLS| -// +----+-+---+ -type OpCode uint8 - -// InvalidOpCode is returned by setters on OpCode -const InvalidOpCode OpCode = 0xff - -// rawInstructions returns the number of BPF instructions required -// to encode this opcode. -func (op OpCode) rawInstructions() int { - if op.IsDWordLoad() { - return 2 - } - return 1 -} - -func (op OpCode) IsDWordLoad() bool { - return op == LoadImmOp(DWord) -} - -// Class returns the class of operation. -func (op OpCode) Class() Class { - return Class(op & classMask) -} - -// Mode returns the mode for load and store operations. -func (op OpCode) Mode() Mode { - if !op.Class().isLoadOrStore() { - return InvalidMode - } - return Mode(op & modeMask) -} - -// Size returns the size for load and store operations. -func (op OpCode) Size() Size { - if !op.Class().isLoadOrStore() { - return InvalidSize - } - return Size(op & sizeMask) -} - -// Source returns the source for branch and ALU operations. -func (op OpCode) Source() Source { - if !op.Class().isJumpOrALU() || op.ALUOp() == Swap { - return InvalidSource - } - return Source(op & sourceMask) -} - -// ALUOp returns the ALUOp. -func (op OpCode) ALUOp() ALUOp { - if !op.Class().IsALU() { - return InvalidALUOp - } - return ALUOp(op & aluMask) -} - -// Endianness returns the Endianness for a byte swap instruction. -func (op OpCode) Endianness() Endianness { - if op.ALUOp() != Swap { - return InvalidEndian - } - return Endianness(op & endianMask) -} - -// JumpOp returns the JumpOp. -// Returns InvalidJumpOp if it doesn't encode a jump. -func (op OpCode) JumpOp() JumpOp { - if !op.Class().IsJump() { - return InvalidJumpOp - } - - jumpOp := JumpOp(op & jumpMask) - - // Some JumpOps are only supported by JumpClass, not Jump32Class. - if op.Class() == Jump32Class && (jumpOp == Exit || jumpOp == Call || jumpOp == Ja) { - return InvalidJumpOp - } - - return jumpOp -} - -// SetMode sets the mode on load and store operations. -// -// Returns InvalidOpCode if op is of the wrong class. -func (op OpCode) SetMode(mode Mode) OpCode { - if !op.Class().isLoadOrStore() || !valid(OpCode(mode), modeMask) { - return InvalidOpCode - } - return (op & ^modeMask) | OpCode(mode) -} - -// SetSize sets the size on load and store operations. -// -// Returns InvalidOpCode if op is of the wrong class. -func (op OpCode) SetSize(size Size) OpCode { - if !op.Class().isLoadOrStore() || !valid(OpCode(size), sizeMask) { - return InvalidOpCode - } - return (op & ^sizeMask) | OpCode(size) -} - -// SetSource sets the source on jump and ALU operations. -// -// Returns InvalidOpCode if op is of the wrong class. -func (op OpCode) SetSource(source Source) OpCode { - if !op.Class().isJumpOrALU() || !valid(OpCode(source), sourceMask) { - return InvalidOpCode - } - return (op & ^sourceMask) | OpCode(source) -} - -// SetALUOp sets the ALUOp on ALU operations. -// -// Returns InvalidOpCode if op is of the wrong class. -func (op OpCode) SetALUOp(alu ALUOp) OpCode { - if !op.Class().IsALU() || !valid(OpCode(alu), aluMask) { - return InvalidOpCode - } - return (op & ^aluMask) | OpCode(alu) -} - -// SetJumpOp sets the JumpOp on jump operations. -// -// Returns InvalidOpCode if op is of the wrong class. -func (op OpCode) SetJumpOp(jump JumpOp) OpCode { - if !op.Class().IsJump() || !valid(OpCode(jump), jumpMask) { - return InvalidOpCode - } - - newOp := (op & ^jumpMask) | OpCode(jump) - - // Check newOp is legal. - if newOp.JumpOp() == InvalidJumpOp { - return InvalidOpCode - } - - return newOp -} - -func (op OpCode) String() string { - var f strings.Builder - - switch class := op.Class(); { - case class.isLoadOrStore(): - f.WriteString(strings.TrimSuffix(class.String(), "Class")) - - mode := op.Mode() - f.WriteString(strings.TrimSuffix(mode.String(), "Mode")) - - switch op.Size() { - case DWord: - f.WriteString("DW") - case Word: - f.WriteString("W") - case Half: - f.WriteString("H") - case Byte: - f.WriteString("B") - } - - case class.IsALU(): - f.WriteString(op.ALUOp().String()) - - if op.ALUOp() == Swap { - // Width for Endian is controlled by Constant - f.WriteString(op.Endianness().String()) - } else { - if class == ALUClass { - f.WriteString("32") - } - - f.WriteString(strings.TrimSuffix(op.Source().String(), "Source")) - } - - case class.IsJump(): - f.WriteString(op.JumpOp().String()) - - if class == Jump32Class { - f.WriteString("32") - } - - if jop := op.JumpOp(); jop != Exit && jop != Call { - f.WriteString(strings.TrimSuffix(op.Source().String(), "Source")) - } - - default: - fmt.Fprintf(&f, "OpCode(%#x)", uint8(op)) - } - - return f.String() -} - -// valid returns true if all bits in value are covered by mask. -func valid(value, mask OpCode) bool { - return value & ^mask == 0 -} diff --git a/vendor/github.com/cilium/ebpf/asm/opcode_string.go b/vendor/github.com/cilium/ebpf/asm/opcode_string.go deleted file mode 100644 index 58bc3e7e..00000000 --- a/vendor/github.com/cilium/ebpf/asm/opcode_string.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by "stringer -output opcode_string.go -type=Class"; DO NOT EDIT. - -package asm - -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[LdClass-0] - _ = x[LdXClass-1] - _ = x[StClass-2] - _ = x[StXClass-3] - _ = x[ALUClass-4] - _ = x[JumpClass-5] - _ = x[Jump32Class-6] - _ = x[ALU64Class-7] -} - -const _Class_name = "LdClassLdXClassStClassStXClassALUClassJumpClassJump32ClassALU64Class" - -var _Class_index = [...]uint8{0, 7, 15, 22, 30, 38, 47, 58, 68} - -func (i Class) String() string { - if i >= Class(len(_Class_index)-1) { - return "Class(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _Class_name[_Class_index[i]:_Class_index[i+1]] -} diff --git a/vendor/github.com/cilium/ebpf/asm/register.go b/vendor/github.com/cilium/ebpf/asm/register.go deleted file mode 100644 index dd5d44f1..00000000 --- a/vendor/github.com/cilium/ebpf/asm/register.go +++ /dev/null @@ -1,50 +0,0 @@ -package asm - -import ( - "fmt" -) - -// Register is the source or destination of most operations. -type Register uint8 - -// R0 contains return values. -const R0 Register = 0 - -// Registers for function arguments. -const ( - R1 Register = R0 + 1 + iota - R2 - R3 - R4 - R5 -) - -// Callee saved registers preserved by function calls. -const ( - R6 Register = R5 + 1 + iota - R7 - R8 - R9 -) - -// Read-only frame pointer to access stack. -const ( - R10 Register = R9 + 1 - RFP = R10 -) - -// Pseudo registers used by 64bit loads and jumps -const ( - PseudoMapFD = R1 // BPF_PSEUDO_MAP_FD - PseudoMapValue = R2 // BPF_PSEUDO_MAP_VALUE - PseudoCall = R1 // BPF_PSEUDO_CALL - PseudoFunc = R4 // BPF_PSEUDO_FUNC -) - -func (r Register) String() string { - v := uint8(r) - if v == 10 { - return "rfp" - } - return fmt.Sprintf("r%d", v) -} diff --git a/vendor/github.com/cilium/ebpf/attachtype_string.go b/vendor/github.com/cilium/ebpf/attachtype_string.go deleted file mode 100644 index de355ed9..00000000 --- a/vendor/github.com/cilium/ebpf/attachtype_string.go +++ /dev/null @@ -1,65 +0,0 @@ -// Code generated by "stringer -type AttachType -trimprefix Attach"; DO NOT EDIT. - -package ebpf - -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[AttachNone-0] - _ = x[AttachCGroupInetIngress-0] - _ = x[AttachCGroupInetEgress-1] - _ = x[AttachCGroupInetSockCreate-2] - _ = x[AttachCGroupSockOps-3] - _ = x[AttachSkSKBStreamParser-4] - _ = x[AttachSkSKBStreamVerdict-5] - _ = x[AttachCGroupDevice-6] - _ = x[AttachSkMsgVerdict-7] - _ = x[AttachCGroupInet4Bind-8] - _ = x[AttachCGroupInet6Bind-9] - _ = x[AttachCGroupInet4Connect-10] - _ = x[AttachCGroupInet6Connect-11] - _ = x[AttachCGroupInet4PostBind-12] - _ = x[AttachCGroupInet6PostBind-13] - _ = x[AttachCGroupUDP4Sendmsg-14] - _ = x[AttachCGroupUDP6Sendmsg-15] - _ = x[AttachLircMode2-16] - _ = x[AttachFlowDissector-17] - _ = x[AttachCGroupSysctl-18] - _ = x[AttachCGroupUDP4Recvmsg-19] - _ = x[AttachCGroupUDP6Recvmsg-20] - _ = x[AttachCGroupGetsockopt-21] - _ = x[AttachCGroupSetsockopt-22] - _ = x[AttachTraceRawTp-23] - _ = x[AttachTraceFEntry-24] - _ = x[AttachTraceFExit-25] - _ = x[AttachModifyReturn-26] - _ = x[AttachLSMMac-27] - _ = x[AttachTraceIter-28] - _ = x[AttachCgroupInet4GetPeername-29] - _ = x[AttachCgroupInet6GetPeername-30] - _ = x[AttachCgroupInet4GetSockname-31] - _ = x[AttachCgroupInet6GetSockname-32] - _ = x[AttachXDPDevMap-33] - _ = x[AttachCgroupInetSockRelease-34] - _ = x[AttachXDPCPUMap-35] - _ = x[AttachSkLookup-36] - _ = x[AttachXDP-37] - _ = x[AttachSkSKBVerdict-38] - _ = x[AttachSkReuseportSelect-39] - _ = x[AttachSkReuseportSelectOrMigrate-40] - _ = x[AttachPerfEvent-41] -} - -const _AttachType_name = "NoneCGroupInetEgressCGroupInetSockCreateCGroupSockOpsSkSKBStreamParserSkSKBStreamVerdictCGroupDeviceSkMsgVerdictCGroupInet4BindCGroupInet6BindCGroupInet4ConnectCGroupInet6ConnectCGroupInet4PostBindCGroupInet6PostBindCGroupUDP4SendmsgCGroupUDP6SendmsgLircMode2FlowDissectorCGroupSysctlCGroupUDP4RecvmsgCGroupUDP6RecvmsgCGroupGetsockoptCGroupSetsockoptTraceRawTpTraceFEntryTraceFExitModifyReturnLSMMacTraceIterCgroupInet4GetPeernameCgroupInet6GetPeernameCgroupInet4GetSocknameCgroupInet6GetSocknameXDPDevMapCgroupInetSockReleaseXDPCPUMapSkLookupXDPSkSKBVerdictSkReuseportSelectSkReuseportSelectOrMigratePerfEvent" - -var _AttachType_index = [...]uint16{0, 4, 20, 40, 53, 70, 88, 100, 112, 127, 142, 160, 178, 197, 216, 233, 250, 259, 272, 284, 301, 318, 334, 350, 360, 371, 381, 393, 399, 408, 430, 452, 474, 496, 505, 526, 535, 543, 546, 558, 575, 601, 610} - -func (i AttachType) String() string { - if i >= AttachType(len(_AttachType_index)-1) { - return "AttachType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _AttachType_name[_AttachType_index[i]:_AttachType_index[i+1]] -} diff --git a/vendor/github.com/cilium/ebpf/btf/btf.go b/vendor/github.com/cilium/ebpf/btf/btf.go deleted file mode 100644 index a5969332..00000000 --- a/vendor/github.com/cilium/ebpf/btf/btf.go +++ /dev/null @@ -1,897 +0,0 @@ -package btf - -import ( - "bufio" - "bytes" - "debug/elf" - "encoding/binary" - "errors" - "fmt" - "io" - "math" - "os" - "reflect" - - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -const btfMagic = 0xeB9F - -// Errors returned by BTF functions. -var ( - ErrNotSupported = internal.ErrNotSupported - ErrNotFound = errors.New("not found") - ErrNoExtendedInfo = errors.New("no extended info") -) - -// ID represents the unique ID of a BTF object. -type ID = sys.BTFID - -// Spec represents decoded BTF. -type Spec struct { - // Data from .BTF. - rawTypes []rawType - strings *stringTable - - // All types contained by the spec. For the base type, the position of - // a type in the slice is its ID. - types types - - // Type IDs indexed by type. - typeIDs map[Type]TypeID - - // Types indexed by essential name. - // Includes all struct flavors and types with the same name. - namedTypes map[essentialName][]Type - - byteOrder binary.ByteOrder -} - -type btfHeader struct { - Magic uint16 - Version uint8 - Flags uint8 - HdrLen uint32 - - TypeOff uint32 - TypeLen uint32 - StringOff uint32 - StringLen uint32 -} - -// typeStart returns the offset from the beginning of the .BTF section -// to the start of its type entries. -func (h *btfHeader) typeStart() int64 { - return int64(h.HdrLen + h.TypeOff) -} - -// stringStart returns the offset from the beginning of the .BTF section -// to the start of its string table. -func (h *btfHeader) stringStart() int64 { - return int64(h.HdrLen + h.StringOff) -} - -// LoadSpec opens file and calls LoadSpecFromReader on it. -func LoadSpec(file string) (*Spec, error) { - fh, err := os.Open(file) - if err != nil { - return nil, err - } - defer fh.Close() - - return LoadSpecFromReader(fh) -} - -// LoadSpecFromReader reads from an ELF or a raw BTF blob. -// -// Returns ErrNotFound if reading from an ELF which contains no BTF. ExtInfos -// may be nil. -func LoadSpecFromReader(rd io.ReaderAt) (*Spec, error) { - file, err := internal.NewSafeELFFile(rd) - if err != nil { - if bo := guessRawBTFByteOrder(rd); bo != nil { - // Try to parse a naked BTF blob. This will return an error if - // we encounter a Datasec, since we can't fix it up. - spec, err := loadRawSpec(io.NewSectionReader(rd, 0, math.MaxInt64), bo, nil, nil) - return spec, err - } - - return nil, err - } - - return loadSpecFromELF(file) -} - -// LoadSpecAndExtInfosFromReader reads from an ELF. -// -// ExtInfos may be nil if the ELF doesn't contain section metadta. -// Returns ErrNotFound if the ELF contains no BTF. -func LoadSpecAndExtInfosFromReader(rd io.ReaderAt) (*Spec, *ExtInfos, error) { - file, err := internal.NewSafeELFFile(rd) - if err != nil { - return nil, nil, err - } - - spec, err := loadSpecFromELF(file) - if err != nil { - return nil, nil, err - } - - extInfos, err := loadExtInfosFromELF(file, spec.types, spec.strings) - if err != nil && !errors.Is(err, ErrNotFound) { - return nil, nil, err - } - - return spec, extInfos, nil -} - -// variableOffsets extracts all symbols offsets from an ELF and indexes them by -// section and variable name. -// -// References to variables in BTF data sections carry unsigned 32-bit offsets. -// Some ELF symbols (e.g. in vmlinux) may point to virtual memory that is well -// beyond this range. Since these symbols cannot be described by BTF info, -// ignore them here. -func variableOffsets(file *internal.SafeELFFile) (map[variable]uint32, error) { - symbols, err := file.Symbols() - if err != nil { - return nil, fmt.Errorf("can't read symbols: %v", err) - } - - variableOffsets := make(map[variable]uint32) - for _, symbol := range symbols { - if idx := symbol.Section; idx >= elf.SHN_LORESERVE && idx <= elf.SHN_HIRESERVE { - // Ignore things like SHN_ABS - continue - } - - if symbol.Value > math.MaxUint32 { - // VarSecinfo offset is u32, cannot reference symbols in higher regions. - continue - } - - if int(symbol.Section) >= len(file.Sections) { - return nil, fmt.Errorf("symbol %s: invalid section %d", symbol.Name, symbol.Section) - } - - secName := file.Sections[symbol.Section].Name - variableOffsets[variable{secName, symbol.Name}] = uint32(symbol.Value) - } - - return variableOffsets, nil -} - -func loadSpecFromELF(file *internal.SafeELFFile) (*Spec, error) { - var ( - btfSection *elf.Section - sectionSizes = make(map[string]uint32) - ) - - for _, sec := range file.Sections { - switch sec.Name { - case ".BTF": - btfSection = sec - default: - if sec.Type != elf.SHT_PROGBITS && sec.Type != elf.SHT_NOBITS { - break - } - - if sec.Size > math.MaxUint32 { - return nil, fmt.Errorf("section %s exceeds maximum size", sec.Name) - } - - sectionSizes[sec.Name] = uint32(sec.Size) - } - } - - if btfSection == nil { - return nil, fmt.Errorf("btf: %w", ErrNotFound) - } - - vars, err := variableOffsets(file) - if err != nil { - return nil, err - } - - if btfSection.ReaderAt == nil { - return nil, fmt.Errorf("compressed BTF is not supported") - } - - rawTypes, rawStrings, err := parseBTF(btfSection.ReaderAt, file.ByteOrder, nil) - if err != nil { - return nil, err - } - - err = fixupDatasec(rawTypes, rawStrings, sectionSizes, vars) - if err != nil { - return nil, err - } - - return inflateSpec(rawTypes, rawStrings, file.ByteOrder, nil) -} - -func loadRawSpec(btf io.ReaderAt, bo binary.ByteOrder, - baseTypes types, baseStrings *stringTable) (*Spec, error) { - - rawTypes, rawStrings, err := parseBTF(btf, bo, baseStrings) - if err != nil { - return nil, err - } - - return inflateSpec(rawTypes, rawStrings, bo, baseTypes) -} - -func inflateSpec(rawTypes []rawType, rawStrings *stringTable, bo binary.ByteOrder, - baseTypes types) (*Spec, error) { - - types, err := inflateRawTypes(rawTypes, baseTypes, rawStrings) - if err != nil { - return nil, err - } - - typeIDs, typesByName := indexTypes(types, TypeID(len(baseTypes))) - - return &Spec{ - rawTypes: rawTypes, - namedTypes: typesByName, - typeIDs: typeIDs, - types: types, - strings: rawStrings, - byteOrder: bo, - }, nil -} - -func indexTypes(types []Type, typeIDOffset TypeID) (map[Type]TypeID, map[essentialName][]Type) { - namedTypes := 0 - for _, typ := range types { - if typ.TypeName() != "" { - // Do a pre-pass to figure out how big types by name has to be. - // Most types have unique names, so it's OK to ignore essentialName - // here. - namedTypes++ - } - } - - typeIDs := make(map[Type]TypeID, len(types)) - typesByName := make(map[essentialName][]Type, namedTypes) - - for i, typ := range types { - if name := newEssentialName(typ.TypeName()); name != "" { - typesByName[name] = append(typesByName[name], typ) - } - typeIDs[typ] = TypeID(i) + typeIDOffset - } - - return typeIDs, typesByName -} - -// LoadKernelSpec returns the current kernel's BTF information. -// -// Defaults to /sys/kernel/btf/vmlinux and falls back to scanning the file system -// for vmlinux ELFs. Returns an error wrapping ErrNotSupported if BTF is not enabled. -func LoadKernelSpec() (*Spec, error) { - fh, err := os.Open("/sys/kernel/btf/vmlinux") - if err == nil { - defer fh.Close() - - return loadRawSpec(fh, internal.NativeEndian, nil, nil) - } - - file, err := findVMLinux() - if err != nil { - return nil, err - } - defer file.Close() - - return loadSpecFromELF(file) -} - -// findVMLinux scans multiple well-known paths for vmlinux kernel images. -func findVMLinux() (*internal.SafeELFFile, error) { - release, err := internal.KernelRelease() - if err != nil { - return nil, err - } - - // use same list of locations as libbpf - // https://github.com/libbpf/libbpf/blob/9a3a42608dbe3731256a5682a125ac1e23bced8f/src/btf.c#L3114-L3122 - locations := []string{ - "/boot/vmlinux-%s", - "/lib/modules/%s/vmlinux-%[1]s", - "/lib/modules/%s/build/vmlinux", - "/usr/lib/modules/%s/kernel/vmlinux", - "/usr/lib/debug/boot/vmlinux-%s", - "/usr/lib/debug/boot/vmlinux-%s.debug", - "/usr/lib/debug/lib/modules/%s/vmlinux", - } - - for _, loc := range locations { - file, err := internal.OpenSafeELFFile(fmt.Sprintf(loc, release)) - if errors.Is(err, os.ErrNotExist) { - continue - } - return file, err - } - - return nil, fmt.Errorf("no BTF found for kernel version %s: %w", release, internal.ErrNotSupported) -} - -// parseBTFHeader parses the header of the .BTF section. -func parseBTFHeader(r io.Reader, bo binary.ByteOrder) (*btfHeader, error) { - var header btfHeader - if err := binary.Read(r, bo, &header); err != nil { - return nil, fmt.Errorf("can't read header: %v", err) - } - - if header.Magic != btfMagic { - return nil, fmt.Errorf("incorrect magic value %v", header.Magic) - } - - if header.Version != 1 { - return nil, fmt.Errorf("unexpected version %v", header.Version) - } - - if header.Flags != 0 { - return nil, fmt.Errorf("unsupported flags %v", header.Flags) - } - - remainder := int64(header.HdrLen) - int64(binary.Size(&header)) - if remainder < 0 { - return nil, errors.New("header length shorter than btfHeader size") - } - - if _, err := io.CopyN(internal.DiscardZeroes{}, r, remainder); err != nil { - return nil, fmt.Errorf("header padding: %v", err) - } - - return &header, nil -} - -func guessRawBTFByteOrder(r io.ReaderAt) binary.ByteOrder { - buf := new(bufio.Reader) - for _, bo := range []binary.ByteOrder{ - binary.LittleEndian, - binary.BigEndian, - } { - buf.Reset(io.NewSectionReader(r, 0, math.MaxInt64)) - if _, err := parseBTFHeader(buf, bo); err == nil { - return bo - } - } - - return nil -} - -// parseBTF reads a .BTF section into memory and parses it into a list of -// raw types and a string table. -func parseBTF(btf io.ReaderAt, bo binary.ByteOrder, baseStrings *stringTable) ([]rawType, *stringTable, error) { - buf := internal.NewBufferedSectionReader(btf, 0, math.MaxInt64) - header, err := parseBTFHeader(buf, bo) - if err != nil { - return nil, nil, fmt.Errorf("parsing .BTF header: %v", err) - } - - rawStrings, err := readStringTable(io.NewSectionReader(btf, header.stringStart(), int64(header.StringLen)), - baseStrings) - if err != nil { - return nil, nil, fmt.Errorf("can't read type names: %w", err) - } - - buf.Reset(io.NewSectionReader(btf, header.typeStart(), int64(header.TypeLen))) - rawTypes, err := readTypes(buf, bo, header.TypeLen) - if err != nil { - return nil, nil, fmt.Errorf("can't read types: %w", err) - } - - return rawTypes, rawStrings, nil -} - -type variable struct { - section string - name string -} - -func fixupDatasec(rawTypes []rawType, rawStrings *stringTable, sectionSizes map[string]uint32, variableOffsets map[variable]uint32) error { - for i, rawType := range rawTypes { - if rawType.Kind() != kindDatasec { - continue - } - - name, err := rawStrings.Lookup(rawType.NameOff) - if err != nil { - return err - } - - if name == ".kconfig" || name == ".ksyms" { - return fmt.Errorf("reference to %s: %w", name, ErrNotSupported) - } - - if rawTypes[i].SizeType != 0 { - continue - } - - size, ok := sectionSizes[name] - if !ok { - return fmt.Errorf("data section %s: missing size", name) - } - - rawTypes[i].SizeType = size - - secinfos := rawType.data.([]btfVarSecinfo) - for j, secInfo := range secinfos { - id := int(secInfo.Type - 1) - if id >= len(rawTypes) { - return fmt.Errorf("data section %s: invalid type id %d for variable %d", name, id, j) - } - - varName, err := rawStrings.Lookup(rawTypes[id].NameOff) - if err != nil { - return fmt.Errorf("data section %s: can't get name for type %d: %w", name, id, err) - } - - offset, ok := variableOffsets[variable{name, varName}] - if !ok { - return fmt.Errorf("data section %s: missing offset for variable %s", name, varName) - } - - secinfos[j].Offset = offset - } - } - - return nil -} - -// Copy creates a copy of Spec. -func (s *Spec) Copy() *Spec { - types := copyTypes(s.types, nil) - - typeIDOffset := TypeID(0) - if len(s.types) != 0 { - typeIDOffset = s.typeIDs[s.types[0]] - } - typeIDs, typesByName := indexTypes(types, typeIDOffset) - - // NB: Other parts of spec are not copied since they are immutable. - return &Spec{ - s.rawTypes, - s.strings, - types, - typeIDs, - typesByName, - s.byteOrder, - } -} - -type marshalOpts struct { - ByteOrder binary.ByteOrder - StripFuncLinkage bool -} - -func (s *Spec) marshal(opts marshalOpts) ([]byte, error) { - var ( - buf bytes.Buffer - header = new(btfHeader) - headerLen = binary.Size(header) - ) - - // Reserve space for the header. We have to write it last since - // we don't know the size of the type section yet. - _, _ = buf.Write(make([]byte, headerLen)) - - // Write type section, just after the header. - for _, raw := range s.rawTypes { - switch { - case opts.StripFuncLinkage && raw.Kind() == kindFunc: - raw.SetLinkage(StaticFunc) - } - - if err := raw.Marshal(&buf, opts.ByteOrder); err != nil { - return nil, fmt.Errorf("can't marshal BTF: %w", err) - } - } - - typeLen := uint32(buf.Len() - headerLen) - - // Write string section after type section. - stringsLen := s.strings.Length() - buf.Grow(stringsLen) - if err := s.strings.Marshal(&buf); err != nil { - return nil, err - } - - // Fill out the header, and write it out. - header = &btfHeader{ - Magic: btfMagic, - Version: 1, - Flags: 0, - HdrLen: uint32(headerLen), - TypeOff: 0, - TypeLen: typeLen, - StringOff: typeLen, - StringLen: uint32(stringsLen), - } - - raw := buf.Bytes() - err := binary.Write(sliceWriter(raw[:headerLen]), opts.ByteOrder, header) - if err != nil { - return nil, fmt.Errorf("can't write header: %v", err) - } - - return raw, nil -} - -type sliceWriter []byte - -func (sw sliceWriter) Write(p []byte) (int, error) { - if len(p) != len(sw) { - return 0, errors.New("size doesn't match") - } - - return copy(sw, p), nil -} - -// TypeByID returns the BTF Type with the given type ID. -// -// Returns an error wrapping ErrNotFound if a Type with the given ID -// does not exist in the Spec. -func (s *Spec) TypeByID(id TypeID) (Type, error) { - return s.types.ByID(id) -} - -// TypeID returns the ID for a given Type. -// -// Returns an error wrapping ErrNoFound if the type isn't part of the Spec. -func (s *Spec) TypeID(typ Type) (TypeID, error) { - if _, ok := typ.(*Void); ok { - // Equality is weird for void, since it is a zero sized type. - return 0, nil - } - - id, ok := s.typeIDs[typ] - if !ok { - return 0, fmt.Errorf("no ID for type %s: %w", typ, ErrNotFound) - } - - return id, nil -} - -// AnyTypesByName returns a list of BTF Types with the given name. -// -// If the BTF blob describes multiple compilation units like vmlinux, multiple -// Types with the same name and kind can exist, but might not describe the same -// data structure. -// -// Returns an error wrapping ErrNotFound if no matching Type exists in the Spec. -func (s *Spec) AnyTypesByName(name string) ([]Type, error) { - types := s.namedTypes[newEssentialName(name)] - if len(types) == 0 { - return nil, fmt.Errorf("type name %s: %w", name, ErrNotFound) - } - - // Return a copy to prevent changes to namedTypes. - result := make([]Type, 0, len(types)) - for _, t := range types { - // Match against the full name, not just the essential one - // in case the type being looked up is a struct flavor. - if t.TypeName() == name { - result = append(result, t) - } - } - return result, nil -} - -// AnyTypeByName returns a Type with the given name. -// -// Returns an error if multiple types of that name exist. -func (s *Spec) AnyTypeByName(name string) (Type, error) { - types, err := s.AnyTypesByName(name) - if err != nil { - return nil, err - } - - if len(types) > 1 { - return nil, fmt.Errorf("found multiple types: %v", types) - } - - return types[0], nil -} - -// TypeByName searches for a Type with a specific name. Since multiple -// Types with the same name can exist, the parameter typ is taken to -// narrow down the search in case of a clash. -// -// typ must be a non-nil pointer to an implementation of a Type. -// On success, the address of the found Type will be copied to typ. -// -// Returns an error wrapping ErrNotFound if no matching -// Type exists in the Spec. If multiple candidates are found, -// an error is returned. -func (s *Spec) TypeByName(name string, typ interface{}) error { - typValue := reflect.ValueOf(typ) - if typValue.Kind() != reflect.Ptr { - return fmt.Errorf("%T is not a pointer", typ) - } - - typPtr := typValue.Elem() - if !typPtr.CanSet() { - return fmt.Errorf("%T cannot be set", typ) - } - - wanted := typPtr.Type() - if !wanted.AssignableTo(reflect.TypeOf((*Type)(nil)).Elem()) { - return fmt.Errorf("%T does not satisfy Type interface", typ) - } - - types, err := s.AnyTypesByName(name) - if err != nil { - return err - } - - var candidate Type - for _, typ := range types { - if reflect.TypeOf(typ) != wanted { - continue - } - - if candidate != nil { - return fmt.Errorf("type %s: multiple candidates for %T", name, typ) - } - - candidate = typ - } - - if candidate == nil { - return fmt.Errorf("type %s: %w", name, ErrNotFound) - } - - typPtr.Set(reflect.ValueOf(candidate)) - - return nil -} - -// LoadSplitSpecFromReader loads split BTF from a reader. -// -// Types from base are used to resolve references in the split BTF. -// The returned Spec only contains types from the split BTF, not from the base. -func LoadSplitSpecFromReader(r io.ReaderAt, base *Spec) (*Spec, error) { - return loadRawSpec(r, internal.NativeEndian, base.types, base.strings) -} - -// TypesIterator iterates over types of a given spec. -type TypesIterator struct { - spec *Spec - index int - // The last visited type in the spec. - Type Type -} - -// Iterate returns the types iterator. -func (s *Spec) Iterate() *TypesIterator { - return &TypesIterator{spec: s, index: 0} -} - -// Next returns true as long as there are any remaining types. -func (iter *TypesIterator) Next() bool { - if len(iter.spec.types) <= iter.index { - return false - } - - iter.Type = iter.spec.types[iter.index] - iter.index++ - return true -} - -// Handle is a reference to BTF loaded into the kernel. -type Handle struct { - fd *sys.FD - - // Size of the raw BTF in bytes. - size uint32 -} - -// NewHandle loads BTF into the kernel. -// -// Returns ErrNotSupported if BTF is not supported. -func NewHandle(spec *Spec) (*Handle, error) { - if err := haveBTF(); err != nil { - return nil, err - } - - if spec.byteOrder != internal.NativeEndian { - return nil, fmt.Errorf("can't load %s BTF on %s", spec.byteOrder, internal.NativeEndian) - } - - btf, err := spec.marshal(marshalOpts{ - ByteOrder: internal.NativeEndian, - StripFuncLinkage: haveFuncLinkage() != nil, - }) - if err != nil { - return nil, fmt.Errorf("can't marshal BTF: %w", err) - } - - if uint64(len(btf)) > math.MaxUint32 { - return nil, errors.New("BTF exceeds the maximum size") - } - - attr := &sys.BtfLoadAttr{ - Btf: sys.NewSlicePointer(btf), - BtfSize: uint32(len(btf)), - } - - fd, err := sys.BtfLoad(attr) - if err != nil { - logBuf := make([]byte, 64*1024) - attr.BtfLogBuf = sys.NewSlicePointer(logBuf) - attr.BtfLogSize = uint32(len(logBuf)) - attr.BtfLogLevel = 1 - // NB: The syscall will never return ENOSPC as of 5.18-rc4. - _, _ = sys.BtfLoad(attr) - return nil, internal.ErrorWithLog(err, logBuf) - } - - return &Handle{fd, attr.BtfSize}, nil -} - -// NewHandleFromID returns the BTF handle for a given id. -// -// Prefer calling [ebpf.Program.Handle] or [ebpf.Map.Handle] if possible. -// -// Returns ErrNotExist, if there is no BTF with the given id. -// -// Requires CAP_SYS_ADMIN. -func NewHandleFromID(id ID) (*Handle, error) { - fd, err := sys.BtfGetFdById(&sys.BtfGetFdByIdAttr{ - Id: uint32(id), - }) - if err != nil { - return nil, fmt.Errorf("get FD for ID %d: %w", id, err) - } - - info, err := newHandleInfoFromFD(fd) - if err != nil { - _ = fd.Close() - return nil, err - } - - return &Handle{fd, info.size}, nil -} - -// Spec parses the kernel BTF into Go types. -// -// base is used to decode split BTF and may be nil. -func (h *Handle) Spec(base *Spec) (*Spec, error) { - var btfInfo sys.BtfInfo - btfBuffer := make([]byte, h.size) - btfInfo.Btf, btfInfo.BtfSize = sys.NewSlicePointerLen(btfBuffer) - - if err := sys.ObjInfo(h.fd, &btfInfo); err != nil { - return nil, err - } - - var baseTypes types - var baseStrings *stringTable - if base != nil { - baseTypes = base.types - baseStrings = base.strings - } - - return loadRawSpec(bytes.NewReader(btfBuffer), internal.NativeEndian, baseTypes, baseStrings) -} - -// Close destroys the handle. -// -// Subsequent calls to FD will return an invalid value. -func (h *Handle) Close() error { - if h == nil { - return nil - } - - return h.fd.Close() -} - -// FD returns the file descriptor for the handle. -func (h *Handle) FD() int { - return h.fd.Int() -} - -// Info returns metadata about the handle. -func (h *Handle) Info() (*HandleInfo, error) { - return newHandleInfoFromFD(h.fd) -} - -func marshalBTF(types interface{}, strings []byte, bo binary.ByteOrder) []byte { - const minHeaderLength = 24 - - typesLen := uint32(binary.Size(types)) - header := btfHeader{ - Magic: btfMagic, - Version: 1, - HdrLen: minHeaderLength, - TypeOff: 0, - TypeLen: typesLen, - StringOff: typesLen, - StringLen: uint32(len(strings)), - } - - buf := new(bytes.Buffer) - _ = binary.Write(buf, bo, &header) - _ = binary.Write(buf, bo, types) - buf.Write(strings) - - return buf.Bytes() -} - -var haveBTF = internal.FeatureTest("BTF", "5.1", func() error { - var ( - types struct { - Integer btfType - Var btfType - btfVar struct{ Linkage uint32 } - } - strings = []byte{0, 'a', 0} - ) - - // We use a BTF_KIND_VAR here, to make sure that - // the kernel understands BTF at least as well as we - // do. BTF_KIND_VAR was introduced ~5.1. - types.Integer.SetKind(kindPointer) - types.Var.NameOff = 1 - types.Var.SetKind(kindVar) - types.Var.SizeType = 1 - - btf := marshalBTF(&types, strings, internal.NativeEndian) - - fd, err := sys.BtfLoad(&sys.BtfLoadAttr{ - Btf: sys.NewSlicePointer(btf), - BtfSize: uint32(len(btf)), - }) - if errors.Is(err, unix.EINVAL) || errors.Is(err, unix.EPERM) { - // Treat both EINVAL and EPERM as not supported: loading the program - // might still succeed without BTF. - return internal.ErrNotSupported - } - if err != nil { - return err - } - - fd.Close() - return nil -}) - -var haveFuncLinkage = internal.FeatureTest("BTF func linkage", "5.6", func() error { - if err := haveBTF(); err != nil { - return err - } - - var ( - types struct { - FuncProto btfType - Func btfType - } - strings = []byte{0, 'a', 0} - ) - - types.FuncProto.SetKind(kindFuncProto) - types.Func.SetKind(kindFunc) - types.Func.SizeType = 1 // aka FuncProto - types.Func.NameOff = 1 - types.Func.SetLinkage(GlobalFunc) - - btf := marshalBTF(&types, strings, internal.NativeEndian) - - fd, err := sys.BtfLoad(&sys.BtfLoadAttr{ - Btf: sys.NewSlicePointer(btf), - BtfSize: uint32(len(btf)), - }) - if errors.Is(err, unix.EINVAL) { - return internal.ErrNotSupported - } - if err != nil { - return err - } - - fd.Close() - return nil -}) diff --git a/vendor/github.com/cilium/ebpf/btf/btf_types.go b/vendor/github.com/cilium/ebpf/btf/btf_types.go deleted file mode 100644 index 48101804..00000000 --- a/vendor/github.com/cilium/ebpf/btf/btf_types.go +++ /dev/null @@ -1,343 +0,0 @@ -package btf - -import ( - "encoding/binary" - "fmt" - "io" -) - -//go:generate stringer -linecomment -output=btf_types_string.go -type=FuncLinkage,VarLinkage - -// btfKind describes a Type. -type btfKind uint8 - -// Equivalents of the BTF_KIND_* constants. -const ( - kindUnknown btfKind = iota - kindInt - kindPointer - kindArray - kindStruct - kindUnion - kindEnum - kindForward - kindTypedef - kindVolatile - kindConst - kindRestrict - // Added ~4.20 - kindFunc - kindFuncProto - // Added ~5.1 - kindVar - kindDatasec - // Added ~5.13 - kindFloat -) - -// FuncLinkage describes BTF function linkage metadata. -type FuncLinkage int - -// Equivalent of enum btf_func_linkage. -const ( - StaticFunc FuncLinkage = iota // static - GlobalFunc // global - ExternFunc // extern -) - -// VarLinkage describes BTF variable linkage metadata. -type VarLinkage int - -const ( - StaticVar VarLinkage = iota // static - GlobalVar // global - ExternVar // extern -) - -const ( - btfTypeKindShift = 24 - btfTypeKindLen = 5 - btfTypeVlenShift = 0 - btfTypeVlenMask = 16 - btfTypeKindFlagShift = 31 - btfTypeKindFlagMask = 1 -) - -// btfType is equivalent to struct btf_type in Documentation/bpf/btf.rst. -type btfType struct { - NameOff uint32 - /* "info" bits arrangement - * bits 0-15: vlen (e.g. # of struct's members), linkage - * bits 16-23: unused - * bits 24-28: kind (e.g. int, ptr, array...etc) - * bits 29-30: unused - * bit 31: kind_flag, currently used by - * struct, union and fwd - */ - Info uint32 - /* "size" is used by INT, ENUM, STRUCT and UNION. - * "size" tells the size of the type it is describing. - * - * "type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT, - * FUNC and FUNC_PROTO. - * "type" is a type_id referring to another type. - */ - SizeType uint32 -} - -func (k btfKind) String() string { - switch k { - case kindUnknown: - return "Unknown" - case kindInt: - return "Integer" - case kindPointer: - return "Pointer" - case kindArray: - return "Array" - case kindStruct: - return "Struct" - case kindUnion: - return "Union" - case kindEnum: - return "Enumeration" - case kindForward: - return "Forward" - case kindTypedef: - return "Typedef" - case kindVolatile: - return "Volatile" - case kindConst: - return "Const" - case kindRestrict: - return "Restrict" - case kindFunc: - return "Function" - case kindFuncProto: - return "Function Proto" - case kindVar: - return "Variable" - case kindDatasec: - return "Section" - case kindFloat: - return "Float" - default: - return fmt.Sprintf("Unknown (%d)", k) - } -} - -func mask(len uint32) uint32 { - return (1 << len) - 1 -} - -func readBits(value, len, shift uint32) uint32 { - return (value >> shift) & mask(len) -} - -func writeBits(value, len, shift, new uint32) uint32 { - value &^= mask(len) << shift - value |= (new & mask(len)) << shift - return value -} - -func (bt *btfType) info(len, shift uint32) uint32 { - return readBits(bt.Info, len, shift) -} - -func (bt *btfType) setInfo(value, len, shift uint32) { - bt.Info = writeBits(bt.Info, len, shift, value) -} - -func (bt *btfType) Kind() btfKind { - return btfKind(bt.info(btfTypeKindLen, btfTypeKindShift)) -} - -func (bt *btfType) SetKind(kind btfKind) { - bt.setInfo(uint32(kind), btfTypeKindLen, btfTypeKindShift) -} - -func (bt *btfType) Vlen() int { - return int(bt.info(btfTypeVlenMask, btfTypeVlenShift)) -} - -func (bt *btfType) SetVlen(vlen int) { - bt.setInfo(uint32(vlen), btfTypeVlenMask, btfTypeVlenShift) -} - -func (bt *btfType) KindFlag() bool { - return bt.info(btfTypeKindFlagMask, btfTypeKindFlagShift) == 1 -} - -func (bt *btfType) Linkage() FuncLinkage { - return FuncLinkage(bt.info(btfTypeVlenMask, btfTypeVlenShift)) -} - -func (bt *btfType) SetLinkage(linkage FuncLinkage) { - bt.setInfo(uint32(linkage), btfTypeVlenMask, btfTypeVlenShift) -} - -func (bt *btfType) Type() TypeID { - // TODO: Panic here if wrong kind? - return TypeID(bt.SizeType) -} - -func (bt *btfType) Size() uint32 { - // TODO: Panic here if wrong kind? - return bt.SizeType -} - -func (bt *btfType) SetSize(size uint32) { - bt.SizeType = size -} - -type rawType struct { - btfType - data interface{} -} - -func (rt *rawType) Marshal(w io.Writer, bo binary.ByteOrder) error { - if err := binary.Write(w, bo, &rt.btfType); err != nil { - return err - } - - if rt.data == nil { - return nil - } - - return binary.Write(w, bo, rt.data) -} - -// btfInt encodes additional data for integers. -// -// ? ? ? ? e e e e o o o o o o o o ? ? ? ? ? ? ? ? b b b b b b b b -// ? = undefined -// e = encoding -// o = offset (bitfields?) -// b = bits (bitfields) -type btfInt struct { - Raw uint32 -} - -const ( - btfIntEncodingLen = 4 - btfIntEncodingShift = 24 - btfIntOffsetLen = 8 - btfIntOffsetShift = 16 - btfIntBitsLen = 8 - btfIntBitsShift = 0 -) - -func (bi btfInt) Encoding() IntEncoding { - return IntEncoding(readBits(bi.Raw, btfIntEncodingLen, btfIntEncodingShift)) -} - -func (bi *btfInt) SetEncoding(e IntEncoding) { - bi.Raw = writeBits(uint32(bi.Raw), btfIntEncodingLen, btfIntEncodingShift, uint32(e)) -} - -func (bi btfInt) Offset() Bits { - return Bits(readBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift)) -} - -func (bi *btfInt) SetOffset(offset uint32) { - bi.Raw = writeBits(bi.Raw, btfIntOffsetLen, btfIntOffsetShift, offset) -} - -func (bi btfInt) Bits() Bits { - return Bits(readBits(bi.Raw, btfIntBitsLen, btfIntBitsShift)) -} - -func (bi *btfInt) SetBits(bits byte) { - bi.Raw = writeBits(bi.Raw, btfIntBitsLen, btfIntBitsShift, uint32(bits)) -} - -type btfArray struct { - Type TypeID - IndexType TypeID - Nelems uint32 -} - -type btfMember struct { - NameOff uint32 - Type TypeID - Offset uint32 -} - -type btfVarSecinfo struct { - Type TypeID - Offset uint32 - Size uint32 -} - -type btfVariable struct { - Linkage uint32 -} - -type btfEnum struct { - NameOff uint32 - Val int32 -} - -type btfParam struct { - NameOff uint32 - Type TypeID -} - -func readTypes(r io.Reader, bo binary.ByteOrder, typeLen uint32) ([]rawType, error) { - var header btfType - // because of the interleaving between types and struct members it is difficult to - // precompute the numbers of raw types this will parse - // this "guess" is a good first estimation - sizeOfbtfType := uintptr(binary.Size(btfType{})) - tyMaxCount := uintptr(typeLen) / sizeOfbtfType / 2 - types := make([]rawType, 0, tyMaxCount) - - for id := TypeID(1); ; id++ { - if err := binary.Read(r, bo, &header); err == io.EOF { - return types, nil - } else if err != nil { - return nil, fmt.Errorf("can't read type info for id %v: %v", id, err) - } - - var data interface{} - switch header.Kind() { - case kindInt: - data = new(btfInt) - case kindPointer: - case kindArray: - data = new(btfArray) - case kindStruct: - fallthrough - case kindUnion: - data = make([]btfMember, header.Vlen()) - case kindEnum: - data = make([]btfEnum, header.Vlen()) - case kindForward: - case kindTypedef: - case kindVolatile: - case kindConst: - case kindRestrict: - case kindFunc: - case kindFuncProto: - data = make([]btfParam, header.Vlen()) - case kindVar: - data = new(btfVariable) - case kindDatasec: - data = make([]btfVarSecinfo, header.Vlen()) - case kindFloat: - default: - return nil, fmt.Errorf("type id %v: unknown kind: %v", id, header.Kind()) - } - - if data == nil { - types = append(types, rawType{header, nil}) - continue - } - - if err := binary.Read(r, bo, data); err != nil { - return nil, fmt.Errorf("type id %d: kind %v: can't read %T: %v", id, header.Kind(), data, err) - } - - types = append(types, rawType{header, data}) - } -} diff --git a/vendor/github.com/cilium/ebpf/btf/btf_types_string.go b/vendor/github.com/cilium/ebpf/btf/btf_types_string.go deleted file mode 100644 index 0e0c17d6..00000000 --- a/vendor/github.com/cilium/ebpf/btf/btf_types_string.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by "stringer -linecomment -output=btf_types_string.go -type=FuncLinkage,VarLinkage"; DO NOT EDIT. - -package btf - -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[StaticFunc-0] - _ = x[GlobalFunc-1] - _ = x[ExternFunc-2] -} - -const _FuncLinkage_name = "staticglobalextern" - -var _FuncLinkage_index = [...]uint8{0, 6, 12, 18} - -func (i FuncLinkage) String() string { - if i < 0 || i >= FuncLinkage(len(_FuncLinkage_index)-1) { - return "FuncLinkage(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _FuncLinkage_name[_FuncLinkage_index[i]:_FuncLinkage_index[i+1]] -} -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[StaticVar-0] - _ = x[GlobalVar-1] - _ = x[ExternVar-2] -} - -const _VarLinkage_name = "staticglobalextern" - -var _VarLinkage_index = [...]uint8{0, 6, 12, 18} - -func (i VarLinkage) String() string { - if i < 0 || i >= VarLinkage(len(_VarLinkage_index)-1) { - return "VarLinkage(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _VarLinkage_name[_VarLinkage_index[i]:_VarLinkage_index[i+1]] -} diff --git a/vendor/github.com/cilium/ebpf/btf/core.go b/vendor/github.com/cilium/ebpf/btf/core.go deleted file mode 100644 index c4875480..00000000 --- a/vendor/github.com/cilium/ebpf/btf/core.go +++ /dev/null @@ -1,972 +0,0 @@ -package btf - -import ( - "encoding/binary" - "errors" - "fmt" - "math" - "reflect" - "strconv" - "strings" - - "github.com/cilium/ebpf/asm" -) - -// Code in this file is derived from libbpf, which is available under a BSD -// 2-Clause license. - -// COREFixup is the result of computing a CO-RE relocation for a target. -type COREFixup struct { - kind coreKind - local uint32 - target uint32 - // True if there is no valid fixup. The instruction is replaced with an - // invalid dummy. - poison bool - // True if the validation of the local value should be skipped. Used by - // some kinds of bitfield relocations. - skipLocalValidation bool -} - -func (f *COREFixup) equal(other COREFixup) bool { - return f.local == other.local && f.target == other.target -} - -func (f *COREFixup) String() string { - if f.poison { - return fmt.Sprintf("%s=poison", f.kind) - } - return fmt.Sprintf("%s=%d->%d", f.kind, f.local, f.target) -} - -func (f *COREFixup) Apply(ins *asm.Instruction) error { - if f.poison { - const badRelo = 0xbad2310 - - *ins = asm.BuiltinFunc(badRelo).Call() - return nil - } - - switch class := ins.OpCode.Class(); class { - case asm.LdXClass, asm.StClass, asm.StXClass: - if want := int16(f.local); !f.skipLocalValidation && want != ins.Offset { - return fmt.Errorf("invalid offset %d, expected %d", ins.Offset, f.local) - } - - if f.target > math.MaxInt16 { - return fmt.Errorf("offset %d exceeds MaxInt16", f.target) - } - - ins.Offset = int16(f.target) - - case asm.LdClass: - if !ins.IsConstantLoad(asm.DWord) { - return fmt.Errorf("not a dword-sized immediate load") - } - - if want := int64(f.local); !f.skipLocalValidation && want != ins.Constant { - return fmt.Errorf("invalid immediate %d, expected %d (fixup: %v)", ins.Constant, want, f) - } - - ins.Constant = int64(f.target) - - case asm.ALUClass: - if ins.OpCode.ALUOp() == asm.Swap { - return fmt.Errorf("relocation against swap") - } - - fallthrough - - case asm.ALU64Class: - if src := ins.OpCode.Source(); src != asm.ImmSource { - return fmt.Errorf("invalid source %s", src) - } - - if want := int64(f.local); !f.skipLocalValidation && want != ins.Constant { - return fmt.Errorf("invalid immediate %d, expected %d (fixup: %v, kind: %v, ins: %v)", ins.Constant, want, f, f.kind, ins) - } - - if f.target > math.MaxInt32 { - return fmt.Errorf("immediate %d exceeds MaxInt32", f.target) - } - - ins.Constant = int64(f.target) - - default: - return fmt.Errorf("invalid class %s", class) - } - - return nil -} - -func (f COREFixup) isNonExistant() bool { - return f.kind.checksForExistence() && f.target == 0 -} - -// coreKind is the type of CO-RE relocation as specified in BPF source code. -type coreKind uint32 - -const ( - reloFieldByteOffset coreKind = iota /* field byte offset */ - reloFieldByteSize /* field size in bytes */ - reloFieldExists /* field existence in target kernel */ - reloFieldSigned /* field signedness (0 - unsigned, 1 - signed) */ - reloFieldLShiftU64 /* bitfield-specific left bitshift */ - reloFieldRShiftU64 /* bitfield-specific right bitshift */ - reloTypeIDLocal /* type ID in local BPF object */ - reloTypeIDTarget /* type ID in target kernel */ - reloTypeExists /* type existence in target kernel */ - reloTypeSize /* type size in bytes */ - reloEnumvalExists /* enum value existence in target kernel */ - reloEnumvalValue /* enum value integer value */ -) - -func (k coreKind) checksForExistence() bool { - return k == reloEnumvalExists || k == reloTypeExists || k == reloFieldExists -} - -func (k coreKind) String() string { - switch k { - case reloFieldByteOffset: - return "byte_off" - case reloFieldByteSize: - return "byte_sz" - case reloFieldExists: - return "field_exists" - case reloFieldSigned: - return "signed" - case reloFieldLShiftU64: - return "lshift_u64" - case reloFieldRShiftU64: - return "rshift_u64" - case reloTypeIDLocal: - return "local_type_id" - case reloTypeIDTarget: - return "target_type_id" - case reloTypeExists: - return "type_exists" - case reloTypeSize: - return "type_size" - case reloEnumvalExists: - return "enumval_exists" - case reloEnumvalValue: - return "enumval_value" - default: - return "unknown" - } -} - -// CORERelocate calculates the difference in types between local and target. -// -// Returns a list of fixups which can be applied to instructions to make them -// match the target type(s). -// -// Fixups are returned in the order of relos, e.g. fixup[i] is the solution -// for relos[i]. -func CORERelocate(local, target *Spec, relos []*CORERelocation) ([]COREFixup, error) { - if local.byteOrder != target.byteOrder { - return nil, fmt.Errorf("can't relocate %s against %s", local.byteOrder, target.byteOrder) - } - - type reloGroup struct { - relos []*CORERelocation - // Position of each relocation in relos. - indices []int - } - - // Split relocations into per Type lists. - relosByType := make(map[Type]*reloGroup) - result := make([]COREFixup, len(relos)) - for i, relo := range relos { - if relo.kind == reloTypeIDLocal { - // Filtering out reloTypeIDLocal here makes our lives a lot easier - // down the line, since it doesn't have a target at all. - if len(relo.accessor) > 1 || relo.accessor[0] != 0 { - return nil, fmt.Errorf("%s: unexpected accessor %v", relo.kind, relo.accessor) - } - - id, err := local.TypeID(relo.typ) - if err != nil { - return nil, fmt.Errorf("%s: %w", relo.kind, err) - } - - result[i] = COREFixup{ - kind: relo.kind, - local: uint32(id), - target: uint32(id), - } - continue - } - - group, ok := relosByType[relo.typ] - if !ok { - group = &reloGroup{} - relosByType[relo.typ] = group - } - group.relos = append(group.relos, relo) - group.indices = append(group.indices, i) - } - - for localType, group := range relosByType { - localTypeName := localType.TypeName() - if localTypeName == "" { - return nil, fmt.Errorf("relocate unnamed or anonymous type %s: %w", localType, ErrNotSupported) - } - - targets := target.namedTypes[newEssentialName(localTypeName)] - fixups, err := coreCalculateFixups(local, target, localType, targets, group.relos) - if err != nil { - return nil, fmt.Errorf("relocate %s: %w", localType, err) - } - - for j, index := range group.indices { - result[index] = fixups[j] - } - } - - return result, nil -} - -var errAmbiguousRelocation = errors.New("ambiguous relocation") -var errImpossibleRelocation = errors.New("impossible relocation") - -// coreCalculateFixups calculates the fixups for the given relocations using -// the "best" target. -// -// The best target is determined by scoring: the less poisoning we have to do -// the better the target is. -func coreCalculateFixups(localSpec, targetSpec *Spec, local Type, targets []Type, relos []*CORERelocation) ([]COREFixup, error) { - localID, err := localSpec.TypeID(local) - if err != nil { - return nil, fmt.Errorf("local type ID: %w", err) - } - local = Copy(local, UnderlyingType) - - bestScore := len(relos) - var bestFixups []COREFixup - for i := range targets { - targetID, err := targetSpec.TypeID(targets[i]) - if err != nil { - return nil, fmt.Errorf("target type ID: %w", err) - } - target := Copy(targets[i], UnderlyingType) - - score := 0 // lower is better - fixups := make([]COREFixup, 0, len(relos)) - for _, relo := range relos { - fixup, err := coreCalculateFixup(localSpec.byteOrder, local, localID, target, targetID, relo) - if err != nil { - return nil, fmt.Errorf("target %s: %w", target, err) - } - if fixup.poison || fixup.isNonExistant() { - score++ - } - fixups = append(fixups, fixup) - } - - if score > bestScore { - // We have a better target already, ignore this one. - continue - } - - if score < bestScore { - // This is the best target yet, use it. - bestScore = score - bestFixups = fixups - continue - } - - // Some other target has the same score as the current one. Make sure - // the fixups agree with each other. - for i, fixup := range bestFixups { - if !fixup.equal(fixups[i]) { - return nil, fmt.Errorf("%s: multiple types match: %w", fixup.kind, errAmbiguousRelocation) - } - } - } - - if bestFixups == nil { - // Nothing at all matched, probably because there are no suitable - // targets at all. - // - // Poison everything except checksForExistence. - bestFixups = make([]COREFixup, len(relos)) - for i, relo := range relos { - if relo.kind.checksForExistence() { - bestFixups[i] = COREFixup{kind: relo.kind, local: 1, target: 0} - } else { - bestFixups[i] = COREFixup{kind: relo.kind, poison: true} - } - } - } - - return bestFixups, nil -} - -// coreCalculateFixup calculates the fixup for a single local type, target type -// and relocation. -func coreCalculateFixup(byteOrder binary.ByteOrder, local Type, localID TypeID, target Type, targetID TypeID, relo *CORERelocation) (COREFixup, error) { - fixup := func(local, target uint32) (COREFixup, error) { - return COREFixup{kind: relo.kind, local: local, target: target}, nil - } - fixupWithoutValidation := func(local, target uint32) (COREFixup, error) { - return COREFixup{kind: relo.kind, local: local, target: target, skipLocalValidation: true}, nil - } - poison := func() (COREFixup, error) { - if relo.kind.checksForExistence() { - return fixup(1, 0) - } - return COREFixup{kind: relo.kind, poison: true}, nil - } - zero := COREFixup{} - - switch relo.kind { - case reloTypeIDTarget, reloTypeSize, reloTypeExists: - if len(relo.accessor) > 1 || relo.accessor[0] != 0 { - return zero, fmt.Errorf("%s: unexpected accessor %v", relo.kind, relo.accessor) - } - - err := coreAreTypesCompatible(local, target) - if errors.Is(err, errImpossibleRelocation) { - return poison() - } - if err != nil { - return zero, fmt.Errorf("relocation %s: %w", relo.kind, err) - } - - switch relo.kind { - case reloTypeExists: - return fixup(1, 1) - - case reloTypeIDTarget: - return fixup(uint32(localID), uint32(targetID)) - - case reloTypeSize: - localSize, err := Sizeof(local) - if err != nil { - return zero, err - } - - targetSize, err := Sizeof(target) - if err != nil { - return zero, err - } - - return fixup(uint32(localSize), uint32(targetSize)) - } - - case reloEnumvalValue, reloEnumvalExists: - localValue, targetValue, err := coreFindEnumValue(local, relo.accessor, target) - if errors.Is(err, errImpossibleRelocation) { - return poison() - } - if err != nil { - return zero, fmt.Errorf("relocation %s: %w", relo.kind, err) - } - - switch relo.kind { - case reloEnumvalExists: - return fixup(1, 1) - - case reloEnumvalValue: - return fixup(uint32(localValue.Value), uint32(targetValue.Value)) - } - - case reloFieldSigned: - switch local.(type) { - case *Enum: - return fixup(1, 1) - case *Int: - return fixup( - uint32(local.(*Int).Encoding&Signed), - uint32(target.(*Int).Encoding&Signed), - ) - default: - return fixupWithoutValidation(0, 0) - } - - case reloFieldByteOffset, reloFieldByteSize, reloFieldExists, reloFieldLShiftU64, reloFieldRShiftU64: - if _, ok := target.(*Fwd); ok { - // We can't relocate fields using a forward declaration, so - // skip it. If a non-forward declaration is present in the BTF - // we'll find it in one of the other iterations. - return poison() - } - - localField, targetField, err := coreFindField(local, relo.accessor, target) - if errors.Is(err, errImpossibleRelocation) { - return poison() - } - if err != nil { - return zero, fmt.Errorf("target %s: %w", target, err) - } - - maybeSkipValidation := func(f COREFixup, err error) (COREFixup, error) { - f.skipLocalValidation = localField.bitfieldSize > 0 - return f, err - } - - switch relo.kind { - case reloFieldExists: - return fixup(1, 1) - - case reloFieldByteOffset: - return maybeSkipValidation(fixup(localField.offset, targetField.offset)) - - case reloFieldByteSize: - localSize, err := Sizeof(localField.Type) - if err != nil { - return zero, err - } - - targetSize, err := Sizeof(targetField.Type) - if err != nil { - return zero, err - } - return maybeSkipValidation(fixup(uint32(localSize), uint32(targetSize))) - - case reloFieldLShiftU64: - var target uint32 - if byteOrder == binary.LittleEndian { - targetSize, err := targetField.sizeBits() - if err != nil { - return zero, err - } - - target = uint32(64 - targetField.bitfieldOffset - targetSize) - } else { - loadWidth, err := Sizeof(targetField.Type) - if err != nil { - return zero, err - } - - target = uint32(64 - Bits(loadWidth*8) + targetField.bitfieldOffset) - } - return fixupWithoutValidation(0, target) - - case reloFieldRShiftU64: - targetSize, err := targetField.sizeBits() - if err != nil { - return zero, err - } - - return fixupWithoutValidation(0, uint32(64-targetSize)) - } - } - - return zero, fmt.Errorf("relocation %s: %w", relo.kind, ErrNotSupported) -} - -/* coreAccessor contains a path through a struct. It contains at least one index. - * - * The interpretation depends on the kind of the relocation. The following is - * taken from struct bpf_core_relo in libbpf_internal.h: - * - * - for field-based relocations, string encodes an accessed field using - * a sequence of field and array indices, separated by colon (:). It's - * conceptually very close to LLVM's getelementptr ([0]) instruction's - * arguments for identifying offset to a field. - * - for type-based relocations, strings is expected to be just "0"; - * - for enum value-based relocations, string contains an index of enum - * value within its enum type; - * - * Example to provide a better feel. - * - * struct sample { - * int a; - * struct { - * int b[10]; - * }; - * }; - * - * struct sample s = ...; - * int x = &s->a; // encoded as "0:0" (a is field #0) - * int y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1, - * // b is field #0 inside anon struct, accessing elem #5) - * int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array) - */ -type coreAccessor []int - -func parseCOREAccessor(accessor string) (coreAccessor, error) { - if accessor == "" { - return nil, fmt.Errorf("empty accessor") - } - - parts := strings.Split(accessor, ":") - result := make(coreAccessor, 0, len(parts)) - for _, part := range parts { - // 31 bits to avoid overflowing int on 32 bit platforms. - index, err := strconv.ParseUint(part, 10, 31) - if err != nil { - return nil, fmt.Errorf("accessor index %q: %s", part, err) - } - - result = append(result, int(index)) - } - - return result, nil -} - -func (ca coreAccessor) String() string { - strs := make([]string, 0, len(ca)) - for _, i := range ca { - strs = append(strs, strconv.Itoa(i)) - } - return strings.Join(strs, ":") -} - -func (ca coreAccessor) enumValue(t Type) (*EnumValue, error) { - e, ok := t.(*Enum) - if !ok { - return nil, fmt.Errorf("not an enum: %s", t) - } - - if len(ca) > 1 { - return nil, fmt.Errorf("invalid accessor %s for enum", ca) - } - - i := ca[0] - if i >= len(e.Values) { - return nil, fmt.Errorf("invalid index %d for %s", i, e) - } - - return &e.Values[i], nil -} - -// coreField represents the position of a "child" of a composite type from the -// start of that type. -// -// /- start of composite -// | offset * 8 | bitfieldOffset | bitfieldSize | ... | -// \- start of field end of field -/ -type coreField struct { - Type Type - - // The position of the field from the start of the composite type in bytes. - offset uint32 - - // The offset of the bitfield in bits from the start of the field. - bitfieldOffset Bits - - // The size of the bitfield in bits. - // - // Zero if the field is not a bitfield. - bitfieldSize Bits -} - -func (cf *coreField) adjustOffsetToNthElement(n int) error { - size, err := Sizeof(cf.Type) - if err != nil { - return err - } - - cf.offset += uint32(n) * uint32(size) - return nil -} - -func (cf *coreField) adjustOffsetBits(offset Bits) error { - align, err := alignof(cf.Type) - if err != nil { - return err - } - - // We can compute the load offset by: - // 1) converting the bit offset to bytes with a flooring division. - // 2) dividing and multiplying that offset by the alignment, yielding the - // load size aligned offset. - offsetBytes := uint32(offset/8) / uint32(align) * uint32(align) - - // The number of bits remaining is the bit offset less the number of bits - // we can "skip" with the aligned offset. - cf.bitfieldOffset = offset - Bits(offsetBytes*8) - - // We know that cf.offset is aligned at to at least align since we get it - // from the compiler via BTF. Adding an aligned offsetBytes preserves the - // alignment. - cf.offset += offsetBytes - return nil -} - -func (cf *coreField) sizeBits() (Bits, error) { - if cf.bitfieldSize > 0 { - return cf.bitfieldSize, nil - } - - // Someone is trying to access a non-bitfield via a bit shift relocation. - // This happens when a field changes from a bitfield to a regular field - // between kernel versions. Synthesise the size to make the shifts work. - size, err := Sizeof(cf.Type) - if err != nil { - return 0, nil - } - return Bits(size * 8), nil -} - -// coreFindField descends into the local type using the accessor and tries to -// find an equivalent field in target at each step. -// -// Returns the field and the offset of the field from the start of -// target in bits. -func coreFindField(localT Type, localAcc coreAccessor, targetT Type) (coreField, coreField, error) { - local := coreField{Type: localT} - target := coreField{Type: targetT} - - // The first index is used to offset a pointer of the base type like - // when accessing an array. - if err := local.adjustOffsetToNthElement(localAcc[0]); err != nil { - return coreField{}, coreField{}, err - } - - if err := target.adjustOffsetToNthElement(localAcc[0]); err != nil { - return coreField{}, coreField{}, err - } - - if err := coreAreMembersCompatible(local.Type, target.Type); err != nil { - return coreField{}, coreField{}, fmt.Errorf("fields: %w", err) - } - - var localMaybeFlex, targetMaybeFlex bool - for i, acc := range localAcc[1:] { - switch localType := local.Type.(type) { - case composite: - // For composite types acc is used to find the field in the local type, - // and then we try to find a field in target with the same name. - localMembers := localType.members() - if acc >= len(localMembers) { - return coreField{}, coreField{}, fmt.Errorf("invalid accessor %d for %s", acc, localType) - } - - localMember := localMembers[acc] - if localMember.Name == "" { - _, ok := localMember.Type.(composite) - if !ok { - return coreField{}, coreField{}, fmt.Errorf("unnamed field with type %s: %s", localMember.Type, ErrNotSupported) - } - - // This is an anonymous struct or union, ignore it. - local = coreField{ - Type: localMember.Type, - offset: local.offset + localMember.Offset.Bytes(), - } - localMaybeFlex = false - continue - } - - targetType, ok := target.Type.(composite) - if !ok { - return coreField{}, coreField{}, fmt.Errorf("target not composite: %w", errImpossibleRelocation) - } - - targetMember, last, err := coreFindMember(targetType, localMember.Name) - if err != nil { - return coreField{}, coreField{}, err - } - - local = coreField{ - Type: localMember.Type, - offset: local.offset, - bitfieldSize: localMember.BitfieldSize, - } - localMaybeFlex = acc == len(localMembers)-1 - - target = coreField{ - Type: targetMember.Type, - offset: target.offset, - bitfieldSize: targetMember.BitfieldSize, - } - targetMaybeFlex = last - - if local.bitfieldSize == 0 && target.bitfieldSize == 0 { - local.offset += localMember.Offset.Bytes() - target.offset += targetMember.Offset.Bytes() - break - } - - // Either of the members is a bitfield. Make sure we're at the - // end of the accessor. - if next := i + 1; next < len(localAcc[1:]) { - return coreField{}, coreField{}, fmt.Errorf("can't descend into bitfield") - } - - if err := local.adjustOffsetBits(localMember.Offset); err != nil { - return coreField{}, coreField{}, err - } - - if err := target.adjustOffsetBits(targetMember.Offset); err != nil { - return coreField{}, coreField{}, err - } - - case *Array: - // For arrays, acc is the index in the target. - targetType, ok := target.Type.(*Array) - if !ok { - return coreField{}, coreField{}, fmt.Errorf("target not array: %w", errImpossibleRelocation) - } - - if localType.Nelems == 0 && !localMaybeFlex { - return coreField{}, coreField{}, fmt.Errorf("local type has invalid flexible array") - } - if targetType.Nelems == 0 && !targetMaybeFlex { - return coreField{}, coreField{}, fmt.Errorf("target type has invalid flexible array") - } - - if localType.Nelems > 0 && acc >= int(localType.Nelems) { - return coreField{}, coreField{}, fmt.Errorf("invalid access of %s at index %d", localType, acc) - } - if targetType.Nelems > 0 && acc >= int(targetType.Nelems) { - return coreField{}, coreField{}, fmt.Errorf("out of bounds access of target: %w", errImpossibleRelocation) - } - - local = coreField{ - Type: localType.Type, - offset: local.offset, - } - localMaybeFlex = false - - if err := local.adjustOffsetToNthElement(acc); err != nil { - return coreField{}, coreField{}, err - } - - target = coreField{ - Type: targetType.Type, - offset: target.offset, - } - targetMaybeFlex = false - - if err := target.adjustOffsetToNthElement(acc); err != nil { - return coreField{}, coreField{}, err - } - - default: - return coreField{}, coreField{}, fmt.Errorf("relocate field of %T: %w", localType, ErrNotSupported) - } - - if err := coreAreMembersCompatible(local.Type, target.Type); err != nil { - return coreField{}, coreField{}, err - } - } - - return local, target, nil -} - -// coreFindMember finds a member in a composite type while handling anonymous -// structs and unions. -func coreFindMember(typ composite, name string) (Member, bool, error) { - if name == "" { - return Member{}, false, errors.New("can't search for anonymous member") - } - - type offsetTarget struct { - composite - offset Bits - } - - targets := []offsetTarget{{typ, 0}} - visited := make(map[composite]bool) - - for i := 0; i < len(targets); i++ { - target := targets[i] - - // Only visit targets once to prevent infinite recursion. - if visited[target] { - continue - } - if len(visited) >= maxTypeDepth { - // This check is different than libbpf, which restricts the entire - // path to BPF_CORE_SPEC_MAX_LEN items. - return Member{}, false, fmt.Errorf("type is nested too deep") - } - visited[target] = true - - members := target.members() - for j, member := range members { - if member.Name == name { - // NB: This is safe because member is a copy. - member.Offset += target.offset - return member, j == len(members)-1, nil - } - - // The names don't match, but this member could be an anonymous struct - // or union. - if member.Name != "" { - continue - } - - comp, ok := member.Type.(composite) - if !ok { - return Member{}, false, fmt.Errorf("anonymous non-composite type %T not allowed", member.Type) - } - - targets = append(targets, offsetTarget{comp, target.offset + member.Offset}) - } - } - - return Member{}, false, fmt.Errorf("no matching member: %w", errImpossibleRelocation) -} - -// coreFindEnumValue follows localAcc to find the equivalent enum value in target. -func coreFindEnumValue(local Type, localAcc coreAccessor, target Type) (localValue, targetValue *EnumValue, _ error) { - localValue, err := localAcc.enumValue(local) - if err != nil { - return nil, nil, err - } - - targetEnum, ok := target.(*Enum) - if !ok { - return nil, nil, errImpossibleRelocation - } - - localName := newEssentialName(localValue.Name) - for i, targetValue := range targetEnum.Values { - if newEssentialName(targetValue.Name) != localName { - continue - } - - return localValue, &targetEnum.Values[i], nil - } - - return nil, nil, errImpossibleRelocation -} - -/* The comment below is from bpf_core_types_are_compat in libbpf.c: - * - * Check local and target types for compatibility. This check is used for - * type-based CO-RE relocations and follow slightly different rules than - * field-based relocations. This function assumes that root types were already - * checked for name match. Beyond that initial root-level name check, names - * are completely ignored. Compatibility rules are as follows: - * - any two STRUCTs/UNIONs/FWDs/ENUMs/INTs are considered compatible, but - * kind should match for local and target types (i.e., STRUCT is not - * compatible with UNION); - * - for ENUMs, the size is ignored; - * - for INT, size and signedness are ignored; - * - for ARRAY, dimensionality is ignored, element types are checked for - * compatibility recursively; - * - CONST/VOLATILE/RESTRICT modifiers are ignored; - * - TYPEDEFs/PTRs are compatible if types they pointing to are compatible; - * - FUNC_PROTOs are compatible if they have compatible signature: same - * number of input args and compatible return and argument types. - * These rules are not set in stone and probably will be adjusted as we get - * more experience with using BPF CO-RE relocations. - * - * Returns errImpossibleRelocation if types are not compatible. - */ -func coreAreTypesCompatible(localType Type, targetType Type) error { - var ( - localTs, targetTs typeDeque - l, t = &localType, &targetType - depth = 0 - ) - - for ; l != nil && t != nil; l, t = localTs.shift(), targetTs.shift() { - if depth >= maxTypeDepth { - return errors.New("types are nested too deep") - } - - localType = *l - targetType = *t - - if reflect.TypeOf(localType) != reflect.TypeOf(targetType) { - return fmt.Errorf("type mismatch: %w", errImpossibleRelocation) - } - - switch lv := (localType).(type) { - case *Void, *Struct, *Union, *Enum, *Fwd, *Int: - // Nothing to do here - - case *Pointer, *Array: - depth++ - localType.walk(&localTs) - targetType.walk(&targetTs) - - case *FuncProto: - tv := targetType.(*FuncProto) - if len(lv.Params) != len(tv.Params) { - return fmt.Errorf("function param mismatch: %w", errImpossibleRelocation) - } - - depth++ - localType.walk(&localTs) - targetType.walk(&targetTs) - - default: - return fmt.Errorf("unsupported type %T", localType) - } - } - - if l != nil { - return fmt.Errorf("dangling local type %T", *l) - } - - if t != nil { - return fmt.Errorf("dangling target type %T", *t) - } - - return nil -} - -/* coreAreMembersCompatible checks two types for field-based relocation compatibility. - * - * The comment below is from bpf_core_fields_are_compat in libbpf.c: - * - * Check two types for compatibility for the purpose of field access - * relocation. const/volatile/restrict and typedefs are skipped to ensure we - * are relocating semantically compatible entities: - * - any two STRUCTs/UNIONs are compatible and can be mixed; - * - any two FWDs are compatible, if their names match (modulo flavor suffix); - * - any two PTRs are always compatible; - * - for ENUMs, names should be the same (ignoring flavor suffix) or at - * least one of enums should be anonymous; - * - for ENUMs, check sizes, names are ignored; - * - for INT, size and signedness are ignored; - * - any two FLOATs are always compatible; - * - for ARRAY, dimensionality is ignored, element types are checked for - * compatibility recursively; - * [ NB: coreAreMembersCompatible doesn't recurse, this check is done - * by coreFindField. ] - * - everything else shouldn't be ever a target of relocation. - * These rules are not set in stone and probably will be adjusted as we get - * more experience with using BPF CO-RE relocations. - * - * Returns errImpossibleRelocation if the members are not compatible. - */ -func coreAreMembersCompatible(localType Type, targetType Type) error { - doNamesMatch := func(a, b string) error { - if a == "" || b == "" { - // allow anonymous and named type to match - return nil - } - - if newEssentialName(a) == newEssentialName(b) { - return nil - } - - return fmt.Errorf("names don't match: %w", errImpossibleRelocation) - } - - _, lok := localType.(composite) - _, tok := targetType.(composite) - if lok && tok { - return nil - } - - if reflect.TypeOf(localType) != reflect.TypeOf(targetType) { - return fmt.Errorf("type mismatch: %w", errImpossibleRelocation) - } - - switch lv := localType.(type) { - case *Array, *Pointer, *Float, *Int: - return nil - - case *Enum: - tv := targetType.(*Enum) - return doNamesMatch(lv.Name, tv.Name) - - case *Fwd: - tv := targetType.(*Fwd) - return doNamesMatch(lv.Name, tv.Name) - - default: - return fmt.Errorf("type %s: %w", localType, ErrNotSupported) - } -} diff --git a/vendor/github.com/cilium/ebpf/btf/doc.go b/vendor/github.com/cilium/ebpf/btf/doc.go deleted file mode 100644 index b1f4b1fc..00000000 --- a/vendor/github.com/cilium/ebpf/btf/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package btf handles data encoded according to the BPF Type Format. -// -// The canonical documentation lives in the Linux kernel repository and is -// available at https://www.kernel.org/doc/html/latest/bpf/btf.html -package btf diff --git a/vendor/github.com/cilium/ebpf/btf/ext_info.go b/vendor/github.com/cilium/ebpf/btf/ext_info.go deleted file mode 100644 index 2c0e1afe..00000000 --- a/vendor/github.com/cilium/ebpf/btf/ext_info.go +++ /dev/null @@ -1,721 +0,0 @@ -package btf - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "math" - "sort" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/internal" -) - -// ExtInfos contains ELF section metadata. -type ExtInfos struct { - // The slices are sorted by offset in ascending order. - funcInfos map[string][]funcInfo - lineInfos map[string][]lineInfo - relocationInfos map[string][]coreRelocationInfo -} - -// loadExtInfosFromELF parses ext infos from the .BTF.ext section in an ELF. -// -// Returns an error wrapping ErrNotFound if no ext infos are present. -func loadExtInfosFromELF(file *internal.SafeELFFile, ts types, strings *stringTable) (*ExtInfos, error) { - section := file.Section(".BTF.ext") - if section == nil { - return nil, fmt.Errorf("btf ext infos: %w", ErrNotFound) - } - - if section.ReaderAt == nil { - return nil, fmt.Errorf("compressed ext_info is not supported") - } - - return loadExtInfos(section.ReaderAt, file.ByteOrder, ts, strings) -} - -// loadExtInfos parses bare ext infos. -func loadExtInfos(r io.ReaderAt, bo binary.ByteOrder, ts types, strings *stringTable) (*ExtInfos, error) { - // Open unbuffered section reader. binary.Read() calls io.ReadFull on - // the header structs, resulting in one syscall per header. - headerRd := io.NewSectionReader(r, 0, math.MaxInt64) - extHeader, err := parseBTFExtHeader(headerRd, bo) - if err != nil { - return nil, fmt.Errorf("parsing BTF extension header: %w", err) - } - - coreHeader, err := parseBTFExtCOREHeader(headerRd, bo, extHeader) - if err != nil { - return nil, fmt.Errorf("parsing BTF CO-RE header: %w", err) - } - - buf := internal.NewBufferedSectionReader(r, extHeader.funcInfoStart(), int64(extHeader.FuncInfoLen)) - btfFuncInfos, err := parseFuncInfos(buf, bo, strings) - if err != nil { - return nil, fmt.Errorf("parsing BTF function info: %w", err) - } - - funcInfos := make(map[string][]funcInfo, len(btfFuncInfos)) - for section, bfis := range btfFuncInfos { - funcInfos[section], err = newFuncInfos(bfis, ts) - if err != nil { - return nil, fmt.Errorf("section %s: func infos: %w", section, err) - } - } - - buf = internal.NewBufferedSectionReader(r, extHeader.lineInfoStart(), int64(extHeader.LineInfoLen)) - btfLineInfos, err := parseLineInfos(buf, bo, strings) - if err != nil { - return nil, fmt.Errorf("parsing BTF line info: %w", err) - } - - lineInfos := make(map[string][]lineInfo, len(btfLineInfos)) - for section, blis := range btfLineInfos { - lineInfos[section], err = newLineInfos(blis, strings) - if err != nil { - return nil, fmt.Errorf("section %s: line infos: %w", section, err) - } - } - - if coreHeader == nil || coreHeader.COREReloLen == 0 { - return &ExtInfos{funcInfos, lineInfos, nil}, nil - } - - var btfCORERelos map[string][]bpfCORERelo - buf = internal.NewBufferedSectionReader(r, extHeader.coreReloStart(coreHeader), int64(coreHeader.COREReloLen)) - btfCORERelos, err = parseCORERelos(buf, bo, strings) - if err != nil { - return nil, fmt.Errorf("parsing CO-RE relocation info: %w", err) - } - - coreRelos := make(map[string][]coreRelocationInfo, len(btfCORERelos)) - for section, brs := range btfCORERelos { - coreRelos[section], err = newRelocationInfos(brs, ts, strings) - if err != nil { - return nil, fmt.Errorf("section %s: CO-RE relocations: %w", section, err) - } - } - - return &ExtInfos{funcInfos, lineInfos, coreRelos}, nil -} - -type funcInfoMeta struct{} -type coreRelocationMeta struct{} - -// Assign per-section metadata from BTF to a section's instructions. -func (ei *ExtInfos) Assign(insns asm.Instructions, section string) { - funcInfos := ei.funcInfos[section] - lineInfos := ei.lineInfos[section] - reloInfos := ei.relocationInfos[section] - - iter := insns.Iterate() - for iter.Next() { - if len(funcInfos) > 0 && funcInfos[0].offset == iter.Offset { - iter.Ins.Metadata.Set(funcInfoMeta{}, funcInfos[0].fn) - funcInfos = funcInfos[1:] - } - - if len(lineInfos) > 0 && lineInfos[0].offset == iter.Offset { - *iter.Ins = iter.Ins.WithSource(lineInfos[0].line) - lineInfos = lineInfos[1:] - } - - if len(reloInfos) > 0 && reloInfos[0].offset == iter.Offset { - iter.Ins.Metadata.Set(coreRelocationMeta{}, reloInfos[0].relo) - reloInfos = reloInfos[1:] - } - } -} - -// MarshalExtInfos encodes function and line info embedded in insns into kernel -// wire format. -func MarshalExtInfos(insns asm.Instructions, typeID func(Type) (TypeID, error)) (funcInfos, lineInfos []byte, _ error) { - iter := insns.Iterate() - var fiBuf, liBuf bytes.Buffer - for iter.Next() { - if fn := FuncMetadata(iter.Ins); fn != nil { - fi := &funcInfo{ - fn: fn, - offset: iter.Offset, - } - if err := fi.marshal(&fiBuf, typeID); err != nil { - return nil, nil, fmt.Errorf("write func info: %w", err) - } - } - - if line, ok := iter.Ins.Source().(*Line); ok { - li := &lineInfo{ - line: line, - offset: iter.Offset, - } - if err := li.marshal(&liBuf); err != nil { - return nil, nil, fmt.Errorf("write line info: %w", err) - } - } - } - return fiBuf.Bytes(), liBuf.Bytes(), nil -} - -// btfExtHeader is found at the start of the .BTF.ext section. -type btfExtHeader struct { - Magic uint16 - Version uint8 - Flags uint8 - - // HdrLen is larger than the size of struct btfExtHeader when it is - // immediately followed by a btfExtCOREHeader. - HdrLen uint32 - - FuncInfoOff uint32 - FuncInfoLen uint32 - LineInfoOff uint32 - LineInfoLen uint32 -} - -// parseBTFExtHeader parses the header of the .BTF.ext section. -func parseBTFExtHeader(r io.Reader, bo binary.ByteOrder) (*btfExtHeader, error) { - var header btfExtHeader - if err := binary.Read(r, bo, &header); err != nil { - return nil, fmt.Errorf("can't read header: %v", err) - } - - if header.Magic != btfMagic { - return nil, fmt.Errorf("incorrect magic value %v", header.Magic) - } - - if header.Version != 1 { - return nil, fmt.Errorf("unexpected version %v", header.Version) - } - - if header.Flags != 0 { - return nil, fmt.Errorf("unsupported flags %v", header.Flags) - } - - if int64(header.HdrLen) < int64(binary.Size(&header)) { - return nil, fmt.Errorf("header length shorter than btfExtHeader size") - } - - return &header, nil -} - -// funcInfoStart returns the offset from the beginning of the .BTF.ext section -// to the start of its func_info entries. -func (h *btfExtHeader) funcInfoStart() int64 { - return int64(h.HdrLen + h.FuncInfoOff) -} - -// lineInfoStart returns the offset from the beginning of the .BTF.ext section -// to the start of its line_info entries. -func (h *btfExtHeader) lineInfoStart() int64 { - return int64(h.HdrLen + h.LineInfoOff) -} - -// coreReloStart returns the offset from the beginning of the .BTF.ext section -// to the start of its CO-RE relocation entries. -func (h *btfExtHeader) coreReloStart(ch *btfExtCOREHeader) int64 { - return int64(h.HdrLen + ch.COREReloOff) -} - -// btfExtCOREHeader is found right after the btfExtHeader when its HdrLen -// field is larger than its size. -type btfExtCOREHeader struct { - COREReloOff uint32 - COREReloLen uint32 -} - -// parseBTFExtCOREHeader parses the tail of the .BTF.ext header. If additional -// header bytes are present, extHeader.HdrLen will be larger than the struct, -// indicating the presence of a CO-RE extension header. -func parseBTFExtCOREHeader(r io.Reader, bo binary.ByteOrder, extHeader *btfExtHeader) (*btfExtCOREHeader, error) { - extHdrSize := int64(binary.Size(&extHeader)) - remainder := int64(extHeader.HdrLen) - extHdrSize - - if remainder == 0 { - return nil, nil - } - - var coreHeader btfExtCOREHeader - if err := binary.Read(r, bo, &coreHeader); err != nil { - return nil, fmt.Errorf("can't read header: %v", err) - } - - return &coreHeader, nil -} - -type btfExtInfoSec struct { - SecNameOff uint32 - NumInfo uint32 -} - -// parseExtInfoSec parses a btf_ext_info_sec header within .BTF.ext, -// appearing within func_info and line_info sub-sections. -// These headers appear once for each program section in the ELF and are -// followed by one or more func/line_info records for the section. -func parseExtInfoSec(r io.Reader, bo binary.ByteOrder, strings *stringTable) (string, *btfExtInfoSec, error) { - var infoHeader btfExtInfoSec - if err := binary.Read(r, bo, &infoHeader); err != nil { - return "", nil, fmt.Errorf("read ext info header: %w", err) - } - - secName, err := strings.Lookup(infoHeader.SecNameOff) - if err != nil { - return "", nil, fmt.Errorf("get section name: %w", err) - } - if secName == "" { - return "", nil, fmt.Errorf("extinfo header refers to empty section name") - } - - if infoHeader.NumInfo == 0 { - return "", nil, fmt.Errorf("section %s has zero records", secName) - } - - return secName, &infoHeader, nil -} - -// parseExtInfoRecordSize parses the uint32 at the beginning of a func_infos -// or line_infos segment that describes the length of all extInfoRecords in -// that segment. -func parseExtInfoRecordSize(r io.Reader, bo binary.ByteOrder) (uint32, error) { - const maxRecordSize = 256 - - var recordSize uint32 - if err := binary.Read(r, bo, &recordSize); err != nil { - return 0, fmt.Errorf("can't read record size: %v", err) - } - - if recordSize < 4 { - // Need at least InsnOff worth of bytes per record. - return 0, errors.New("record size too short") - } - if recordSize > maxRecordSize { - return 0, fmt.Errorf("record size %v exceeds %v", recordSize, maxRecordSize) - } - - return recordSize, nil -} - -// The size of a FuncInfo in BTF wire format. -var FuncInfoSize = uint32(binary.Size(bpfFuncInfo{})) - -type funcInfo struct { - fn *Func - offset asm.RawInstructionOffset -} - -type bpfFuncInfo struct { - // Instruction offset of the function within an ELF section. - InsnOff uint32 - TypeID TypeID -} - -func newFuncInfo(fi bpfFuncInfo, ts types) (*funcInfo, error) { - typ, err := ts.ByID(fi.TypeID) - if err != nil { - return nil, err - } - - fn, ok := typ.(*Func) - if !ok { - return nil, fmt.Errorf("type ID %d is a %T, but expected a Func", fi.TypeID, typ) - } - - // C doesn't have anonymous functions, but check just in case. - if fn.Name == "" { - return nil, fmt.Errorf("func with type ID %d doesn't have a name", fi.TypeID) - } - - return &funcInfo{ - fn, - asm.RawInstructionOffset(fi.InsnOff), - }, nil -} - -func newFuncInfos(bfis []bpfFuncInfo, ts types) ([]funcInfo, error) { - fis := make([]funcInfo, 0, len(bfis)) - for _, bfi := range bfis { - fi, err := newFuncInfo(bfi, ts) - if err != nil { - return nil, fmt.Errorf("offset %d: %w", bfi.InsnOff, err) - } - fis = append(fis, *fi) - } - sort.Slice(fis, func(i, j int) bool { - return fis[i].offset <= fis[j].offset - }) - return fis, nil -} - -// marshal into the BTF wire format. -func (fi *funcInfo) marshal(w io.Writer, typeID func(Type) (TypeID, error)) error { - id, err := typeID(fi.fn) - if err != nil { - return err - } - bfi := bpfFuncInfo{ - InsnOff: uint32(fi.offset), - TypeID: id, - } - return binary.Write(w, internal.NativeEndian, &bfi) -} - -// parseLineInfos parses a func_info sub-section within .BTF.ext ito a map of -// func infos indexed by section name. -func parseFuncInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map[string][]bpfFuncInfo, error) { - recordSize, err := parseExtInfoRecordSize(r, bo) - if err != nil { - return nil, err - } - - result := make(map[string][]bpfFuncInfo) - for { - secName, infoHeader, err := parseExtInfoSec(r, bo, strings) - if errors.Is(err, io.EOF) { - return result, nil - } - if err != nil { - return nil, err - } - - records, err := parseFuncInfoRecords(r, bo, recordSize, infoHeader.NumInfo) - if err != nil { - return nil, fmt.Errorf("section %v: %w", secName, err) - } - - result[secName] = records - } -} - -// parseFuncInfoRecords parses a stream of func_infos into a funcInfos. -// These records appear after a btf_ext_info_sec header in the func_info -// sub-section of .BTF.ext. -func parseFuncInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfFuncInfo, error) { - var out []bpfFuncInfo - var fi bpfFuncInfo - - if exp, got := FuncInfoSize, recordSize; exp != got { - // BTF blob's record size is longer than we know how to parse. - return nil, fmt.Errorf("expected FuncInfo record size %d, but BTF blob contains %d", exp, got) - } - - for i := uint32(0); i < recordNum; i++ { - if err := binary.Read(r, bo, &fi); err != nil { - return nil, fmt.Errorf("can't read function info: %v", err) - } - - if fi.InsnOff%asm.InstructionSize != 0 { - return nil, fmt.Errorf("offset %v is not aligned with instruction size", fi.InsnOff) - } - - // ELF tracks offset in bytes, the kernel expects raw BPF instructions. - // Convert as early as possible. - fi.InsnOff /= asm.InstructionSize - - out = append(out, fi) - } - - return out, nil -} - -var LineInfoSize = uint32(binary.Size(bpfLineInfo{})) - -// Line represents the location and contents of a single line of source -// code a BPF ELF was compiled from. -type Line struct { - fileName string - line string - lineNumber uint32 - lineColumn uint32 - - // TODO: We should get rid of the fields below, but for that we need to be - // able to write BTF. - - fileNameOff uint32 - lineOff uint32 -} - -func (li *Line) FileName() string { - return li.fileName -} - -func (li *Line) Line() string { - return li.line -} - -func (li *Line) LineNumber() uint32 { - return li.lineNumber -} - -func (li *Line) LineColumn() uint32 { - return li.lineColumn -} - -func (li *Line) String() string { - return li.line -} - -type lineInfo struct { - line *Line - offset asm.RawInstructionOffset -} - -// Constants for the format of bpfLineInfo.LineCol. -const ( - bpfLineShift = 10 - bpfLineMax = (1 << (32 - bpfLineShift)) - 1 - bpfColumnMax = (1 << bpfLineShift) - 1 -) - -type bpfLineInfo struct { - // Instruction offset of the line within the whole instruction stream, in instructions. - InsnOff uint32 - FileNameOff uint32 - LineOff uint32 - LineCol uint32 -} - -func newLineInfo(li bpfLineInfo, strings *stringTable) (*lineInfo, error) { - line, err := strings.Lookup(li.LineOff) - if err != nil { - return nil, fmt.Errorf("lookup of line: %w", err) - } - - fileName, err := strings.Lookup(li.FileNameOff) - if err != nil { - return nil, fmt.Errorf("lookup of filename: %w", err) - } - - lineNumber := li.LineCol >> bpfLineShift - lineColumn := li.LineCol & bpfColumnMax - - return &lineInfo{ - &Line{ - fileName, - line, - lineNumber, - lineColumn, - li.FileNameOff, - li.LineOff, - }, - asm.RawInstructionOffset(li.InsnOff), - }, nil -} - -func newLineInfos(blis []bpfLineInfo, strings *stringTable) ([]lineInfo, error) { - lis := make([]lineInfo, 0, len(blis)) - for _, bli := range blis { - li, err := newLineInfo(bli, strings) - if err != nil { - return nil, fmt.Errorf("offset %d: %w", bli.InsnOff, err) - } - lis = append(lis, *li) - } - sort.Slice(lis, func(i, j int) bool { - return lis[i].offset <= lis[j].offset - }) - return lis, nil -} - -// marshal writes the binary representation of the LineInfo to w. -func (li *lineInfo) marshal(w io.Writer) error { - line := li.line - if line.lineNumber > bpfLineMax { - return fmt.Errorf("line %d exceeds %d", line.lineNumber, bpfLineMax) - } - - if line.lineColumn > bpfColumnMax { - return fmt.Errorf("column %d exceeds %d", line.lineColumn, bpfColumnMax) - } - - bli := bpfLineInfo{ - uint32(li.offset), - line.fileNameOff, - line.lineOff, - (line.lineNumber << bpfLineShift) | line.lineColumn, - } - return binary.Write(w, internal.NativeEndian, &bli) -} - -// parseLineInfos parses a line_info sub-section within .BTF.ext ito a map of -// line infos indexed by section name. -func parseLineInfos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map[string][]bpfLineInfo, error) { - recordSize, err := parseExtInfoRecordSize(r, bo) - if err != nil { - return nil, err - } - - result := make(map[string][]bpfLineInfo) - for { - secName, infoHeader, err := parseExtInfoSec(r, bo, strings) - if errors.Is(err, io.EOF) { - return result, nil - } - if err != nil { - return nil, err - } - - records, err := parseLineInfoRecords(r, bo, recordSize, infoHeader.NumInfo) - if err != nil { - return nil, fmt.Errorf("section %v: %w", secName, err) - } - - result[secName] = records - } -} - -// parseLineInfoRecords parses a stream of line_infos into a lineInfos. -// These records appear after a btf_ext_info_sec header in the line_info -// sub-section of .BTF.ext. -func parseLineInfoRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfLineInfo, error) { - var out []bpfLineInfo - var li bpfLineInfo - - if exp, got := uint32(binary.Size(li)), recordSize; exp != got { - // BTF blob's record size is longer than we know how to parse. - return nil, fmt.Errorf("expected LineInfo record size %d, but BTF blob contains %d", exp, got) - } - - for i := uint32(0); i < recordNum; i++ { - if err := binary.Read(r, bo, &li); err != nil { - return nil, fmt.Errorf("can't read line info: %v", err) - } - - if li.InsnOff%asm.InstructionSize != 0 { - return nil, fmt.Errorf("offset %v is not aligned with instruction size", li.InsnOff) - } - - // ELF tracks offset in bytes, the kernel expects raw BPF instructions. - // Convert as early as possible. - li.InsnOff /= asm.InstructionSize - - out = append(out, li) - } - - return out, nil -} - -// bpfCORERelo matches the kernel's struct bpf_core_relo. -type bpfCORERelo struct { - InsnOff uint32 - TypeID TypeID - AccessStrOff uint32 - Kind coreKind -} - -type CORERelocation struct { - typ Type - accessor coreAccessor - kind coreKind -} - -func CORERelocationMetadata(ins *asm.Instruction) *CORERelocation { - relo, _ := ins.Metadata.Get(coreRelocationMeta{}).(*CORERelocation) - return relo -} - -type coreRelocationInfo struct { - relo *CORERelocation - offset asm.RawInstructionOffset -} - -func newRelocationInfo(relo bpfCORERelo, ts types, strings *stringTable) (*coreRelocationInfo, error) { - typ, err := ts.ByID(relo.TypeID) - if err != nil { - return nil, err - } - - accessorStr, err := strings.Lookup(relo.AccessStrOff) - if err != nil { - return nil, err - } - - accessor, err := parseCOREAccessor(accessorStr) - if err != nil { - return nil, fmt.Errorf("accessor %q: %s", accessorStr, err) - } - - return &coreRelocationInfo{ - &CORERelocation{ - typ, - accessor, - relo.Kind, - }, - asm.RawInstructionOffset(relo.InsnOff), - }, nil -} - -func newRelocationInfos(brs []bpfCORERelo, ts types, strings *stringTable) ([]coreRelocationInfo, error) { - rs := make([]coreRelocationInfo, 0, len(brs)) - for _, br := range brs { - relo, err := newRelocationInfo(br, ts, strings) - if err != nil { - return nil, fmt.Errorf("offset %d: %w", br.InsnOff, err) - } - rs = append(rs, *relo) - } - sort.Slice(rs, func(i, j int) bool { - return rs[i].offset < rs[j].offset - }) - return rs, nil -} - -var extInfoReloSize = binary.Size(bpfCORERelo{}) - -// parseCORERelos parses a core_relos sub-section within .BTF.ext ito a map of -// CO-RE relocations indexed by section name. -func parseCORERelos(r io.Reader, bo binary.ByteOrder, strings *stringTable) (map[string][]bpfCORERelo, error) { - recordSize, err := parseExtInfoRecordSize(r, bo) - if err != nil { - return nil, err - } - - if recordSize != uint32(extInfoReloSize) { - return nil, fmt.Errorf("expected record size %d, got %d", extInfoReloSize, recordSize) - } - - result := make(map[string][]bpfCORERelo) - for { - secName, infoHeader, err := parseExtInfoSec(r, bo, strings) - if errors.Is(err, io.EOF) { - return result, nil - } - if err != nil { - return nil, err - } - - records, err := parseCOREReloRecords(r, bo, recordSize, infoHeader.NumInfo) - if err != nil { - return nil, fmt.Errorf("section %v: %w", secName, err) - } - - result[secName] = records - } -} - -// parseCOREReloRecords parses a stream of CO-RE relocation entries into a -// coreRelos. These records appear after a btf_ext_info_sec header in the -// core_relos sub-section of .BTF.ext. -func parseCOREReloRecords(r io.Reader, bo binary.ByteOrder, recordSize uint32, recordNum uint32) ([]bpfCORERelo, error) { - var out []bpfCORERelo - - var relo bpfCORERelo - for i := uint32(0); i < recordNum; i++ { - if err := binary.Read(r, bo, &relo); err != nil { - return nil, fmt.Errorf("can't read CO-RE relocation: %v", err) - } - - if relo.InsnOff%asm.InstructionSize != 0 { - return nil, fmt.Errorf("offset %v is not aligned with instruction size", relo.InsnOff) - } - - // ELF tracks offset in bytes, the kernel expects raw BPF instructions. - // Convert as early as possible. - relo.InsnOff /= asm.InstructionSize - - out = append(out, relo) - } - - return out, nil -} diff --git a/vendor/github.com/cilium/ebpf/btf/format.go b/vendor/github.com/cilium/ebpf/btf/format.go deleted file mode 100644 index e7688a2a..00000000 --- a/vendor/github.com/cilium/ebpf/btf/format.go +++ /dev/null @@ -1,319 +0,0 @@ -package btf - -import ( - "errors" - "fmt" - "strings" -) - -var errNestedTooDeep = errors.New("nested too deep") - -// GoFormatter converts a Type to Go syntax. -// -// A zero GoFormatter is valid to use. -type GoFormatter struct { - w strings.Builder - - // Types present in this map are referred to using the given name if they - // are encountered when outputting another type. - Names map[Type]string - - // Identifier is called for each field of struct-like types. By default the - // field name is used as is. - Identifier func(string) string - - // EnumIdentifier is called for each element of an enum. By default the - // name of the enum type is concatenated with Identifier(element). - EnumIdentifier func(name, element string) string -} - -// TypeDeclaration generates a Go type declaration for a BTF type. -func (gf *GoFormatter) TypeDeclaration(name string, typ Type) (string, error) { - gf.w.Reset() - if err := gf.writeTypeDecl(name, typ); err != nil { - return "", err - } - return gf.w.String(), nil -} - -func (gf *GoFormatter) identifier(s string) string { - if gf.Identifier != nil { - return gf.Identifier(s) - } - - return s -} - -func (gf *GoFormatter) enumIdentifier(name, element string) string { - if gf.EnumIdentifier != nil { - return gf.EnumIdentifier(name, element) - } - - return name + gf.identifier(element) -} - -// writeTypeDecl outputs a declaration of the given type. -// -// It encodes https://golang.org/ref/spec#Type_declarations: -// -// type foo struct { bar uint32; } -// type bar int32 -func (gf *GoFormatter) writeTypeDecl(name string, typ Type) error { - if name == "" { - return fmt.Errorf("need a name for type %s", typ) - } - - switch v := skipQualifiers(typ).(type) { - case *Enum: - fmt.Fprintf(&gf.w, "type %s ", name) - switch v.Size { - case 1: - gf.w.WriteString("int8") - case 2: - gf.w.WriteString("int16") - case 4: - gf.w.WriteString("int32") - case 8: - gf.w.WriteString("int64") - default: - return fmt.Errorf("%s: invalid enum size %d", typ, v.Size) - } - - if len(v.Values) == 0 { - return nil - } - - gf.w.WriteString("; const ( ") - for _, ev := range v.Values { - id := gf.enumIdentifier(name, ev.Name) - fmt.Fprintf(&gf.w, "%s %s = %d; ", id, name, ev.Value) - } - gf.w.WriteString(")") - - return nil - - default: - fmt.Fprintf(&gf.w, "type %s ", name) - return gf.writeTypeLit(v, 0) - } -} - -// writeType outputs the name of a named type or a literal describing the type. -// -// It encodes https://golang.org/ref/spec#Types. -// -// foo (if foo is a named type) -// uint32 -func (gf *GoFormatter) writeType(typ Type, depth int) error { - typ = skipQualifiers(typ) - - name := gf.Names[typ] - if name != "" { - gf.w.WriteString(name) - return nil - } - - return gf.writeTypeLit(typ, depth) -} - -// writeTypeLit outputs a literal describing the type. -// -// The function ignores named types. -// -// It encodes https://golang.org/ref/spec#TypeLit. -// -// struct { bar uint32; } -// uint32 -func (gf *GoFormatter) writeTypeLit(typ Type, depth int) error { - depth++ - if depth > maxTypeDepth { - return errNestedTooDeep - } - - var err error - switch v := skipQualifiers(typ).(type) { - case *Int: - gf.writeIntLit(v) - - case *Enum: - gf.w.WriteString("int32") - - case *Typedef: - err = gf.writeType(v.Type, depth) - - case *Array: - fmt.Fprintf(&gf.w, "[%d]", v.Nelems) - err = gf.writeType(v.Type, depth) - - case *Struct: - err = gf.writeStructLit(v.Size, v.Members, depth) - - case *Union: - // Always choose the first member to represent the union in Go. - err = gf.writeStructLit(v.Size, v.Members[:1], depth) - - case *Datasec: - err = gf.writeDatasecLit(v, depth) - - default: - return fmt.Errorf("type %T: %w", v, ErrNotSupported) - } - - if err != nil { - return fmt.Errorf("%s: %w", typ, err) - } - - return nil -} - -func (gf *GoFormatter) writeIntLit(i *Int) { - // NB: Encoding.IsChar is ignored. - if i.Encoding.IsBool() && i.Size == 1 { - gf.w.WriteString("bool") - return - } - - bits := i.Size * 8 - if i.Encoding.IsSigned() { - fmt.Fprintf(&gf.w, "int%d", bits) - } else { - fmt.Fprintf(&gf.w, "uint%d", bits) - } -} - -func (gf *GoFormatter) writeStructLit(size uint32, members []Member, depth int) error { - gf.w.WriteString("struct { ") - - prevOffset := uint32(0) - skippedBitfield := false - for i, m := range members { - if m.BitfieldSize > 0 { - skippedBitfield = true - continue - } - - offset := m.Offset.Bytes() - if n := offset - prevOffset; skippedBitfield && n > 0 { - fmt.Fprintf(&gf.w, "_ [%d]byte /* unsupported bitfield */; ", n) - } else { - gf.writePadding(n) - } - - size, err := Sizeof(m.Type) - if err != nil { - return fmt.Errorf("field %d: %w", i, err) - } - prevOffset = offset + uint32(size) - - if err := gf.writeStructField(m, depth); err != nil { - return fmt.Errorf("field %d: %w", i, err) - } - } - - gf.writePadding(size - prevOffset) - gf.w.WriteString("}") - return nil -} - -func (gf *GoFormatter) writeStructField(m Member, depth int) error { - if m.BitfieldSize > 0 { - return fmt.Errorf("bitfields are not supported") - } - if m.Offset%8 != 0 { - return fmt.Errorf("unsupported offset %d", m.Offset) - } - - if m.Name == "" { - // Special case a nested anonymous union like - // struct foo { union { int bar; int baz }; } - // by replacing the whole union with its first member. - union, ok := m.Type.(*Union) - if !ok { - return fmt.Errorf("anonymous fields are not supported") - - } - - if len(union.Members) == 0 { - return errors.New("empty anonymous union") - } - - depth++ - if depth > maxTypeDepth { - return errNestedTooDeep - } - - m := union.Members[0] - size, err := Sizeof(m.Type) - if err != nil { - return err - } - - if err := gf.writeStructField(m, depth); err != nil { - return err - } - - gf.writePadding(union.Size - uint32(size)) - return nil - - } - - fmt.Fprintf(&gf.w, "%s ", gf.identifier(m.Name)) - - if err := gf.writeType(m.Type, depth); err != nil { - return err - } - - gf.w.WriteString("; ") - return nil -} - -func (gf *GoFormatter) writeDatasecLit(ds *Datasec, depth int) error { - gf.w.WriteString("struct { ") - - prevOffset := uint32(0) - for i, vsi := range ds.Vars { - v := vsi.Type.(*Var) - if v.Linkage != GlobalVar { - // Ignore static, extern, etc. for now. - continue - } - - if v.Name == "" { - return fmt.Errorf("variable %d: empty name", i) - } - - gf.writePadding(vsi.Offset - prevOffset) - prevOffset = vsi.Offset + vsi.Size - - fmt.Fprintf(&gf.w, "%s ", gf.identifier(v.Name)) - - if err := gf.writeType(v.Type, depth); err != nil { - return fmt.Errorf("variable %d: %w", i, err) - } - - gf.w.WriteString("; ") - } - - gf.writePadding(ds.Size - prevOffset) - gf.w.WriteString("}") - return nil -} - -func (gf *GoFormatter) writePadding(bytes uint32) { - if bytes > 0 { - fmt.Fprintf(&gf.w, "_ [%d]byte; ", bytes) - } -} - -func skipQualifiers(typ Type) Type { - result := typ - for depth := 0; depth <= maxTypeDepth; depth++ { - switch v := (result).(type) { - case qualifier: - result = v.qualify() - default: - return result - } - } - return &cycle{typ} -} diff --git a/vendor/github.com/cilium/ebpf/btf/handle.go b/vendor/github.com/cilium/ebpf/btf/handle.go deleted file mode 100644 index 128e9b35..00000000 --- a/vendor/github.com/cilium/ebpf/btf/handle.go +++ /dev/null @@ -1,121 +0,0 @@ -package btf - -import ( - "errors" - "fmt" - "os" - - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// HandleInfo describes a Handle. -type HandleInfo struct { - // ID of this handle in the kernel. The ID is only valid as long as the - // associated handle is kept alive. - ID ID - - // Name is an identifying name for the BTF, currently only used by the - // kernel. - Name string - - // IsKernel is true if the BTF originated with the kernel and not - // userspace. - IsKernel bool - - // Size of the raw BTF in bytes. - size uint32 -} - -func newHandleInfoFromFD(fd *sys.FD) (*HandleInfo, error) { - // We invoke the syscall once with a empty BTF and name buffers to get size - // information to allocate buffers. Then we invoke it a second time with - // buffers to receive the data. - var btfInfo sys.BtfInfo - if err := sys.ObjInfo(fd, &btfInfo); err != nil { - return nil, fmt.Errorf("get BTF info for fd %s: %w", fd, err) - } - - if btfInfo.NameLen > 0 { - // NameLen doesn't account for the terminating NUL. - btfInfo.NameLen++ - } - - // Don't pull raw BTF by default, since it may be quite large. - btfSize := btfInfo.BtfSize - btfInfo.BtfSize = 0 - - nameBuffer := make([]byte, btfInfo.NameLen) - btfInfo.Name, btfInfo.NameLen = sys.NewSlicePointerLen(nameBuffer) - if err := sys.ObjInfo(fd, &btfInfo); err != nil { - return nil, err - } - - return &HandleInfo{ - ID: ID(btfInfo.Id), - Name: unix.ByteSliceToString(nameBuffer), - IsKernel: btfInfo.KernelBtf != 0, - size: btfSize, - }, nil -} - -// IsModule returns true if the BTF is for the kernel itself. -func (i *HandleInfo) IsVmlinux() bool { - return i.IsKernel && i.Name == "vmlinux" -} - -// IsModule returns true if the BTF is for a kernel module. -func (i *HandleInfo) IsModule() bool { - return i.IsKernel && i.Name != "vmlinux" -} - -// HandleIterator allows enumerating BTF blobs loaded into the kernel. -type HandleIterator struct { - // The ID of the last retrieved handle. Only valid after a call to Next. - ID ID - err error -} - -// Next retrieves a handle for the next BTF blob. -// -// [Handle.Close] is called if *handle is non-nil to avoid leaking fds. -// -// Returns true if another BTF blob was found. Call [HandleIterator.Err] after -// the function returns false. -func (it *HandleIterator) Next(handle **Handle) bool { - if *handle != nil { - (*handle).Close() - *handle = nil - } - - id := it.ID - for { - attr := &sys.BtfGetNextIdAttr{Id: id} - err := sys.BtfGetNextId(attr) - if errors.Is(err, os.ErrNotExist) { - // There are no more BTF objects. - return false - } else if err != nil { - it.err = fmt.Errorf("get next BTF ID: %w", err) - return false - } - - id = attr.NextId - *handle, err = NewHandleFromID(id) - if errors.Is(err, os.ErrNotExist) { - // Try again with the next ID. - continue - } else if err != nil { - it.err = fmt.Errorf("retrieve handle for ID %d: %w", id, err) - return false - } - - it.ID = id - return true - } -} - -// Err returns an error if iteration failed for some reason. -func (it *HandleIterator) Err() error { - return it.err -} diff --git a/vendor/github.com/cilium/ebpf/btf/strings.go b/vendor/github.com/cilium/ebpf/btf/strings.go deleted file mode 100644 index 67626e0d..00000000 --- a/vendor/github.com/cilium/ebpf/btf/strings.go +++ /dev/null @@ -1,128 +0,0 @@ -package btf - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" -) - -type stringTable struct { - base *stringTable - offsets []uint32 - strings []string -} - -// sizedReader is implemented by bytes.Reader, io.SectionReader, strings.Reader, etc. -type sizedReader interface { - io.Reader - Size() int64 -} - -func readStringTable(r sizedReader, base *stringTable) (*stringTable, error) { - // When parsing split BTF's string table, the first entry offset is derived - // from the last entry offset of the base BTF. - firstStringOffset := uint32(0) - if base != nil { - idx := len(base.offsets) - 1 - firstStringOffset = base.offsets[idx] + uint32(len(base.strings[idx])) + 1 - } - - // Derived from vmlinux BTF. - const averageStringLength = 16 - - n := int(r.Size() / averageStringLength) - offsets := make([]uint32, 0, n) - strings := make([]string, 0, n) - - offset := firstStringOffset - scanner := bufio.NewScanner(r) - scanner.Split(splitNull) - for scanner.Scan() { - str := scanner.Text() - offsets = append(offsets, offset) - strings = append(strings, str) - offset += uint32(len(str)) + 1 - } - if err := scanner.Err(); err != nil { - return nil, err - } - - if len(strings) == 0 { - return nil, errors.New("string table is empty") - } - - if firstStringOffset == 0 && strings[0] != "" { - return nil, errors.New("first item in string table is non-empty") - } - - return &stringTable{base, offsets, strings}, nil -} - -func splitNull(data []byte, atEOF bool) (advance int, token []byte, err error) { - i := bytes.IndexByte(data, 0) - if i == -1 { - if atEOF && len(data) > 0 { - return 0, nil, errors.New("string table isn't null terminated") - } - return 0, nil, nil - } - - return i + 1, data[:i], nil -} - -func (st *stringTable) Lookup(offset uint32) (string, error) { - if st.base != nil && offset <= st.base.offsets[len(st.base.offsets)-1] { - return st.base.lookup(offset) - } - return st.lookup(offset) -} - -func (st *stringTable) lookup(offset uint32) (string, error) { - i := search(st.offsets, offset) - if i == len(st.offsets) || st.offsets[i] != offset { - return "", fmt.Errorf("offset %d isn't start of a string", offset) - } - - return st.strings[i], nil -} - -func (st *stringTable) Length() int { - last := len(st.offsets) - 1 - return int(st.offsets[last]) + len(st.strings[last]) + 1 -} - -func (st *stringTable) Marshal(w io.Writer) error { - for _, str := range st.strings { - _, err := io.WriteString(w, str) - if err != nil { - return err - } - _, err = w.Write([]byte{0}) - if err != nil { - return err - } - } - return nil -} - -// search is a copy of sort.Search specialised for uint32. -// -// Licensed under https://go.dev/LICENSE -func search(ints []uint32, needle uint32) int { - // Define f(-1) == false and f(n) == true. - // Invariant: f(i-1) == false, f(j) == true. - i, j := 0, len(ints) - for i < j { - h := int(uint(i+j) >> 1) // avoid overflow when computing h - // i ≤ h < j - if !(ints[h] >= needle) { - i = h + 1 // preserves f(i-1) == false - } else { - j = h // preserves f(j) == true - } - } - // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. - return i -} diff --git a/vendor/github.com/cilium/ebpf/btf/types.go b/vendor/github.com/cilium/ebpf/btf/types.go deleted file mode 100644 index 402a363c..00000000 --- a/vendor/github.com/cilium/ebpf/btf/types.go +++ /dev/null @@ -1,1212 +0,0 @@ -package btf - -import ( - "fmt" - "io" - "math" - "reflect" - "strings" - - "github.com/cilium/ebpf/asm" -) - -const maxTypeDepth = 32 - -// TypeID identifies a type in a BTF section. -type TypeID uint32 - -// Type represents a type described by BTF. -type Type interface { - // Type can be formatted using the %s and %v verbs. %s outputs only the - // identity of the type, without any detail. %v outputs additional detail. - // - // Use the '+' flag to include the address of the type. - // - // Use the width to specify how many levels of detail to output, for example - // %1v will output detail for the root type and a short description of its - // children. %2v would output details of the root type and its children - // as well as a short description of the grandchildren. - fmt.Formatter - - // Name of the type, empty for anonymous types and types that cannot - // carry a name, like Void and Pointer. - TypeName() string - - // Make a copy of the type, without copying Type members. - copy() Type - - // Enumerate all nested Types. Repeated calls must visit nested - // types in the same order. - walk(*typeDeque) -} - -var ( - _ Type = (*Int)(nil) - _ Type = (*Struct)(nil) - _ Type = (*Union)(nil) - _ Type = (*Enum)(nil) - _ Type = (*Fwd)(nil) - _ Type = (*Func)(nil) - _ Type = (*Typedef)(nil) - _ Type = (*Var)(nil) - _ Type = (*Datasec)(nil) - _ Type = (*Float)(nil) -) - -// types is a list of Type. -// -// The order determines the ID of a type. -type types []Type - -func (ts types) ByID(id TypeID) (Type, error) { - if int(id) > len(ts) { - return nil, fmt.Errorf("type ID %d: %w", id, ErrNotFound) - } - return ts[id], nil -} - -// Void is the unit type of BTF. -type Void struct{} - -func (v *Void) Format(fs fmt.State, verb rune) { formatType(fs, verb, v) } -func (v *Void) TypeName() string { return "" } -func (v *Void) size() uint32 { return 0 } -func (v *Void) copy() Type { return (*Void)(nil) } -func (v *Void) walk(*typeDeque) {} - -type IntEncoding byte - -const ( - Signed IntEncoding = 1 << iota - Char - Bool -) - -func (ie IntEncoding) IsSigned() bool { - return ie&Signed != 0 -} - -func (ie IntEncoding) IsChar() bool { - return ie&Char != 0 -} - -func (ie IntEncoding) IsBool() bool { - return ie&Bool != 0 -} - -func (ie IntEncoding) String() string { - switch { - case ie.IsChar() && ie.IsSigned(): - return "char" - case ie.IsChar() && !ie.IsSigned(): - return "uchar" - case ie.IsBool(): - return "bool" - case ie.IsSigned(): - return "signed" - default: - return "unsigned" - } -} - -// Int is an integer of a given length. -// -// See https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int -type Int struct { - Name string - - // The size of the integer in bytes. - Size uint32 - Encoding IntEncoding -} - -func (i *Int) Format(fs fmt.State, verb rune) { - formatType(fs, verb, i, i.Encoding, "size=", i.Size*8) -} - -func (i *Int) TypeName() string { return i.Name } -func (i *Int) size() uint32 { return i.Size } -func (i *Int) walk(*typeDeque) {} -func (i *Int) copy() Type { - cpy := *i - return &cpy -} - -// Pointer is a pointer to another type. -type Pointer struct { - Target Type -} - -func (p *Pointer) Format(fs fmt.State, verb rune) { - formatType(fs, verb, p, "target=", p.Target) -} - -func (p *Pointer) TypeName() string { return "" } -func (p *Pointer) size() uint32 { return 8 } -func (p *Pointer) walk(tdq *typeDeque) { tdq.push(&p.Target) } -func (p *Pointer) copy() Type { - cpy := *p - return &cpy -} - -// Array is an array with a fixed number of elements. -type Array struct { - Index Type - Type Type - Nelems uint32 -} - -func (arr *Array) Format(fs fmt.State, verb rune) { - formatType(fs, verb, arr, "index=", arr.Index, "type=", arr.Type, "n=", arr.Nelems) -} - -func (arr *Array) TypeName() string { return "" } - -func (arr *Array) walk(tdq *typeDeque) { - tdq.push(&arr.Index) - tdq.push(&arr.Type) -} - -func (arr *Array) copy() Type { - cpy := *arr - return &cpy -} - -// Struct is a compound type of consecutive members. -type Struct struct { - Name string - // The size of the struct including padding, in bytes - Size uint32 - Members []Member -} - -func (s *Struct) Format(fs fmt.State, verb rune) { - formatType(fs, verb, s, "fields=", len(s.Members)) -} - -func (s *Struct) TypeName() string { return s.Name } - -func (s *Struct) size() uint32 { return s.Size } - -func (s *Struct) walk(tdq *typeDeque) { - for i := range s.Members { - tdq.push(&s.Members[i].Type) - } -} - -func (s *Struct) copy() Type { - cpy := *s - cpy.Members = copyMembers(s.Members) - return &cpy -} - -func (s *Struct) members() []Member { - return s.Members -} - -// Union is a compound type where members occupy the same memory. -type Union struct { - Name string - // The size of the union including padding, in bytes. - Size uint32 - Members []Member -} - -func (u *Union) Format(fs fmt.State, verb rune) { - formatType(fs, verb, u, "fields=", len(u.Members)) -} - -func (u *Union) TypeName() string { return u.Name } - -func (u *Union) size() uint32 { return u.Size } - -func (u *Union) walk(tdq *typeDeque) { - for i := range u.Members { - tdq.push(&u.Members[i].Type) - } -} - -func (u *Union) copy() Type { - cpy := *u - cpy.Members = copyMembers(u.Members) - return &cpy -} - -func (u *Union) members() []Member { - return u.Members -} - -func copyMembers(orig []Member) []Member { - cpy := make([]Member, len(orig)) - copy(cpy, orig) - return cpy -} - -type composite interface { - members() []Member -} - -var ( - _ composite = (*Struct)(nil) - _ composite = (*Union)(nil) -) - -// A value in bits. -type Bits uint32 - -// Bytes converts a bit value into bytes. -func (b Bits) Bytes() uint32 { - return uint32(b / 8) -} - -// Member is part of a Struct or Union. -// -// It is not a valid Type. -type Member struct { - Name string - Type Type - Offset Bits - BitfieldSize Bits -} - -// Enum lists possible values. -type Enum struct { - Name string - // Size of the enum value in bytes. - Size uint32 - Values []EnumValue -} - -func (e *Enum) Format(fs fmt.State, verb rune) { - formatType(fs, verb, e, "size=", e.Size, "values=", len(e.Values)) -} - -func (e *Enum) TypeName() string { return e.Name } - -// EnumValue is part of an Enum -// -// Is is not a valid Type -type EnumValue struct { - Name string - Value int32 -} - -func (e *Enum) size() uint32 { return e.Size } -func (e *Enum) walk(*typeDeque) {} -func (e *Enum) copy() Type { - cpy := *e - cpy.Values = make([]EnumValue, len(e.Values)) - copy(cpy.Values, e.Values) - return &cpy -} - -// FwdKind is the type of forward declaration. -type FwdKind int - -// Valid types of forward declaration. -const ( - FwdStruct FwdKind = iota - FwdUnion -) - -func (fk FwdKind) String() string { - switch fk { - case FwdStruct: - return "struct" - case FwdUnion: - return "union" - default: - return fmt.Sprintf("%T(%d)", fk, int(fk)) - } -} - -// Fwd is a forward declaration of a Type. -type Fwd struct { - Name string - Kind FwdKind -} - -func (f *Fwd) Format(fs fmt.State, verb rune) { - formatType(fs, verb, f, f.Kind) -} - -func (f *Fwd) TypeName() string { return f.Name } - -func (f *Fwd) walk(*typeDeque) {} -func (f *Fwd) copy() Type { - cpy := *f - return &cpy -} - -// Typedef is an alias of a Type. -type Typedef struct { - Name string - Type Type -} - -func (td *Typedef) Format(fs fmt.State, verb rune) { - formatType(fs, verb, td, td.Type) -} - -func (td *Typedef) TypeName() string { return td.Name } - -func (td *Typedef) walk(tdq *typeDeque) { tdq.push(&td.Type) } -func (td *Typedef) copy() Type { - cpy := *td - return &cpy -} - -// Volatile is a qualifier. -type Volatile struct { - Type Type -} - -func (v *Volatile) Format(fs fmt.State, verb rune) { - formatType(fs, verb, v, v.Type) -} - -func (v *Volatile) TypeName() string { return "" } - -func (v *Volatile) qualify() Type { return v.Type } -func (v *Volatile) walk(tdq *typeDeque) { tdq.push(&v.Type) } -func (v *Volatile) copy() Type { - cpy := *v - return &cpy -} - -// Const is a qualifier. -type Const struct { - Type Type -} - -func (c *Const) Format(fs fmt.State, verb rune) { - formatType(fs, verb, c, c.Type) -} - -func (c *Const) TypeName() string { return "" } - -func (c *Const) qualify() Type { return c.Type } -func (c *Const) walk(tdq *typeDeque) { tdq.push(&c.Type) } -func (c *Const) copy() Type { - cpy := *c - return &cpy -} - -// Restrict is a qualifier. -type Restrict struct { - Type Type -} - -func (r *Restrict) Format(fs fmt.State, verb rune) { - formatType(fs, verb, r, r.Type) -} - -func (r *Restrict) TypeName() string { return "" } - -func (r *Restrict) qualify() Type { return r.Type } -func (r *Restrict) walk(tdq *typeDeque) { tdq.push(&r.Type) } -func (r *Restrict) copy() Type { - cpy := *r - return &cpy -} - -// Func is a function definition. -type Func struct { - Name string - Type Type - Linkage FuncLinkage -} - -func FuncMetadata(ins *asm.Instruction) *Func { - fn, _ := ins.Metadata.Get(funcInfoMeta{}).(*Func) - return fn -} - -func (f *Func) Format(fs fmt.State, verb rune) { - formatType(fs, verb, f, f.Linkage, "proto=", f.Type) -} - -func (f *Func) TypeName() string { return f.Name } - -func (f *Func) walk(tdq *typeDeque) { tdq.push(&f.Type) } -func (f *Func) copy() Type { - cpy := *f - return &cpy -} - -// FuncProto is a function declaration. -type FuncProto struct { - Return Type - Params []FuncParam -} - -func (fp *FuncProto) Format(fs fmt.State, verb rune) { - formatType(fs, verb, fp, "args=", len(fp.Params), "return=", fp.Return) -} - -func (fp *FuncProto) TypeName() string { return "" } - -func (fp *FuncProto) walk(tdq *typeDeque) { - tdq.push(&fp.Return) - for i := range fp.Params { - tdq.push(&fp.Params[i].Type) - } -} - -func (fp *FuncProto) copy() Type { - cpy := *fp - cpy.Params = make([]FuncParam, len(fp.Params)) - copy(cpy.Params, fp.Params) - return &cpy -} - -type FuncParam struct { - Name string - Type Type -} - -// Var is a global variable. -type Var struct { - Name string - Type Type - Linkage VarLinkage -} - -func (v *Var) Format(fs fmt.State, verb rune) { - formatType(fs, verb, v, v.Linkage) -} - -func (v *Var) TypeName() string { return v.Name } - -func (v *Var) walk(tdq *typeDeque) { tdq.push(&v.Type) } -func (v *Var) copy() Type { - cpy := *v - return &cpy -} - -// Datasec is a global program section containing data. -type Datasec struct { - Name string - Size uint32 - Vars []VarSecinfo -} - -func (ds *Datasec) Format(fs fmt.State, verb rune) { - formatType(fs, verb, ds) -} - -func (ds *Datasec) TypeName() string { return ds.Name } - -func (ds *Datasec) size() uint32 { return ds.Size } - -func (ds *Datasec) walk(tdq *typeDeque) { - for i := range ds.Vars { - tdq.push(&ds.Vars[i].Type) - } -} - -func (ds *Datasec) copy() Type { - cpy := *ds - cpy.Vars = make([]VarSecinfo, len(ds.Vars)) - copy(cpy.Vars, ds.Vars) - return &cpy -} - -// VarSecinfo describes variable in a Datasec. -// -// It is not a valid Type. -type VarSecinfo struct { - Type Type - Offset uint32 - Size uint32 -} - -// Float is a float of a given length. -type Float struct { - Name string - - // The size of the float in bytes. - Size uint32 -} - -func (f *Float) Format(fs fmt.State, verb rune) { - formatType(fs, verb, f, "size=", f.Size*8) -} - -func (f *Float) TypeName() string { return f.Name } -func (f *Float) size() uint32 { return f.Size } -func (f *Float) walk(*typeDeque) {} -func (f *Float) copy() Type { - cpy := *f - return &cpy -} - -// cycle is a type which had to be elided since it exceeded maxTypeDepth. -type cycle struct { - root Type -} - -func (c *cycle) ID() TypeID { return math.MaxUint32 } -func (c *cycle) Format(fs fmt.State, verb rune) { formatType(fs, verb, c, "root=", c.root) } -func (c *cycle) TypeName() string { return "" } -func (c *cycle) walk(*typeDeque) {} -func (c *cycle) copy() Type { - cpy := *c - return &cpy -} - -type sizer interface { - size() uint32 -} - -var ( - _ sizer = (*Int)(nil) - _ sizer = (*Pointer)(nil) - _ sizer = (*Struct)(nil) - _ sizer = (*Union)(nil) - _ sizer = (*Enum)(nil) - _ sizer = (*Datasec)(nil) -) - -type qualifier interface { - qualify() Type -} - -var ( - _ qualifier = (*Const)(nil) - _ qualifier = (*Restrict)(nil) - _ qualifier = (*Volatile)(nil) -) - -// Sizeof returns the size of a type in bytes. -// -// Returns an error if the size can't be computed. -func Sizeof(typ Type) (int, error) { - var ( - n = int64(1) - elem int64 - ) - - for i := 0; i < maxTypeDepth; i++ { - switch v := typ.(type) { - case *Array: - if n > 0 && int64(v.Nelems) > math.MaxInt64/n { - return 0, fmt.Errorf("type %s: overflow", typ) - } - - // Arrays may be of zero length, which allows - // n to be zero as well. - n *= int64(v.Nelems) - typ = v.Type - continue - - case sizer: - elem = int64(v.size()) - - case *Typedef: - typ = v.Type - continue - - case qualifier: - typ = v.qualify() - continue - - default: - return 0, fmt.Errorf("unsized type %T", typ) - } - - if n > 0 && elem > math.MaxInt64/n { - return 0, fmt.Errorf("type %s: overflow", typ) - } - - size := n * elem - if int64(int(size)) != size { - return 0, fmt.Errorf("type %s: overflow", typ) - } - - return int(size), nil - } - - return 0, fmt.Errorf("type %s: exceeded type depth", typ) -} - -// alignof returns the alignment of a type. -// -// Currently only supports the subset of types necessary for bitfield relocations. -func alignof(typ Type) (int, error) { - switch t := UnderlyingType(typ).(type) { - case *Enum: - return int(t.size()), nil - case *Int: - return int(t.Size), nil - default: - return 0, fmt.Errorf("can't calculate alignment of %T", t) - } -} - -// Transformer modifies a given Type and returns the result. -// -// For example, UnderlyingType removes any qualifiers or typedefs from a type. -// See the example on Copy for how to use a transform. -type Transformer func(Type) Type - -// Copy a Type recursively. -// -// typ may form a cycle. If transform is not nil, it is called with the -// to be copied type, and the returned value is copied instead. -func Copy(typ Type, transform Transformer) Type { - copies := make(copier) - copies.copy(&typ, transform) - return typ -} - -// copy a slice of Types recursively. -// -// See Copy for the semantics. -func copyTypes(types []Type, transform Transformer) []Type { - result := make([]Type, len(types)) - copy(result, types) - - copies := make(copier) - for i := range result { - copies.copy(&result[i], transform) - } - - return result -} - -type copier map[Type]Type - -func (c copier) copy(typ *Type, transform Transformer) { - var work typeDeque - for t := typ; t != nil; t = work.pop() { - // *t is the identity of the type. - if cpy := c[*t]; cpy != nil { - *t = cpy - continue - } - - var cpy Type - if transform != nil { - cpy = transform(*t).copy() - } else { - cpy = (*t).copy() - } - - c[*t] = cpy - *t = cpy - - // Mark any nested types for copying. - cpy.walk(&work) - } -} - -// typeDeque keeps track of pointers to types which still -// need to be visited. -type typeDeque struct { - types []*Type - read, write uint64 - mask uint64 -} - -func (dq *typeDeque) empty() bool { - return dq.read == dq.write -} - -// push adds a type to the stack. -func (dq *typeDeque) push(t *Type) { - if dq.write-dq.read < uint64(len(dq.types)) { - dq.types[dq.write&dq.mask] = t - dq.write++ - return - } - - new := len(dq.types) * 2 - if new == 0 { - new = 8 - } - - types := make([]*Type, new) - pivot := dq.read & dq.mask - n := copy(types, dq.types[pivot:]) - n += copy(types[n:], dq.types[:pivot]) - types[n] = t - - dq.types = types - dq.mask = uint64(new) - 1 - dq.read, dq.write = 0, uint64(n+1) -} - -// shift returns the first element or null. -func (dq *typeDeque) shift() *Type { - if dq.empty() { - return nil - } - - index := dq.read & dq.mask - t := dq.types[index] - dq.types[index] = nil - dq.read++ - return t -} - -// pop returns the last element or null. -func (dq *typeDeque) pop() *Type { - if dq.empty() { - return nil - } - - dq.write-- - index := dq.write & dq.mask - t := dq.types[index] - dq.types[index] = nil - return t -} - -// all returns all elements. -// -// The deque is empty after calling this method. -func (dq *typeDeque) all() []*Type { - length := dq.write - dq.read - types := make([]*Type, 0, length) - for t := dq.shift(); t != nil; t = dq.shift() { - types = append(types, t) - } - return types -} - -// inflateRawTypes takes a list of raw btf types linked via type IDs, and turns -// it into a graph of Types connected via pointers. -// -// If baseTypes are provided, then the raw types are -// considered to be of a split BTF (e.g., a kernel module). -// -// Returns a slice of types indexed by TypeID. Since BTF ignores compilation -// units, multiple types may share the same name. A Type may form a cyclic graph -// by pointing at itself. -func inflateRawTypes(rawTypes []rawType, baseTypes types, rawStrings *stringTable) ([]Type, error) { - types := make([]Type, 0, len(rawTypes)+1) // +1 for Void added to base types - - typeIDOffset := TypeID(1) // Void is TypeID(0), so the rest starts from TypeID(1) - - if baseTypes == nil { - // Void is defined to always be type ID 0, and is thus omitted from BTF. - types = append(types, (*Void)(nil)) - } else { - // For split BTF, the next ID is max base BTF type ID + 1 - typeIDOffset = TypeID(len(baseTypes)) - } - - type fixupDef struct { - id TypeID - typ *Type - } - - var fixups []fixupDef - fixup := func(id TypeID, typ *Type) { - if id < TypeID(len(baseTypes)) { - *typ = baseTypes[id] - return - } - - idx := id - if baseTypes != nil { - idx = id - TypeID(len(baseTypes)) - } - if idx < TypeID(len(types)) { - // We've already inflated this type, fix it up immediately. - *typ = types[idx] - return - } - fixups = append(fixups, fixupDef{id, typ}) - } - - type assertion struct { - typ *Type - want reflect.Type - } - - var assertions []assertion - assert := func(typ *Type, want reflect.Type) error { - if *typ != nil { - // The type has already been fixed up, check the type immediately. - if reflect.TypeOf(*typ) != want { - return fmt.Errorf("expected %s, got %T", want, *typ) - } - return nil - } - assertions = append(assertions, assertion{typ, want}) - return nil - } - - type bitfieldFixupDef struct { - id TypeID - m *Member - } - - var ( - legacyBitfields = make(map[TypeID][2]Bits) // offset, size - bitfieldFixups []bitfieldFixupDef - ) - convertMembers := func(raw []btfMember, kindFlag bool) ([]Member, error) { - // NB: The fixup below relies on pre-allocating this array to - // work, since otherwise append might re-allocate members. - members := make([]Member, 0, len(raw)) - for i, btfMember := range raw { - name, err := rawStrings.Lookup(btfMember.NameOff) - if err != nil { - return nil, fmt.Errorf("can't get name for member %d: %w", i, err) - } - - members = append(members, Member{ - Name: name, - Offset: Bits(btfMember.Offset), - }) - - m := &members[i] - fixup(raw[i].Type, &m.Type) - - if kindFlag { - m.BitfieldSize = Bits(btfMember.Offset >> 24) - m.Offset &= 0xffffff - // We ignore legacy bitfield definitions if the current composite - // is a new-style bitfield. This is kind of safe since offset and - // size on the type of the member must be zero if kindFlat is set - // according to spec. - continue - } - - // This may be a legacy bitfield, try to fix it up. - data, ok := legacyBitfields[raw[i].Type] - if ok { - // Bingo! - m.Offset += data[0] - m.BitfieldSize = data[1] - continue - } - - if m.Type != nil { - // We couldn't find a legacy bitfield, but we know that the member's - // type has already been inflated. Hence we know that it can't be - // a legacy bitfield and there is nothing left to do. - continue - } - - // We don't have fixup data, and the type we're pointing - // at hasn't been inflated yet. No choice but to defer - // the fixup. - bitfieldFixups = append(bitfieldFixups, bitfieldFixupDef{ - raw[i].Type, - m, - }) - } - return members, nil - } - - for i, raw := range rawTypes { - var ( - id = typeIDOffset + TypeID(i) - typ Type - ) - - name, err := rawStrings.Lookup(raw.NameOff) - if err != nil { - return nil, fmt.Errorf("get name for type id %d: %w", id, err) - } - - switch raw.Kind() { - case kindInt: - size := raw.Size() - bi := raw.data.(*btfInt) - if bi.Offset() > 0 || bi.Bits().Bytes() != size { - legacyBitfields[id] = [2]Bits{bi.Offset(), bi.Bits()} - } - typ = &Int{name, raw.Size(), bi.Encoding()} - - case kindPointer: - ptr := &Pointer{nil} - fixup(raw.Type(), &ptr.Target) - typ = ptr - - case kindArray: - btfArr := raw.data.(*btfArray) - arr := &Array{nil, nil, btfArr.Nelems} - fixup(btfArr.IndexType, &arr.Index) - fixup(btfArr.Type, &arr.Type) - typ = arr - - case kindStruct: - members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) - if err != nil { - return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err) - } - typ = &Struct{name, raw.Size(), members} - - case kindUnion: - members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag()) - if err != nil { - return nil, fmt.Errorf("union %s (id %d): %w", name, id, err) - } - typ = &Union{name, raw.Size(), members} - - case kindEnum: - rawvals := raw.data.([]btfEnum) - vals := make([]EnumValue, 0, len(rawvals)) - for i, btfVal := range rawvals { - name, err := rawStrings.Lookup(btfVal.NameOff) - if err != nil { - return nil, fmt.Errorf("get name for enum value %d: %s", i, err) - } - vals = append(vals, EnumValue{ - Name: name, - Value: btfVal.Val, - }) - } - typ = &Enum{name, raw.Size(), vals} - - case kindForward: - if raw.KindFlag() { - typ = &Fwd{name, FwdUnion} - } else { - typ = &Fwd{name, FwdStruct} - } - - case kindTypedef: - typedef := &Typedef{name, nil} - fixup(raw.Type(), &typedef.Type) - typ = typedef - - case kindVolatile: - volatile := &Volatile{nil} - fixup(raw.Type(), &volatile.Type) - typ = volatile - - case kindConst: - cnst := &Const{nil} - fixup(raw.Type(), &cnst.Type) - typ = cnst - - case kindRestrict: - restrict := &Restrict{nil} - fixup(raw.Type(), &restrict.Type) - typ = restrict - - case kindFunc: - fn := &Func{name, nil, raw.Linkage()} - fixup(raw.Type(), &fn.Type) - if err := assert(&fn.Type, reflect.TypeOf((*FuncProto)(nil))); err != nil { - return nil, err - } - typ = fn - - case kindFuncProto: - rawparams := raw.data.([]btfParam) - params := make([]FuncParam, 0, len(rawparams)) - for i, param := range rawparams { - name, err := rawStrings.Lookup(param.NameOff) - if err != nil { - return nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err) - } - params = append(params, FuncParam{ - Name: name, - }) - } - for i := range params { - fixup(rawparams[i].Type, ¶ms[i].Type) - } - - fp := &FuncProto{nil, params} - fixup(raw.Type(), &fp.Return) - typ = fp - - case kindVar: - variable := raw.data.(*btfVariable) - v := &Var{name, nil, VarLinkage(variable.Linkage)} - fixup(raw.Type(), &v.Type) - typ = v - - case kindDatasec: - btfVars := raw.data.([]btfVarSecinfo) - vars := make([]VarSecinfo, 0, len(btfVars)) - for _, btfVar := range btfVars { - vars = append(vars, VarSecinfo{ - Offset: btfVar.Offset, - Size: btfVar.Size, - }) - } - for i := range vars { - fixup(btfVars[i].Type, &vars[i].Type) - if err := assert(&vars[i].Type, reflect.TypeOf((*Var)(nil))); err != nil { - return nil, err - } - } - typ = &Datasec{name, raw.SizeType, vars} - - case kindFloat: - typ = &Float{name, raw.Size()} - - default: - return nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind()) - } - - types = append(types, typ) - } - - for _, fixup := range fixups { - i := int(fixup.id) - if i >= len(types)+len(baseTypes) { - return nil, fmt.Errorf("reference to invalid type id: %d", fixup.id) - } - if i < len(baseTypes) { - return nil, fmt.Errorf("fixup for base type id %d is not expected", i) - } - - *fixup.typ = types[i-len(baseTypes)] - } - - for _, bitfieldFixup := range bitfieldFixups { - if bitfieldFixup.id < TypeID(len(baseTypes)) { - return nil, fmt.Errorf("bitfield fixup from split to base types is not expected") - } - - data, ok := legacyBitfields[bitfieldFixup.id] - if ok { - // This is indeed a legacy bitfield, fix it up. - bitfieldFixup.m.Offset += data[0] - bitfieldFixup.m.BitfieldSize = data[1] - } - } - - for _, assertion := range assertions { - if reflect.TypeOf(*assertion.typ) != assertion.want { - return nil, fmt.Errorf("expected %s, got %T", assertion.want, *assertion.typ) - } - } - - return types, nil -} - -// essentialName represents the name of a BTF type stripped of any flavor -// suffixes after a ___ delimiter. -type essentialName string - -// newEssentialName returns name without a ___ suffix. -// -// CO-RE has the concept of 'struct flavors', which are used to deal with -// changes in kernel data structures. Anything after three underscores -// in a type name is ignored for the purpose of finding a candidate type -// in the kernel's BTF. -func newEssentialName(name string) essentialName { - if name == "" { - return "" - } - lastIdx := strings.LastIndex(name, "___") - if lastIdx > 0 { - return essentialName(name[:lastIdx]) - } - return essentialName(name) -} - -// UnderlyingType skips qualifiers and Typedefs. -func UnderlyingType(typ Type) Type { - result := typ - for depth := 0; depth <= maxTypeDepth; depth++ { - switch v := (result).(type) { - case qualifier: - result = v.qualify() - case *Typedef: - result = v.Type - default: - return result - } - } - return &cycle{typ} -} - -type formatState struct { - fmt.State - depth int -} - -// formattableType is a subset of Type, to ease unit testing of formatType. -type formattableType interface { - fmt.Formatter - TypeName() string -} - -// formatType formats a type in a canonical form. -// -// Handles cyclical types by only printing cycles up to a certain depth. Elements -// in extra are separated by spaces unless the preceding element is a string -// ending in '='. -func formatType(f fmt.State, verb rune, t formattableType, extra ...interface{}) { - if verb != 'v' && verb != 's' { - fmt.Fprintf(f, "{UNRECOGNIZED: %c}", verb) - return - } - - // This is the same as %T, but elides the package name. Assumes that - // formattableType is implemented by a pointer receiver. - goTypeName := reflect.TypeOf(t).Elem().Name() - _, _ = io.WriteString(f, goTypeName) - - if name := t.TypeName(); name != "" { - // Output BTF type name if present. - fmt.Fprintf(f, ":%q", name) - } - - if f.Flag('+') { - // Output address if requested. - fmt.Fprintf(f, ":%#p", t) - } - - if verb == 's' { - // %s omits details. - return - } - - var depth int - if ps, ok := f.(*formatState); ok { - depth = ps.depth - f = ps.State - } - - maxDepth, ok := f.Width() - if !ok { - maxDepth = 0 - } - - if depth > maxDepth { - // We've reached the maximum depth. This avoids infinite recursion even - // for cyclical types. - return - } - - if len(extra) == 0 { - return - } - - wantSpace := false - _, _ = io.WriteString(f, "[") - for _, arg := range extra { - if wantSpace { - _, _ = io.WriteString(f, " ") - } - - switch v := arg.(type) { - case string: - _, _ = io.WriteString(f, v) - wantSpace = len(v) > 0 && v[len(v)-1] != '=' - continue - - case formattableType: - v.Format(&formatState{f, depth + 1}, verb) - - default: - fmt.Fprint(f, arg) - } - - wantSpace = true - } - _, _ = io.WriteString(f, "]") -} diff --git a/vendor/github.com/cilium/ebpf/collection.go b/vendor/github.com/cilium/ebpf/collection.go deleted file mode 100644 index 8c2ddc38..00000000 --- a/vendor/github.com/cilium/ebpf/collection.go +++ /dev/null @@ -1,772 +0,0 @@ -package ebpf - -import ( - "encoding/binary" - "errors" - "fmt" - "reflect" - "strings" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/btf" -) - -// CollectionOptions control loading a collection into the kernel. -// -// Maps and Programs are passed to NewMapWithOptions and NewProgramsWithOptions. -type CollectionOptions struct { - Maps MapOptions - Programs ProgramOptions - - // MapReplacements takes a set of Maps that will be used instead of - // creating new ones when loading the CollectionSpec. - // - // For each given Map, there must be a corresponding MapSpec in - // CollectionSpec.Maps, and its type, key/value size, max entries and flags - // must match the values of the MapSpec. - // - // The given Maps are Clone()d before being used in the Collection, so the - // caller can Close() them freely when they are no longer needed. - MapReplacements map[string]*Map -} - -// CollectionSpec describes a collection. -type CollectionSpec struct { - Maps map[string]*MapSpec - Programs map[string]*ProgramSpec - - // Types holds type information about Maps and Programs. - // Modifications to Types are currently undefined behaviour. - Types *btf.Spec - - // ByteOrder specifies whether the ELF was compiled for - // big-endian or little-endian architectures. - ByteOrder binary.ByteOrder -} - -// Copy returns a recursive copy of the spec. -func (cs *CollectionSpec) Copy() *CollectionSpec { - if cs == nil { - return nil - } - - cpy := CollectionSpec{ - Maps: make(map[string]*MapSpec, len(cs.Maps)), - Programs: make(map[string]*ProgramSpec, len(cs.Programs)), - ByteOrder: cs.ByteOrder, - Types: cs.Types, - } - - for name, spec := range cs.Maps { - cpy.Maps[name] = spec.Copy() - } - - for name, spec := range cs.Programs { - cpy.Programs[name] = spec.Copy() - } - - return &cpy -} - -// RewriteMaps replaces all references to specific maps. -// -// Use this function to use pre-existing maps instead of creating new ones -// when calling NewCollection. Any named maps are removed from CollectionSpec.Maps. -// -// Returns an error if a named map isn't used in at least one program. -// -// Deprecated: Pass CollectionOptions.MapReplacements when loading the Collection -// instead. -func (cs *CollectionSpec) RewriteMaps(maps map[string]*Map) error { - for symbol, m := range maps { - // have we seen a program that uses this symbol / map - seen := false - for progName, progSpec := range cs.Programs { - err := progSpec.Instructions.AssociateMap(symbol, m) - - switch { - case err == nil: - seen = true - - case errors.Is(err, asm.ErrUnreferencedSymbol): - // Not all programs need to use the map - - default: - return fmt.Errorf("program %s: %w", progName, err) - } - } - - if !seen { - return fmt.Errorf("map %s not referenced by any programs", symbol) - } - - // Prevent NewCollection from creating rewritten maps - delete(cs.Maps, symbol) - } - - return nil -} - -// RewriteConstants replaces the value of multiple constants. -// -// The constant must be defined like so in the C program: -// -// volatile const type foobar; -// volatile const type foobar = default; -// -// Replacement values must be of the same length as the C sizeof(type). -// If necessary, they are marshalled according to the same rules as -// map values. -// -// From Linux 5.5 the verifier will use constants to eliminate dead code. -// -// Returns an error if a constant doesn't exist. -func (cs *CollectionSpec) RewriteConstants(consts map[string]interface{}) error { - replaced := make(map[string]bool) - - for name, spec := range cs.Maps { - if !strings.HasPrefix(name, ".rodata") { - continue - } - - b, ds, err := spec.dataSection() - if errors.Is(err, errMapNoBTFValue) { - // Data sections without a BTF Datasec are valid, but don't support - // constant replacements. - continue - } - if err != nil { - return fmt.Errorf("map %s: %w", name, err) - } - - // MapSpec.Copy() performs a shallow copy. Fully copy the byte slice - // to avoid any changes affecting other copies of the MapSpec. - cpy := make([]byte, len(b)) - copy(cpy, b) - - for _, v := range ds.Vars { - vname := v.Type.TypeName() - replacement, ok := consts[vname] - if !ok { - continue - } - - if replaced[vname] { - return fmt.Errorf("section %s: duplicate variable %s", name, vname) - } - - if int(v.Offset+v.Size) > len(cpy) { - return fmt.Errorf("section %s: offset %d(+%d) for variable %s is out of bounds", name, v.Offset, v.Size, vname) - } - - b, err := marshalBytes(replacement, int(v.Size)) - if err != nil { - return fmt.Errorf("marshaling constant replacement %s: %w", vname, err) - } - - copy(cpy[v.Offset:v.Offset+v.Size], b) - - replaced[vname] = true - } - - spec.Contents[0] = MapKV{Key: uint32(0), Value: cpy} - } - - var missing []string - for c := range consts { - if !replaced[c] { - missing = append(missing, c) - } - } - - if len(missing) != 0 { - return fmt.Errorf("spec is missing one or more constants: %s", strings.Join(missing, ",")) - } - - return nil -} - -// Assign the contents of a CollectionSpec to a struct. -// -// This function is a shortcut to manually checking the presence -// of maps and programs in a CollectionSpec. Consider using bpf2go -// if this sounds useful. -// -// 'to' must be a pointer to a struct. A field of the -// struct is updated with values from Programs or Maps if it -// has an `ebpf` tag and its type is *ProgramSpec or *MapSpec. -// The tag's value specifies the name of the program or map as -// found in the CollectionSpec. -// -// struct { -// Foo *ebpf.ProgramSpec `ebpf:"xdp_foo"` -// Bar *ebpf.MapSpec `ebpf:"bar_map"` -// Ignored int -// } -// -// Returns an error if any of the eBPF objects can't be found, or -// if the same MapSpec or ProgramSpec is assigned multiple times. -func (cs *CollectionSpec) Assign(to interface{}) error { - // Assign() only supports assigning ProgramSpecs and MapSpecs, - // so doesn't load any resources into the kernel. - getValue := func(typ reflect.Type, name string) (interface{}, error) { - switch typ { - - case reflect.TypeOf((*ProgramSpec)(nil)): - if p := cs.Programs[name]; p != nil { - return p, nil - } - return nil, fmt.Errorf("missing program %q", name) - - case reflect.TypeOf((*MapSpec)(nil)): - if m := cs.Maps[name]; m != nil { - return m, nil - } - return nil, fmt.Errorf("missing map %q", name) - - default: - return nil, fmt.Errorf("unsupported type %s", typ) - } - } - - return assignValues(to, getValue) -} - -// LoadAndAssign loads Maps and Programs into the kernel and assigns them -// to a struct. -// -// Omitting Map/Program.Close() during application shutdown is an error. -// See the package documentation for details around Map and Program lifecycle. -// -// This function is a shortcut to manually checking the presence -// of maps and programs in a CollectionSpec. Consider using bpf2go -// if this sounds useful. -// -// 'to' must be a pointer to a struct. A field of the struct is updated with -// a Program or Map if it has an `ebpf` tag and its type is *Program or *Map. -// The tag's value specifies the name of the program or map as found in the -// CollectionSpec. Before updating the struct, the requested objects and their -// dependent resources are loaded into the kernel and populated with values if -// specified. -// -// struct { -// Foo *ebpf.Program `ebpf:"xdp_foo"` -// Bar *ebpf.Map `ebpf:"bar_map"` -// Ignored int -// } -// -// opts may be nil. -// -// Returns an error if any of the fields can't be found, or -// if the same Map or Program is assigned multiple times. -func (cs *CollectionSpec) LoadAndAssign(to interface{}, opts *CollectionOptions) error { - loader, err := newCollectionLoader(cs, opts) - if err != nil { - return err - } - defer loader.close() - - // Support assigning Programs and Maps, lazy-loading the required objects. - assignedMaps := make(map[string]bool) - assignedProgs := make(map[string]bool) - - getValue := func(typ reflect.Type, name string) (interface{}, error) { - switch typ { - - case reflect.TypeOf((*Program)(nil)): - assignedProgs[name] = true - return loader.loadProgram(name) - - case reflect.TypeOf((*Map)(nil)): - assignedMaps[name] = true - return loader.loadMap(name) - - default: - return nil, fmt.Errorf("unsupported type %s", typ) - } - } - - // Load the Maps and Programs requested by the annotated struct. - if err := assignValues(to, getValue); err != nil { - return err - } - - // Populate the requested maps. Has a chance of lazy-loading other dependent maps. - if err := loader.populateMaps(); err != nil { - return err - } - - // Evaluate the loader's objects after all (lazy)loading has taken place. - for n, m := range loader.maps { - switch m.typ { - case ProgramArray: - // Require all lazy-loaded ProgramArrays to be assigned to the given object. - // The kernel empties a ProgramArray once the last user space reference - // to it closes, which leads to failed tail calls. Combined with the library - // closing map fds via GC finalizers this can lead to surprising behaviour. - // Only allow unassigned ProgramArrays when the library hasn't pre-populated - // any entries from static value declarations. At this point, we know the map - // is empty and there's no way for the caller to interact with the map going - // forward. - if !assignedMaps[n] && len(cs.Maps[n].Contents) > 0 { - return fmt.Errorf("ProgramArray %s must be assigned to prevent missed tail calls", n) - } - } - } - - // Prevent loader.cleanup() from closing assigned Maps and Programs. - for m := range assignedMaps { - delete(loader.maps, m) - } - for p := range assignedProgs { - delete(loader.programs, p) - } - - return nil -} - -// Collection is a collection of Programs and Maps associated -// with their symbols -type Collection struct { - Programs map[string]*Program - Maps map[string]*Map -} - -// NewCollection creates a Collection from the given spec, creating and -// loading its declared resources into the kernel. -// -// Omitting Collection.Close() during application shutdown is an error. -// See the package documentation for details around Map and Program lifecycle. -func NewCollection(spec *CollectionSpec) (*Collection, error) { - return NewCollectionWithOptions(spec, CollectionOptions{}) -} - -// NewCollectionWithOptions creates a Collection from the given spec using -// options, creating and loading its declared resources into the kernel. -// -// Omitting Collection.Close() during application shutdown is an error. -// See the package documentation for details around Map and Program lifecycle. -func NewCollectionWithOptions(spec *CollectionSpec, opts CollectionOptions) (*Collection, error) { - loader, err := newCollectionLoader(spec, &opts) - if err != nil { - return nil, err - } - defer loader.close() - - // Create maps first, as their fds need to be linked into programs. - for mapName := range spec.Maps { - if _, err := loader.loadMap(mapName); err != nil { - return nil, err - } - } - - for progName, prog := range spec.Programs { - if prog.Type == UnspecifiedProgram { - continue - } - - if _, err := loader.loadProgram(progName); err != nil { - return nil, err - } - } - - // Maps can contain Program and Map stubs, so populate them after - // all Maps and Programs have been successfully loaded. - if err := loader.populateMaps(); err != nil { - return nil, err - } - - // Prevent loader.cleanup from closing maps and programs. - maps, progs := loader.maps, loader.programs - loader.maps, loader.programs = nil, nil - - return &Collection{ - progs, - maps, - }, nil -} - -type handleCache struct { - btfHandles map[*btf.Spec]*btf.Handle -} - -func newHandleCache() *handleCache { - return &handleCache{ - btfHandles: make(map[*btf.Spec]*btf.Handle), - } -} - -func (hc handleCache) btfHandle(spec *btf.Spec) (*btf.Handle, error) { - if hc.btfHandles[spec] != nil { - return hc.btfHandles[spec], nil - } - - handle, err := btf.NewHandle(spec) - if err != nil { - return nil, err - } - - hc.btfHandles[spec] = handle - return handle, nil -} - -func (hc handleCache) close() { - for _, handle := range hc.btfHandles { - handle.Close() - } -} - -type collectionLoader struct { - coll *CollectionSpec - opts *CollectionOptions - maps map[string]*Map - programs map[string]*Program - handles *handleCache -} - -func newCollectionLoader(coll *CollectionSpec, opts *CollectionOptions) (*collectionLoader, error) { - if opts == nil { - opts = &CollectionOptions{} - } - - // Check for existing MapSpecs in the CollectionSpec for all provided replacement maps. - for name, m := range opts.MapReplacements { - spec, ok := coll.Maps[name] - if !ok { - return nil, fmt.Errorf("replacement map %s not found in CollectionSpec", name) - } - - if err := spec.checkCompatibility(m); err != nil { - return nil, fmt.Errorf("using replacement map %s: %w", spec.Name, err) - } - } - - return &collectionLoader{ - coll, - opts, - make(map[string]*Map), - make(map[string]*Program), - newHandleCache(), - }, nil -} - -// close all resources left over in the collectionLoader. -func (cl *collectionLoader) close() { - cl.handles.close() - for _, m := range cl.maps { - m.Close() - } - for _, p := range cl.programs { - p.Close() - } -} - -func (cl *collectionLoader) loadMap(mapName string) (*Map, error) { - if m := cl.maps[mapName]; m != nil { - return m, nil - } - - mapSpec := cl.coll.Maps[mapName] - if mapSpec == nil { - return nil, fmt.Errorf("missing map %s", mapName) - } - - if mapSpec.BTF != nil && cl.coll.Types != mapSpec.BTF { - return nil, fmt.Errorf("map %s: BTF doesn't match collection", mapName) - } - - if replaceMap, ok := cl.opts.MapReplacements[mapName]; ok { - // Clone the map to avoid closing user's map later on. - m, err := replaceMap.Clone() - if err != nil { - return nil, err - } - - cl.maps[mapName] = m - return m, nil - } - - m, err := newMapWithOptions(mapSpec, cl.opts.Maps, cl.handles) - if err != nil { - return nil, fmt.Errorf("map %s: %w", mapName, err) - } - - cl.maps[mapName] = m - return m, nil -} - -func (cl *collectionLoader) loadProgram(progName string) (*Program, error) { - if prog := cl.programs[progName]; prog != nil { - return prog, nil - } - - progSpec := cl.coll.Programs[progName] - if progSpec == nil { - return nil, fmt.Errorf("unknown program %s", progName) - } - - // Bail out early if we know the kernel is going to reject the program. - // This skips loading map dependencies, saving some cleanup work later. - if progSpec.Type == UnspecifiedProgram { - return nil, fmt.Errorf("cannot load program %s: program type is unspecified", progName) - } - - if progSpec.BTF != nil && cl.coll.Types != progSpec.BTF { - return nil, fmt.Errorf("program %s: BTF doesn't match collection", progName) - } - - progSpec = progSpec.Copy() - - // Rewrite any reference to a valid map in the program's instructions, - // which includes all of its dependencies. - for i := range progSpec.Instructions { - ins := &progSpec.Instructions[i] - - if !ins.IsLoadFromMap() || ins.Reference() == "" { - continue - } - - // Don't overwrite map loads containing non-zero map fd's, - // they can be manually included by the caller. - // Map FDs/IDs are placed in the lower 32 bits of Constant. - if int32(ins.Constant) > 0 { - continue - } - - m, err := cl.loadMap(ins.Reference()) - if err != nil { - return nil, fmt.Errorf("program %s: %w", progName, err) - } - - if err := ins.AssociateMap(m); err != nil { - return nil, fmt.Errorf("program %s: map %s: %w", progName, ins.Reference(), err) - } - } - - prog, err := newProgramWithOptions(progSpec, cl.opts.Programs, cl.handles) - if err != nil { - return nil, fmt.Errorf("program %s: %w", progName, err) - } - - cl.programs[progName] = prog - return prog, nil -} - -func (cl *collectionLoader) populateMaps() error { - for mapName, m := range cl.maps { - mapSpec, ok := cl.coll.Maps[mapName] - if !ok { - return fmt.Errorf("missing map spec %s", mapName) - } - - mapSpec = mapSpec.Copy() - - // MapSpecs that refer to inner maps or programs within the same - // CollectionSpec do so using strings. These strings are used as the key - // to look up the respective object in the Maps or Programs fields. - // Resolve those references to actual Map or Program resources that - // have been loaded into the kernel. - for i, kv := range mapSpec.Contents { - if objName, ok := kv.Value.(string); ok { - switch mapSpec.Type { - case ProgramArray: - // loadProgram is idempotent and could return an existing Program. - prog, err := cl.loadProgram(objName) - if err != nil { - return fmt.Errorf("loading program %s, for map %s: %w", objName, mapName, err) - } - mapSpec.Contents[i] = MapKV{kv.Key, prog} - - case ArrayOfMaps, HashOfMaps: - // loadMap is idempotent and could return an existing Map. - innerMap, err := cl.loadMap(objName) - if err != nil { - return fmt.Errorf("loading inner map %s, for map %s: %w", objName, mapName, err) - } - mapSpec.Contents[i] = MapKV{kv.Key, innerMap} - } - } - } - - // Populate and freeze the map if specified. - if err := m.finalize(mapSpec); err != nil { - return fmt.Errorf("populating map %s: %w", mapName, err) - } - } - - return nil -} - -// LoadCollection reads an object file and creates and loads its declared -// resources into the kernel. -// -// Omitting Collection.Close() during application shutdown is an error. -// See the package documentation for details around Map and Program lifecycle. -func LoadCollection(file string) (*Collection, error) { - spec, err := LoadCollectionSpec(file) - if err != nil { - return nil, err - } - return NewCollection(spec) -} - -// Close frees all maps and programs associated with the collection. -// -// The collection mustn't be used afterwards. -func (coll *Collection) Close() { - for _, prog := range coll.Programs { - prog.Close() - } - for _, m := range coll.Maps { - m.Close() - } -} - -// DetachMap removes the named map from the Collection. -// -// This means that a later call to Close() will not affect this map. -// -// Returns nil if no map of that name exists. -func (coll *Collection) DetachMap(name string) *Map { - m := coll.Maps[name] - delete(coll.Maps, name) - return m -} - -// DetachProgram removes the named program from the Collection. -// -// This means that a later call to Close() will not affect this program. -// -// Returns nil if no program of that name exists. -func (coll *Collection) DetachProgram(name string) *Program { - p := coll.Programs[name] - delete(coll.Programs, name) - return p -} - -// structField represents a struct field containing the ebpf struct tag. -type structField struct { - reflect.StructField - value reflect.Value -} - -// ebpfFields extracts field names tagged with 'ebpf' from a struct type. -// Keep track of visited types to avoid infinite recursion. -func ebpfFields(structVal reflect.Value, visited map[reflect.Type]bool) ([]structField, error) { - if visited == nil { - visited = make(map[reflect.Type]bool) - } - - structType := structVal.Type() - if structType.Kind() != reflect.Struct { - return nil, fmt.Errorf("%s is not a struct", structType) - } - - if visited[structType] { - return nil, fmt.Errorf("recursion on type %s", structType) - } - - fields := make([]structField, 0, structType.NumField()) - for i := 0; i < structType.NumField(); i++ { - field := structField{structType.Field(i), structVal.Field(i)} - - // If the field is tagged, gather it and move on. - name := field.Tag.Get("ebpf") - if name != "" { - fields = append(fields, field) - continue - } - - // If the field does not have an ebpf tag, but is a struct or a pointer - // to a struct, attempt to gather its fields as well. - var v reflect.Value - switch field.Type.Kind() { - case reflect.Ptr: - if field.Type.Elem().Kind() != reflect.Struct { - continue - } - - if field.value.IsNil() { - return nil, fmt.Errorf("nil pointer to %s", structType) - } - - // Obtain the destination type of the pointer. - v = field.value.Elem() - - case reflect.Struct: - // Reference the value's type directly. - v = field.value - - default: - continue - } - - inner, err := ebpfFields(v, visited) - if err != nil { - return nil, fmt.Errorf("field %s: %w", field.Name, err) - } - - fields = append(fields, inner...) - } - - return fields, nil -} - -// assignValues attempts to populate all fields of 'to' tagged with 'ebpf'. -// -// getValue is called for every tagged field of 'to' and must return the value -// to be assigned to the field with the given typ and name. -func assignValues(to interface{}, - getValue func(typ reflect.Type, name string) (interface{}, error)) error { - - toValue := reflect.ValueOf(to) - if toValue.Type().Kind() != reflect.Ptr { - return fmt.Errorf("%T is not a pointer to struct", to) - } - - if toValue.IsNil() { - return fmt.Errorf("nil pointer to %T", to) - } - - fields, err := ebpfFields(toValue.Elem(), nil) - if err != nil { - return err - } - - type elem struct { - // Either *Map or *Program - typ reflect.Type - name string - } - - assigned := make(map[elem]string) - for _, field := range fields { - // Get string value the field is tagged with. - tag := field.Tag.Get("ebpf") - if strings.Contains(tag, ",") { - return fmt.Errorf("field %s: ebpf tag contains a comma", field.Name) - } - - // Check if the eBPF object with the requested - // type and tag was already assigned elsewhere. - e := elem{field.Type, tag} - if af := assigned[e]; af != "" { - return fmt.Errorf("field %s: object %q was already assigned to %s", field.Name, tag, af) - } - - // Get the eBPF object referred to by the tag. - value, err := getValue(field.Type, tag) - if err != nil { - return fmt.Errorf("field %s: %w", field.Name, err) - } - - if !field.value.CanSet() { - return fmt.Errorf("field %s: can't set value", field.Name) - } - field.value.Set(reflect.ValueOf(value)) - - assigned[e] = field.Name - } - - return nil -} diff --git a/vendor/github.com/cilium/ebpf/doc.go b/vendor/github.com/cilium/ebpf/doc.go deleted file mode 100644 index 396b3394..00000000 --- a/vendor/github.com/cilium/ebpf/doc.go +++ /dev/null @@ -1,25 +0,0 @@ -// Package ebpf is a toolkit for working with eBPF programs. -// -// eBPF programs are small snippets of code which are executed directly -// in a VM in the Linux kernel, which makes them very fast and flexible. -// Many Linux subsystems now accept eBPF programs. This makes it possible -// to implement highly application specific logic inside the kernel, -// without having to modify the actual kernel itself. -// -// This package is designed for long-running processes which -// want to use eBPF to implement part of their application logic. It has no -// run-time dependencies outside of the library and the Linux kernel itself. -// eBPF code should be compiled ahead of time using clang, and shipped with -// your application as any other resource. -// -// Use the link subpackage to attach a loaded program to a hook in the kernel. -// -// Note that losing all references to Map and Program resources will cause -// their underlying file descriptors to be closed, potentially removing those -// objects from the kernel. Always retain a reference by e.g. deferring a -// Close() of a Collection or LoadAndAssign object until application exit. -// -// Special care needs to be taken when handling maps of type ProgramArray, -// as the kernel erases its contents when the last userspace or bpffs -// reference disappears, regardless of the map being in active use. -package ebpf diff --git a/vendor/github.com/cilium/ebpf/elf_reader.go b/vendor/github.com/cilium/ebpf/elf_reader.go deleted file mode 100644 index df278895..00000000 --- a/vendor/github.com/cilium/ebpf/elf_reader.go +++ /dev/null @@ -1,1197 +0,0 @@ -package ebpf - -import ( - "bufio" - "bytes" - "debug/elf" - "encoding/binary" - "errors" - "fmt" - "io" - "math" - "os" - "strings" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/unix" -) - -// elfCode is a convenience to reduce the amount of arguments that have to -// be passed around explicitly. You should treat its contents as immutable. -type elfCode struct { - *internal.SafeELFFile - sections map[elf.SectionIndex]*elfSection - license string - version uint32 - btf *btf.Spec - extInfo *btf.ExtInfos -} - -// LoadCollectionSpec parses an ELF file into a CollectionSpec. -func LoadCollectionSpec(file string) (*CollectionSpec, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - - spec, err := LoadCollectionSpecFromReader(f) - if err != nil { - return nil, fmt.Errorf("file %s: %w", file, err) - } - return spec, nil -} - -// LoadCollectionSpecFromReader parses an ELF file into a CollectionSpec. -func LoadCollectionSpecFromReader(rd io.ReaderAt) (*CollectionSpec, error) { - f, err := internal.NewSafeELFFile(rd) - if err != nil { - return nil, err - } - - var ( - licenseSection *elf.Section - versionSection *elf.Section - sections = make(map[elf.SectionIndex]*elfSection) - relSections = make(map[elf.SectionIndex]*elf.Section) - ) - - // This is the target of relocations generated by inline assembly. - sections[elf.SHN_UNDEF] = newElfSection(new(elf.Section), undefSection) - - // Collect all the sections we're interested in. This includes relocations - // which we parse later. - for i, sec := range f.Sections { - idx := elf.SectionIndex(i) - - switch { - case strings.HasPrefix(sec.Name, "license"): - licenseSection = sec - case strings.HasPrefix(sec.Name, "version"): - versionSection = sec - case strings.HasPrefix(sec.Name, "maps"): - sections[idx] = newElfSection(sec, mapSection) - case sec.Name == ".maps": - sections[idx] = newElfSection(sec, btfMapSection) - case sec.Name == ".bss" || sec.Name == ".data" || strings.HasPrefix(sec.Name, ".rodata"): - sections[idx] = newElfSection(sec, dataSection) - case sec.Type == elf.SHT_REL: - // Store relocations under the section index of the target - relSections[elf.SectionIndex(sec.Info)] = sec - case sec.Type == elf.SHT_PROGBITS && (sec.Flags&elf.SHF_EXECINSTR) != 0 && sec.Size > 0: - sections[idx] = newElfSection(sec, programSection) - } - } - - license, err := loadLicense(licenseSection) - if err != nil { - return nil, fmt.Errorf("load license: %w", err) - } - - version, err := loadVersion(versionSection, f.ByteOrder) - if err != nil { - return nil, fmt.Errorf("load version: %w", err) - } - - btfSpec, btfExtInfo, err := btf.LoadSpecAndExtInfosFromReader(rd) - if err != nil && !errors.Is(err, btf.ErrNotFound) { - return nil, fmt.Errorf("load BTF: %w", err) - } - - ec := &elfCode{ - SafeELFFile: f, - sections: sections, - license: license, - version: version, - btf: btfSpec, - extInfo: btfExtInfo, - } - - symbols, err := f.Symbols() - if err != nil { - return nil, fmt.Errorf("load symbols: %v", err) - } - - ec.assignSymbols(symbols) - - if err := ec.loadRelocations(relSections, symbols); err != nil { - return nil, fmt.Errorf("load relocations: %w", err) - } - - // Collect all the various ways to define maps. - maps := make(map[string]*MapSpec) - if err := ec.loadMaps(maps); err != nil { - return nil, fmt.Errorf("load maps: %w", err) - } - - if err := ec.loadBTFMaps(maps); err != nil { - return nil, fmt.Errorf("load BTF maps: %w", err) - } - - if err := ec.loadDataSections(maps); err != nil { - return nil, fmt.Errorf("load data sections: %w", err) - } - - // Finally, collect programs and link them. - progs, err := ec.loadProgramSections() - if err != nil { - return nil, fmt.Errorf("load programs: %w", err) - } - - return &CollectionSpec{maps, progs, btfSpec, ec.ByteOrder}, nil -} - -func loadLicense(sec *elf.Section) (string, error) { - if sec == nil { - return "", nil - } - - data, err := sec.Data() - if err != nil { - return "", fmt.Errorf("section %s: %v", sec.Name, err) - } - return string(bytes.TrimRight(data, "\000")), nil -} - -func loadVersion(sec *elf.Section, bo binary.ByteOrder) (uint32, error) { - if sec == nil { - return 0, nil - } - - var version uint32 - if err := binary.Read(sec.Open(), bo, &version); err != nil { - return 0, fmt.Errorf("section %s: %v", sec.Name, err) - } - return version, nil -} - -type elfSectionKind int - -const ( - undefSection elfSectionKind = iota - mapSection - btfMapSection - programSection - dataSection -) - -type elfSection struct { - *elf.Section - kind elfSectionKind - // Offset from the start of the section to a symbol - symbols map[uint64]elf.Symbol - // Offset from the start of the section to a relocation, which points at - // a symbol in another section. - relocations map[uint64]elf.Symbol - // The number of relocations pointing at this section. - references int -} - -func newElfSection(section *elf.Section, kind elfSectionKind) *elfSection { - return &elfSection{ - section, - kind, - make(map[uint64]elf.Symbol), - make(map[uint64]elf.Symbol), - 0, - } -} - -// assignSymbols takes a list of symbols and assigns them to their -// respective sections, indexed by name. -func (ec *elfCode) assignSymbols(symbols []elf.Symbol) { - for _, symbol := range symbols { - symType := elf.ST_TYPE(symbol.Info) - symSection := ec.sections[symbol.Section] - if symSection == nil { - continue - } - - // Anonymous symbols only occur in debug sections which we don't process - // relocations for. Anonymous symbols are not referenced from other sections. - if symbol.Name == "" { - continue - } - - // Older versions of LLVM don't tag symbols correctly, so keep - // all NOTYPE ones. - switch symSection.kind { - case mapSection, btfMapSection, dataSection: - if symType != elf.STT_NOTYPE && symType != elf.STT_OBJECT { - continue - } - case programSection: - if symType != elf.STT_NOTYPE && symType != elf.STT_FUNC { - continue - } - // LLVM emits LBB_ (Local Basic Block) symbols that seem to be jump - // targets within sections, but BPF has no use for them. - if symType == elf.STT_NOTYPE && elf.ST_BIND(symbol.Info) == elf.STB_LOCAL && - strings.HasPrefix(symbol.Name, "LBB") { - continue - } - // Only collect symbols that occur in program/maps/data sections. - default: - continue - } - - symSection.symbols[symbol.Value] = symbol - } -} - -// loadRelocations iterates .rel* sections and extracts relocation entries for -// sections of interest. Makes sure relocations point at valid sections. -func (ec *elfCode) loadRelocations(relSections map[elf.SectionIndex]*elf.Section, symbols []elf.Symbol) error { - for idx, relSection := range relSections { - section := ec.sections[idx] - if section == nil { - continue - } - - rels, err := ec.loadSectionRelocations(relSection, symbols) - if err != nil { - return fmt.Errorf("relocation for section %q: %w", section.Name, err) - } - - for _, rel := range rels { - target := ec.sections[rel.Section] - if target == nil { - return fmt.Errorf("section %q: reference to %q in section %s: %w", section.Name, rel.Name, rel.Section, ErrNotSupported) - } - - if target.Flags&elf.SHF_STRINGS > 0 { - return fmt.Errorf("section %q: string is not stack allocated: %w", section.Name, ErrNotSupported) - } - - target.references++ - } - - section.relocations = rels - } - - return nil -} - -// loadProgramSections iterates ec's sections and emits a ProgramSpec -// for each function it finds. -// -// The resulting map is indexed by function name. -func (ec *elfCode) loadProgramSections() (map[string]*ProgramSpec, error) { - - progs := make(map[string]*ProgramSpec) - - // Generate a ProgramSpec for each function found in each program section. - var export []string - for _, sec := range ec.sections { - if sec.kind != programSection { - continue - } - - if len(sec.symbols) == 0 { - return nil, fmt.Errorf("section %v: missing symbols", sec.Name) - } - - funcs, err := ec.loadFunctions(sec) - if err != nil { - return nil, fmt.Errorf("section %v: %w", sec.Name, err) - } - - progType, attachType, progFlags, attachTo := getProgType(sec.Name) - - for name, insns := range funcs { - spec := &ProgramSpec{ - Name: name, - Type: progType, - Flags: progFlags, - AttachType: attachType, - AttachTo: attachTo, - SectionName: sec.Name, - License: ec.license, - KernelVersion: ec.version, - Instructions: insns, - ByteOrder: ec.ByteOrder, - BTF: ec.btf, - } - - // Function names must be unique within a single ELF blob. - if progs[name] != nil { - return nil, fmt.Errorf("duplicate program name %s", name) - } - progs[name] = spec - - if spec.SectionName != ".text" { - export = append(export, name) - } - } - } - - flattenPrograms(progs, export) - - // Hide programs (e.g. library functions) that were not explicitly emitted - // to an ELF section. These could be exposed in a separate CollectionSpec - // field later to allow them to be modified. - for n, p := range progs { - if p.SectionName == ".text" { - delete(progs, n) - } - } - - return progs, nil -} - -// loadFunctions extracts instruction streams from the given program section -// starting at each symbol in the section. The section's symbols must already -// be narrowed down to STT_NOTYPE (emitted by clang <8) or STT_FUNC. -// -// The resulting map is indexed by function name. -func (ec *elfCode) loadFunctions(section *elfSection) (map[string]asm.Instructions, error) { - r := bufio.NewReader(section.Open()) - - // Decode the section's instruction stream. - var insns asm.Instructions - if err := insns.Unmarshal(r, ec.ByteOrder); err != nil { - return nil, fmt.Errorf("decoding instructions for section %s: %w", section.Name, err) - } - if len(insns) == 0 { - return nil, fmt.Errorf("no instructions found in section %s", section.Name) - } - - iter := insns.Iterate() - for iter.Next() { - ins := iter.Ins - offset := iter.Offset.Bytes() - - // Tag Symbol Instructions. - if sym, ok := section.symbols[offset]; ok { - *ins = ins.WithSymbol(sym.Name) - } - - // Apply any relocations for the current instruction. - // If no relocation is present, resolve any section-relative function calls. - if rel, ok := section.relocations[offset]; ok { - if err := ec.relocateInstruction(ins, rel); err != nil { - return nil, fmt.Errorf("offset %d: relocating instruction: %w", offset, err) - } - } else { - if err := referenceRelativeJump(ins, offset, section.symbols); err != nil { - return nil, fmt.Errorf("offset %d: resolving relative jump: %w", offset, err) - } - } - } - - if ec.extInfo != nil { - ec.extInfo.Assign(insns, section.Name) - } - - return splitSymbols(insns) -} - -// referenceRelativeJump turns a relative jump to another bpf subprogram within -// the same ELF section into a Reference Instruction. -// -// Up to LLVM 9, calls to subprograms within the same ELF section are sometimes -// encoded using relative jumps instead of relocation entries. These jumps go -// out of bounds of the current program, so their targets must be memoized -// before the section's instruction stream is split. -// -// The relative jump Constant is blinded to -1 and the target Symbol is set as -// the Instruction's Reference so it can be resolved by the linker. -func referenceRelativeJump(ins *asm.Instruction, offset uint64, symbols map[uint64]elf.Symbol) error { - if !ins.IsFunctionReference() || ins.Constant == -1 { - return nil - } - - tgt := jumpTarget(offset, *ins) - sym := symbols[tgt].Name - if sym == "" { - return fmt.Errorf("no jump target found at offset %d", tgt) - } - - *ins = ins.WithReference(sym) - ins.Constant = -1 - - return nil -} - -// jumpTarget takes ins' offset within an instruction stream (in bytes) -// and returns its absolute jump destination (in bytes) within the -// instruction stream. -func jumpTarget(offset uint64, ins asm.Instruction) uint64 { - // A relative jump instruction describes the amount of raw BPF instructions - // to jump, convert the offset into bytes. - dest := ins.Constant * asm.InstructionSize - - // The starting point of the jump is the end of the current instruction. - dest += int64(offset + asm.InstructionSize) - - if dest < 0 { - return 0 - } - - return uint64(dest) -} - -func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) error { - var ( - typ = elf.ST_TYPE(rel.Info) - bind = elf.ST_BIND(rel.Info) - name = rel.Name - ) - - target := ec.sections[rel.Section] - - switch target.kind { - case mapSection, btfMapSection: - if bind != elf.STB_GLOBAL { - return fmt.Errorf("possible erroneous static qualifier on map definition: found reference to %q", name) - } - - if typ != elf.STT_OBJECT && typ != elf.STT_NOTYPE { - // STT_NOTYPE is generated on clang < 8 which doesn't tag - // relocations appropriately. - return fmt.Errorf("map load: incorrect relocation type %v", typ) - } - - ins.Src = asm.PseudoMapFD - - case dataSection: - var offset uint32 - switch typ { - case elf.STT_SECTION: - if bind != elf.STB_LOCAL { - return fmt.Errorf("direct load: %s: unsupported section relocation %s", name, bind) - } - - // This is really a reference to a static symbol, which clang doesn't - // emit a symbol table entry for. Instead it encodes the offset in - // the instruction itself. - offset = uint32(uint64(ins.Constant)) - - case elf.STT_OBJECT: - // LLVM 9 emits OBJECT-LOCAL symbols for anonymous constants. - if bind != elf.STB_GLOBAL && bind != elf.STB_LOCAL { - return fmt.Errorf("direct load: %s: unsupported object relocation %s", name, bind) - } - - offset = uint32(rel.Value) - - case elf.STT_NOTYPE: - // LLVM 7 emits NOTYPE-LOCAL symbols for anonymous constants. - if bind != elf.STB_LOCAL { - return fmt.Errorf("direct load: %s: unsupported untyped relocation %s", name, bind) - } - - offset = uint32(rel.Value) - - default: - return fmt.Errorf("incorrect relocation type %v for direct map load", typ) - } - - // We rely on using the name of the data section as the reference. It - // would be nicer to keep the real name in case of an STT_OBJECT, but - // it's not clear how to encode that into Instruction. - name = target.Name - - // The kernel expects the offset in the second basic BPF instruction. - ins.Constant = int64(uint64(offset) << 32) - ins.Src = asm.PseudoMapValue - - case programSection: - switch opCode := ins.OpCode; { - case opCode.JumpOp() == asm.Call: - if ins.Src != asm.PseudoCall { - return fmt.Errorf("call: %s: incorrect source register", name) - } - - switch typ { - case elf.STT_NOTYPE, elf.STT_FUNC: - if bind != elf.STB_GLOBAL { - return fmt.Errorf("call: %s: unsupported binding: %s", name, bind) - } - - case elf.STT_SECTION: - if bind != elf.STB_LOCAL { - return fmt.Errorf("call: %s: unsupported binding: %s", name, bind) - } - - // The function we want to call is in the indicated section, - // at the offset encoded in the instruction itself. Reverse - // the calculation to find the real function we're looking for. - // A value of -1 references the first instruction in the section. - offset := int64(int32(ins.Constant)+1) * asm.InstructionSize - sym, ok := target.symbols[uint64(offset)] - if !ok { - return fmt.Errorf("call: no symbol at offset %d", offset) - } - - name = sym.Name - ins.Constant = -1 - - default: - return fmt.Errorf("call: %s: invalid symbol type %s", name, typ) - } - case opCode.IsDWordLoad(): - switch typ { - case elf.STT_FUNC: - if bind != elf.STB_GLOBAL { - return fmt.Errorf("load: %s: unsupported binding: %s", name, bind) - } - - case elf.STT_SECTION: - if bind != elf.STB_LOCAL { - return fmt.Errorf("load: %s: unsupported binding: %s", name, bind) - } - - // ins.Constant already contains the offset in bytes from the - // start of the section. This is different than a call to a - // static function. - - default: - return fmt.Errorf("load: %s: invalid symbol type %s", name, typ) - } - - sym, ok := target.symbols[uint64(ins.Constant)] - if !ok { - return fmt.Errorf("load: no symbol at offset %d", ins.Constant) - } - - name = sym.Name - ins.Constant = -1 - ins.Src = asm.PseudoFunc - - default: - return fmt.Errorf("neither a call nor a load instruction: %v", ins) - } - - case undefSection: - if bind != elf.STB_GLOBAL { - return fmt.Errorf("asm relocation: %s: unsupported binding: %s", name, bind) - } - - if typ != elf.STT_NOTYPE { - return fmt.Errorf("asm relocation: %s: unsupported type %s", name, typ) - } - - // There is nothing to do here but set ins.Reference. - - default: - return fmt.Errorf("relocation to %q: %w", target.Name, ErrNotSupported) - } - - *ins = ins.WithReference(name) - return nil -} - -func (ec *elfCode) loadMaps(maps map[string]*MapSpec) error { - for _, sec := range ec.sections { - if sec.kind != mapSection { - continue - } - - nSym := len(sec.symbols) - if nSym == 0 { - return fmt.Errorf("section %v: no symbols", sec.Name) - } - - if sec.Size%uint64(nSym) != 0 { - return fmt.Errorf("section %v: map descriptors are not of equal size", sec.Name) - } - - var ( - r = bufio.NewReader(sec.Open()) - size = sec.Size / uint64(nSym) - ) - for i, offset := 0, uint64(0); i < nSym; i, offset = i+1, offset+size { - mapSym, ok := sec.symbols[offset] - if !ok { - return fmt.Errorf("section %s: missing symbol for map at offset %d", sec.Name, offset) - } - - mapName := mapSym.Name - if maps[mapName] != nil { - return fmt.Errorf("section %v: map %v already exists", sec.Name, mapSym) - } - - lr := io.LimitReader(r, int64(size)) - - spec := MapSpec{ - Name: SanitizeName(mapName, -1), - } - switch { - case binary.Read(lr, ec.ByteOrder, &spec.Type) != nil: - return fmt.Errorf("map %s: missing type", mapName) - case binary.Read(lr, ec.ByteOrder, &spec.KeySize) != nil: - return fmt.Errorf("map %s: missing key size", mapName) - case binary.Read(lr, ec.ByteOrder, &spec.ValueSize) != nil: - return fmt.Errorf("map %s: missing value size", mapName) - case binary.Read(lr, ec.ByteOrder, &spec.MaxEntries) != nil: - return fmt.Errorf("map %s: missing max entries", mapName) - case binary.Read(lr, ec.ByteOrder, &spec.Flags) != nil: - return fmt.Errorf("map %s: missing flags", mapName) - } - - extra, err := io.ReadAll(lr) - if err != nil { - return fmt.Errorf("map %s: reading map tail: %w", mapName, err) - } - if len(extra) > 0 { - spec.Extra = bytes.NewReader(extra) - } - - if err := spec.clampPerfEventArraySize(); err != nil { - return fmt.Errorf("map %s: %w", mapName, err) - } - - maps[mapName] = &spec - } - } - - return nil -} - -// loadBTFMaps iterates over all ELF sections marked as BTF map sections -// (like .maps) and parses them into MapSpecs. Dump the .maps section and -// any relocations with `readelf -x .maps -r `. -func (ec *elfCode) loadBTFMaps(maps map[string]*MapSpec) error { - for _, sec := range ec.sections { - if sec.kind != btfMapSection { - continue - } - - if ec.btf == nil { - return fmt.Errorf("missing BTF") - } - - // Each section must appear as a DataSec in the ELF's BTF blob. - var ds *btf.Datasec - if err := ec.btf.TypeByName(sec.Name, &ds); err != nil { - return fmt.Errorf("cannot find section '%s' in BTF: %w", sec.Name, err) - } - - // Open a Reader to the ELF's raw section bytes so we can assert that all - // of them are zero on a per-map (per-Var) basis. For now, the section's - // sole purpose is to receive relocations, so all must be zero. - rs := sec.Open() - - for _, vs := range ds.Vars { - // BPF maps are declared as and assigned to global variables, - // so iterate over each Var in the DataSec and validate their types. - v, ok := vs.Type.(*btf.Var) - if !ok { - return fmt.Errorf("section %v: unexpected type %s", sec.Name, vs.Type) - } - name := string(v.Name) - - // The BTF metadata for each Var contains the full length of the map - // declaration, so read the corresponding amount of bytes from the ELF. - // This way, we can pinpoint which map declaration contains unexpected - // (and therefore unsupported) data. - _, err := io.Copy(internal.DiscardZeroes{}, io.LimitReader(rs, int64(vs.Size))) - if err != nil { - return fmt.Errorf("section %v: map %s: initializing BTF map definitions: %w", sec.Name, name, internal.ErrNotSupported) - } - - if maps[name] != nil { - return fmt.Errorf("section %v: map %s already exists", sec.Name, name) - } - - // Each Var representing a BTF map definition contains a Struct. - mapStruct, ok := v.Type.(*btf.Struct) - if !ok { - return fmt.Errorf("expected struct, got %s", v.Type) - } - - mapSpec, err := mapSpecFromBTF(sec, &vs, mapStruct, ec.btf, name, false) - if err != nil { - return fmt.Errorf("map %v: %w", name, err) - } - - if err := mapSpec.clampPerfEventArraySize(); err != nil { - return fmt.Errorf("map %v: %w", name, err) - } - - maps[name] = mapSpec - } - - // Drain the ELF section reader to make sure all bytes are accounted for - // with BTF metadata. - i, err := io.Copy(io.Discard, rs) - if err != nil { - return fmt.Errorf("section %v: unexpected error reading remainder of ELF section: %w", sec.Name, err) - } - if i > 0 { - return fmt.Errorf("section %v: %d unexpected remaining bytes in ELF section, invalid BTF?", sec.Name, i) - } - } - - return nil -} - -// mapSpecFromBTF produces a MapSpec based on a btf.Struct def representing -// a BTF map definition. The name and spec arguments will be copied to the -// resulting MapSpec, and inner must be true on any resursive invocations. -func mapSpecFromBTF(es *elfSection, vs *btf.VarSecinfo, def *btf.Struct, spec *btf.Spec, name string, inner bool) (*MapSpec, error) { - var ( - key, value btf.Type - keySize, valueSize uint32 - mapType MapType - flags, maxEntries uint32 - pinType PinType - innerMapSpec *MapSpec - contents []MapKV - err error - ) - - for i, member := range def.Members { - switch member.Name { - case "type": - mt, err := uintFromBTF(member.Type) - if err != nil { - return nil, fmt.Errorf("can't get type: %w", err) - } - mapType = MapType(mt) - - case "map_flags": - flags, err = uintFromBTF(member.Type) - if err != nil { - return nil, fmt.Errorf("can't get BTF map flags: %w", err) - } - - case "max_entries": - maxEntries, err = uintFromBTF(member.Type) - if err != nil { - return nil, fmt.Errorf("can't get BTF map max entries: %w", err) - } - - case "key": - if keySize != 0 { - return nil, errors.New("both key and key_size given") - } - - pk, ok := member.Type.(*btf.Pointer) - if !ok { - return nil, fmt.Errorf("key type is not a pointer: %T", member.Type) - } - - key = pk.Target - - size, err := btf.Sizeof(pk.Target) - if err != nil { - return nil, fmt.Errorf("can't get size of BTF key: %w", err) - } - - keySize = uint32(size) - - case "value": - if valueSize != 0 { - return nil, errors.New("both value and value_size given") - } - - vk, ok := member.Type.(*btf.Pointer) - if !ok { - return nil, fmt.Errorf("value type is not a pointer: %T", member.Type) - } - - value = vk.Target - - size, err := btf.Sizeof(vk.Target) - if err != nil { - return nil, fmt.Errorf("can't get size of BTF value: %w", err) - } - - valueSize = uint32(size) - - case "key_size": - // Key needs to be nil and keySize needs to be 0 for key_size to be - // considered a valid member. - if key != nil || keySize != 0 { - return nil, errors.New("both key and key_size given") - } - - keySize, err = uintFromBTF(member.Type) - if err != nil { - return nil, fmt.Errorf("can't get BTF key size: %w", err) - } - - case "value_size": - // Value needs to be nil and valueSize needs to be 0 for value_size to be - // considered a valid member. - if value != nil || valueSize != 0 { - return nil, errors.New("both value and value_size given") - } - - valueSize, err = uintFromBTF(member.Type) - if err != nil { - return nil, fmt.Errorf("can't get BTF value size: %w", err) - } - - case "pinning": - if inner { - return nil, errors.New("inner maps can't be pinned") - } - - pinning, err := uintFromBTF(member.Type) - if err != nil { - return nil, fmt.Errorf("can't get pinning: %w", err) - } - - pinType = PinType(pinning) - - case "values": - // The 'values' field in BTF map definitions is used for declaring map - // value types that are references to other BPF objects, like other maps - // or programs. It is always expected to be an array of pointers. - if i != len(def.Members)-1 { - return nil, errors.New("'values' must be the last member in a BTF map definition") - } - - if valueSize != 0 && valueSize != 4 { - return nil, errors.New("value_size must be 0 or 4") - } - valueSize = 4 - - valueType, err := resolveBTFArrayMacro(member.Type) - if err != nil { - return nil, fmt.Errorf("can't resolve type of member 'values': %w", err) - } - - switch t := valueType.(type) { - case *btf.Struct: - // The values member pointing to an array of structs means we're expecting - // a map-in-map declaration. - if mapType != ArrayOfMaps && mapType != HashOfMaps { - return nil, errors.New("outer map needs to be an array or a hash of maps") - } - if inner { - return nil, fmt.Errorf("nested inner maps are not supported") - } - - // This inner map spec is used as a map template, but it needs to be - // created as a traditional map before it can be used to do so. - // libbpf names the inner map template '.inner', but we - // opted for _inner to simplify validation logic. (dots only supported - // on kernels 5.2 and up) - // Pass the BTF spec from the parent object, since both parent and - // child must be created from the same BTF blob (on kernels that support BTF). - innerMapSpec, err = mapSpecFromBTF(es, vs, t, spec, name+"_inner", true) - if err != nil { - return nil, fmt.Errorf("can't parse BTF map definition of inner map: %w", err) - } - - case *btf.FuncProto: - // The values member contains an array of function pointers, meaning an - // autopopulated PROG_ARRAY. - if mapType != ProgramArray { - return nil, errors.New("map needs to be a program array") - } - - default: - return nil, fmt.Errorf("unsupported value type %q in 'values' field", t) - } - - contents, err = resolveBTFValuesContents(es, vs, member) - if err != nil { - return nil, fmt.Errorf("resolving values contents: %w", err) - } - - default: - return nil, fmt.Errorf("unrecognized field %s in BTF map definition", member.Name) - } - } - - if key == nil { - key = &btf.Void{} - } - if value == nil { - value = &btf.Void{} - } - - return &MapSpec{ - Name: SanitizeName(name, -1), - Type: MapType(mapType), - KeySize: keySize, - ValueSize: valueSize, - MaxEntries: maxEntries, - Flags: flags, - Key: key, - Value: value, - BTF: spec, - Pinning: pinType, - InnerMap: innerMapSpec, - Contents: contents, - }, nil -} - -// uintFromBTF resolves the __uint macro, which is a pointer to a sized -// array, e.g. for int (*foo)[10], this function will return 10. -func uintFromBTF(typ btf.Type) (uint32, error) { - ptr, ok := typ.(*btf.Pointer) - if !ok { - return 0, fmt.Errorf("not a pointer: %v", typ) - } - - arr, ok := ptr.Target.(*btf.Array) - if !ok { - return 0, fmt.Errorf("not a pointer to array: %v", typ) - } - - return arr.Nelems, nil -} - -// resolveBTFArrayMacro resolves the __array macro, which declares an array -// of pointers to a given type. This function returns the target Type of -// the pointers in the array. -func resolveBTFArrayMacro(typ btf.Type) (btf.Type, error) { - arr, ok := typ.(*btf.Array) - if !ok { - return nil, fmt.Errorf("not an array: %v", typ) - } - - ptr, ok := arr.Type.(*btf.Pointer) - if !ok { - return nil, fmt.Errorf("not an array of pointers: %v", typ) - } - - return ptr.Target, nil -} - -// resolveBTFValuesContents resolves relocations into ELF sections belonging -// to btf.VarSecinfo's. This can be used on the 'values' member in BTF map -// definitions to extract static declarations of map contents. -func resolveBTFValuesContents(es *elfSection, vs *btf.VarSecinfo, member btf.Member) ([]MapKV, error) { - // The elements of a .values pointer array are not encoded in BTF. - // Instead, relocations are generated into each array index. - // However, it's possible to leave certain array indices empty, so all - // indices' offsets need to be checked for emitted relocations. - - // The offset of the 'values' member within the _struct_ (in bits) - // is the starting point of the array. Convert to bytes. Add VarSecinfo - // offset to get the absolute position in the ELF blob. - start := member.Offset.Bytes() + vs.Offset - // 'values' is encoded in BTF as a zero (variable) length struct - // member, and its contents run until the end of the VarSecinfo. - // Add VarSecinfo offset to get the absolute position in the ELF blob. - end := vs.Size + vs.Offset - // The size of an address in this section. This determines the width of - // an index in the array. - align := uint32(es.SectionHeader.Addralign) - - // Check if variable-length section is aligned. - if (end-start)%align != 0 { - return nil, errors.New("unaligned static values section") - } - elems := (end - start) / align - - if elems == 0 { - return nil, nil - } - - contents := make([]MapKV, 0, elems) - - // k is the array index, off is its corresponding ELF section offset. - for k, off := uint32(0), start; k < elems; k, off = k+1, off+align { - r, ok := es.relocations[uint64(off)] - if !ok { - continue - } - - // Relocation exists for the current offset in the ELF section. - // Emit a value stub based on the type of relocation to be replaced by - // a real fd later in the pipeline before populating the map. - // Map keys are encoded in MapKV entries, so empty array indices are - // skipped here. - switch t := elf.ST_TYPE(r.Info); t { - case elf.STT_FUNC: - contents = append(contents, MapKV{uint32(k), r.Name}) - case elf.STT_OBJECT: - contents = append(contents, MapKV{uint32(k), r.Name}) - default: - return nil, fmt.Errorf("unknown relocation type %v", t) - } - } - - return contents, nil -} - -func (ec *elfCode) loadDataSections(maps map[string]*MapSpec) error { - for _, sec := range ec.sections { - if sec.kind != dataSection { - continue - } - - if sec.references == 0 { - // Prune data sections which are not referenced by any - // instructions. - continue - } - - data, err := sec.Data() - if err != nil { - return fmt.Errorf("data section %s: can't get contents: %w", sec.Name, err) - } - - if uint64(len(data)) > math.MaxUint32 { - return fmt.Errorf("data section %s: contents exceed maximum size", sec.Name) - } - - mapSpec := &MapSpec{ - Name: SanitizeName(sec.Name, -1), - Type: Array, - KeySize: 4, - ValueSize: uint32(len(data)), - MaxEntries: 1, - Contents: []MapKV{{uint32(0), data}}, - } - - // It is possible for a data section to exist without a corresponding BTF Datasec - // if it only contains anonymous values like macro-defined arrays. - if ec.btf != nil { - var ds *btf.Datasec - if ec.btf.TypeByName(sec.Name, &ds) == nil { - // Assign the spec's key and BTF only if the Datasec lookup was successful. - mapSpec.BTF = ec.btf - mapSpec.Key = &btf.Void{} - mapSpec.Value = ds - } - } - - switch n := sec.Name; { - case strings.HasPrefix(n, ".rodata"): - mapSpec.Flags = unix.BPF_F_RDONLY_PROG - mapSpec.Freeze = true - case n == ".bss": - // The kernel already zero-initializes the map - mapSpec.Contents = nil - } - - maps[sec.Name] = mapSpec - } - return nil -} - -func getProgType(sectionName string) (ProgramType, AttachType, uint32, string) { - types := []struct { - prefix string - progType ProgramType - attachType AttachType - progFlags uint32 - }{ - // Please update the types from libbpf.c and follow the order of it. - // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c - {"socket", SocketFilter, AttachNone, 0}, - {"sk_reuseport/migrate", SkReuseport, AttachSkReuseportSelectOrMigrate, 0}, - {"sk_reuseport", SkReuseport, AttachSkReuseportSelect, 0}, - {"kprobe/", Kprobe, AttachNone, 0}, - {"uprobe/", Kprobe, AttachNone, 0}, - {"kretprobe/", Kprobe, AttachNone, 0}, - {"uretprobe/", Kprobe, AttachNone, 0}, - {"tc", SchedCLS, AttachNone, 0}, - {"classifier", SchedCLS, AttachNone, 0}, - {"action", SchedACT, AttachNone, 0}, - {"tracepoint/", TracePoint, AttachNone, 0}, - {"tp/", TracePoint, AttachNone, 0}, - {"raw_tracepoint/", RawTracepoint, AttachNone, 0}, - {"raw_tp/", RawTracepoint, AttachNone, 0}, - {"raw_tracepoint.w/", RawTracepointWritable, AttachNone, 0}, - {"raw_tp.w/", RawTracepointWritable, AttachNone, 0}, - {"tp_btf/", Tracing, AttachTraceRawTp, 0}, - {"fentry/", Tracing, AttachTraceFEntry, 0}, - {"fmod_ret/", Tracing, AttachModifyReturn, 0}, - {"fexit/", Tracing, AttachTraceFExit, 0}, - {"fentry.s/", Tracing, AttachTraceFEntry, unix.BPF_F_SLEEPABLE}, - {"fmod_ret.s/", Tracing, AttachModifyReturn, unix.BPF_F_SLEEPABLE}, - {"fexit.s/", Tracing, AttachTraceFExit, unix.BPF_F_SLEEPABLE}, - {"freplace/", Extension, AttachNone, 0}, - {"lsm/", LSM, AttachLSMMac, 0}, - {"lsm.s/", LSM, AttachLSMMac, unix.BPF_F_SLEEPABLE}, - {"iter/", Tracing, AttachTraceIter, 0}, - {"syscall", Syscall, AttachNone, 0}, - {"xdp_devmap/", XDP, AttachXDPDevMap, 0}, - {"xdp_cpumap/", XDP, AttachXDPCPUMap, 0}, - {"xdp", XDP, AttachNone, 0}, - {"perf_event", PerfEvent, AttachNone, 0}, - {"lwt_in", LWTIn, AttachNone, 0}, - {"lwt_out", LWTOut, AttachNone, 0}, - {"lwt_xmit", LWTXmit, AttachNone, 0}, - {"lwt_seg6local", LWTSeg6Local, AttachNone, 0}, - {"cgroup_skb/ingress", CGroupSKB, AttachCGroupInetIngress, 0}, - {"cgroup_skb/egress", CGroupSKB, AttachCGroupInetEgress, 0}, - {"cgroup/skb", CGroupSKB, AttachNone, 0}, - {"cgroup/sock_create", CGroupSock, AttachCGroupInetSockCreate, 0}, - {"cgroup/sock_release", CGroupSock, AttachCgroupInetSockRelease, 0}, - {"cgroup/sock", CGroupSock, AttachCGroupInetSockCreate, 0}, - {"cgroup/post_bind4", CGroupSock, AttachCGroupInet4PostBind, 0}, - {"cgroup/post_bind6", CGroupSock, AttachCGroupInet6PostBind, 0}, - {"cgroup/dev", CGroupDevice, AttachCGroupDevice, 0}, - {"sockops", SockOps, AttachCGroupSockOps, 0}, - {"sk_skb/stream_parser", SkSKB, AttachSkSKBStreamParser, 0}, - {"sk_skb/stream_verdict", SkSKB, AttachSkSKBStreamVerdict, 0}, - {"sk_skb", SkSKB, AttachNone, 0}, - {"sk_msg", SkMsg, AttachSkMsgVerdict, 0}, - {"lirc_mode2", LircMode2, AttachLircMode2, 0}, - {"flow_dissector", FlowDissector, AttachFlowDissector, 0}, - {"cgroup/bind4", CGroupSockAddr, AttachCGroupInet4Bind, 0}, - {"cgroup/bind6", CGroupSockAddr, AttachCGroupInet6Bind, 0}, - {"cgroup/connect4", CGroupSockAddr, AttachCGroupInet4Connect, 0}, - {"cgroup/connect6", CGroupSockAddr, AttachCGroupInet6Connect, 0}, - {"cgroup/sendmsg4", CGroupSockAddr, AttachCGroupUDP4Sendmsg, 0}, - {"cgroup/sendmsg6", CGroupSockAddr, AttachCGroupUDP6Sendmsg, 0}, - {"cgroup/recvmsg4", CGroupSockAddr, AttachCGroupUDP4Recvmsg, 0}, - {"cgroup/recvmsg6", CGroupSockAddr, AttachCGroupUDP6Recvmsg, 0}, - {"cgroup/getpeername4", CGroupSockAddr, AttachCgroupInet4GetPeername, 0}, - {"cgroup/getpeername6", CGroupSockAddr, AttachCgroupInet6GetPeername, 0}, - {"cgroup/getsockname4", CGroupSockAddr, AttachCgroupInet4GetSockname, 0}, - {"cgroup/getsockname6", CGroupSockAddr, AttachCgroupInet6GetSockname, 0}, - {"cgroup/sysctl", CGroupSysctl, AttachCGroupSysctl, 0}, - {"cgroup/getsockopt", CGroupSockopt, AttachCGroupGetsockopt, 0}, - {"cgroup/setsockopt", CGroupSockopt, AttachCGroupSetsockopt, 0}, - {"struct_ops+", StructOps, AttachNone, 0}, - {"sk_lookup/", SkLookup, AttachSkLookup, 0}, - - {"seccomp", SocketFilter, AttachNone, 0}, - } - - for _, t := range types { - if !strings.HasPrefix(sectionName, t.prefix) { - continue - } - - if !strings.HasSuffix(t.prefix, "/") { - return t.progType, t.attachType, t.progFlags, "" - } - - return t.progType, t.attachType, t.progFlags, sectionName[len(t.prefix):] - } - - return UnspecifiedProgram, AttachNone, 0, "" -} - -func (ec *elfCode) loadSectionRelocations(sec *elf.Section, symbols []elf.Symbol) (map[uint64]elf.Symbol, error) { - rels := make(map[uint64]elf.Symbol) - - if sec.Entsize < 16 { - return nil, fmt.Errorf("section %s: relocations are less than 16 bytes", sec.Name) - } - - r := bufio.NewReader(sec.Open()) - for off := uint64(0); off < sec.Size; off += sec.Entsize { - ent := io.LimitReader(r, int64(sec.Entsize)) - - var rel elf.Rel64 - if binary.Read(ent, ec.ByteOrder, &rel) != nil { - return nil, fmt.Errorf("can't parse relocation at offset %v", off) - } - - symNo := int(elf.R_SYM64(rel.Info) - 1) - if symNo >= len(symbols) { - return nil, fmt.Errorf("offset %d: symbol %d doesn't exist", off, symNo) - } - - symbol := symbols[symNo] - rels[rel.Off] = symbol - } - - return rels, nil -} diff --git a/vendor/github.com/cilium/ebpf/info.go b/vendor/github.com/cilium/ebpf/info.go deleted file mode 100644 index ae77bc61..00000000 --- a/vendor/github.com/cilium/ebpf/info.go +++ /dev/null @@ -1,323 +0,0 @@ -package ebpf - -import ( - "bufio" - "bytes" - "encoding/hex" - "errors" - "fmt" - "io" - "os" - "strings" - "syscall" - "time" - "unsafe" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// MapInfo describes a map. -type MapInfo struct { - Type MapType - id MapID - KeySize uint32 - ValueSize uint32 - MaxEntries uint32 - Flags uint32 - // Name as supplied by user space at load time. Available from 4.15. - Name string -} - -func newMapInfoFromFd(fd *sys.FD) (*MapInfo, error) { - var info sys.MapInfo - err := sys.ObjInfo(fd, &info) - if errors.Is(err, syscall.EINVAL) { - return newMapInfoFromProc(fd) - } - if err != nil { - return nil, err - } - - return &MapInfo{ - MapType(info.Type), - MapID(info.Id), - info.KeySize, - info.ValueSize, - info.MaxEntries, - info.MapFlags, - unix.ByteSliceToString(info.Name[:]), - }, nil -} - -func newMapInfoFromProc(fd *sys.FD) (*MapInfo, error) { - var mi MapInfo - err := scanFdInfo(fd, map[string]interface{}{ - "map_type": &mi.Type, - "key_size": &mi.KeySize, - "value_size": &mi.ValueSize, - "max_entries": &mi.MaxEntries, - "map_flags": &mi.Flags, - }) - if err != nil { - return nil, err - } - return &mi, nil -} - -// ID returns the map ID. -// -// Available from 4.13. -// -// The bool return value indicates whether this optional field is available. -func (mi *MapInfo) ID() (MapID, bool) { - return mi.id, mi.id > 0 -} - -// programStats holds statistics of a program. -type programStats struct { - // Total accumulated runtime of the program ins ns. - runtime time.Duration - // Total number of times the program was called. - runCount uint64 -} - -// ProgramInfo describes a program. -type ProgramInfo struct { - Type ProgramType - id ProgramID - // Truncated hash of the BPF bytecode. Available from 4.13. - Tag string - // Name as supplied by user space at load time. Available from 4.15. - Name string - - btf btf.ID - stats *programStats - - maps []MapID - insns []byte -} - -func newProgramInfoFromFd(fd *sys.FD) (*ProgramInfo, error) { - var info sys.ProgInfo - err := sys.ObjInfo(fd, &info) - if errors.Is(err, syscall.EINVAL) { - return newProgramInfoFromProc(fd) - } - if err != nil { - return nil, err - } - - pi := ProgramInfo{ - Type: ProgramType(info.Type), - id: ProgramID(info.Id), - Tag: hex.EncodeToString(info.Tag[:]), - Name: unix.ByteSliceToString(info.Name[:]), - btf: btf.ID(info.BtfId), - stats: &programStats{ - runtime: time.Duration(info.RunTimeNs), - runCount: info.RunCnt, - }, - } - - // Start with a clean struct for the second call, otherwise we may get EFAULT. - var info2 sys.ProgInfo - - if info.NrMapIds > 0 { - pi.maps = make([]MapID, info.NrMapIds) - info2.NrMapIds = info.NrMapIds - info2.MapIds = sys.NewPointer(unsafe.Pointer(&pi.maps[0])) - } - - if info.XlatedProgLen > 0 { - pi.insns = make([]byte, info.XlatedProgLen) - info2.XlatedProgLen = info.XlatedProgLen - info2.XlatedProgInsns = sys.NewSlicePointer(pi.insns) - } - - if info.NrMapIds > 0 || info.XlatedProgLen > 0 { - if err := sys.ObjInfo(fd, &info2); err != nil { - return nil, err - } - } - - return &pi, nil -} - -func newProgramInfoFromProc(fd *sys.FD) (*ProgramInfo, error) { - var info ProgramInfo - err := scanFdInfo(fd, map[string]interface{}{ - "prog_type": &info.Type, - "prog_tag": &info.Tag, - }) - if errors.Is(err, errMissingFields) { - return nil, &internal.UnsupportedFeatureError{ - Name: "reading program info from /proc/self/fdinfo", - MinimumVersion: internal.Version{4, 10, 0}, - } - } - if err != nil { - return nil, err - } - - return &info, nil -} - -// ID returns the program ID. -// -// Available from 4.13. -// -// The bool return value indicates whether this optional field is available. -func (pi *ProgramInfo) ID() (ProgramID, bool) { - return pi.id, pi.id > 0 -} - -// BTFID returns the BTF ID associated with the program. -// -// The ID is only valid as long as the associated program is kept alive. -// Available from 5.0. -// -// The bool return value indicates whether this optional field is available and -// populated. (The field may be available but not populated if the kernel -// supports the field but the program was loaded without BTF information.) -func (pi *ProgramInfo) BTFID() (btf.ID, bool) { - return pi.btf, pi.btf > 0 -} - -// RunCount returns the total number of times the program was called. -// -// Can return 0 if the collection of statistics is not enabled. See EnableStats(). -// The bool return value indicates whether this optional field is available. -func (pi *ProgramInfo) RunCount() (uint64, bool) { - if pi.stats != nil { - return pi.stats.runCount, true - } - return 0, false -} - -// Runtime returns the total accumulated runtime of the program. -// -// Can return 0 if the collection of statistics is not enabled. See EnableStats(). -// The bool return value indicates whether this optional field is available. -func (pi *ProgramInfo) Runtime() (time.Duration, bool) { - if pi.stats != nil { - return pi.stats.runtime, true - } - return time.Duration(0), false -} - -// Instructions returns the 'xlated' instruction stream of the program -// after it has been verified and rewritten by the kernel. These instructions -// cannot be loaded back into the kernel as-is, this is mainly used for -// inspecting loaded programs for troubleshooting, dumping, etc. -// -// For example, map accesses are made to reference their kernel map IDs, -// not the FDs they had when the program was inserted. Note that before -// the introduction of bpf_insn_prepare_dump in kernel 4.16, xlated -// instructions were not sanitized, making the output even less reusable -// and less likely to round-trip or evaluate to the same program Tag. -// -// The first instruction is marked as a symbol using the Program's name. -// -// Available from 4.13. Requires CAP_BPF or equivalent. -func (pi *ProgramInfo) Instructions() (asm.Instructions, error) { - // If the calling process is not BPF-capable or if the kernel doesn't - // support getting xlated instructions, the field will be zero. - if len(pi.insns) == 0 { - return nil, fmt.Errorf("insufficient permissions or unsupported kernel: %w", ErrNotSupported) - } - - r := bytes.NewReader(pi.insns) - var insns asm.Instructions - if err := insns.Unmarshal(r, internal.NativeEndian); err != nil { - return nil, fmt.Errorf("unmarshaling instructions: %w", err) - } - - // Tag the first instruction with the name of the program, if available. - insns[0] = insns[0].WithSymbol(pi.Name) - - return insns, nil -} - -// MapIDs returns the maps related to the program. -// -// Available from 4.15. -// -// The bool return value indicates whether this optional field is available. -func (pi *ProgramInfo) MapIDs() ([]MapID, bool) { - return pi.maps, pi.maps != nil -} - -func scanFdInfo(fd *sys.FD, fields map[string]interface{}) error { - fh, err := os.Open(fmt.Sprintf("/proc/self/fdinfo/%d", fd.Int())) - if err != nil { - return err - } - defer fh.Close() - - if err := scanFdInfoReader(fh, fields); err != nil { - return fmt.Errorf("%s: %w", fh.Name(), err) - } - return nil -} - -var errMissingFields = errors.New("missing fields") - -func scanFdInfoReader(r io.Reader, fields map[string]interface{}) error { - var ( - scanner = bufio.NewScanner(r) - scanned int - ) - - for scanner.Scan() { - parts := strings.SplitN(scanner.Text(), "\t", 2) - if len(parts) != 2 { - continue - } - - name := strings.TrimSuffix(parts[0], ":") - field, ok := fields[string(name)] - if !ok { - continue - } - - if n, err := fmt.Sscanln(parts[1], field); err != nil || n != 1 { - return fmt.Errorf("can't parse field %s: %v", name, err) - } - - scanned++ - } - - if err := scanner.Err(); err != nil { - return err - } - - if len(fields) > 0 && scanned == 0 { - return ErrNotSupported - } - - if scanned != len(fields) { - return errMissingFields - } - - return nil -} - -// EnableStats starts the measuring of the runtime -// and run counts of eBPF programs. -// -// Collecting statistics can have an impact on the performance. -// -// Requires at least 5.8. -func EnableStats(which uint32) (io.Closer, error) { - fd, err := sys.EnableStats(&sys.EnableStatsAttr{ - Type: which, - }) - if err != nil { - return nil, err - } - return fd, nil -} diff --git a/vendor/github.com/cilium/ebpf/internal/align.go b/vendor/github.com/cilium/ebpf/internal/align.go deleted file mode 100644 index 8b4f2658..00000000 --- a/vendor/github.com/cilium/ebpf/internal/align.go +++ /dev/null @@ -1,6 +0,0 @@ -package internal - -// Align returns 'n' updated to 'alignment' boundary. -func Align(n, alignment int) int { - return (int(n) + alignment - 1) / alignment * alignment -} diff --git a/vendor/github.com/cilium/ebpf/internal/cpu.go b/vendor/github.com/cilium/ebpf/internal/cpu.go deleted file mode 100644 index 3affa1ef..00000000 --- a/vendor/github.com/cilium/ebpf/internal/cpu.go +++ /dev/null @@ -1,62 +0,0 @@ -package internal - -import ( - "fmt" - "os" - "strings" - "sync" -) - -var sysCPU struct { - once sync.Once - err error - num int -} - -// PossibleCPUs returns the max number of CPUs a system may possibly have -// Logical CPU numbers must be of the form 0-n -func PossibleCPUs() (int, error) { - sysCPU.once.Do(func() { - sysCPU.num, sysCPU.err = parseCPUsFromFile("/sys/devices/system/cpu/possible") - }) - - return sysCPU.num, sysCPU.err -} - -func parseCPUsFromFile(path string) (int, error) { - spec, err := os.ReadFile(path) - if err != nil { - return 0, err - } - - n, err := parseCPUs(string(spec)) - if err != nil { - return 0, fmt.Errorf("can't parse %s: %v", path, err) - } - - return n, nil -} - -// parseCPUs parses the number of cpus from a string produced -// by bitmap_list_string() in the Linux kernel. -// Multiple ranges are rejected, since they can't be unified -// into a single number. -// This is the format of /sys/devices/system/cpu/possible, it -// is not suitable for /sys/devices/system/cpu/online, etc. -func parseCPUs(spec string) (int, error) { - if strings.Trim(spec, "\n") == "0" { - return 1, nil - } - - var low, high int - n, err := fmt.Sscanf(spec, "%d-%d\n", &low, &high) - if n != 2 || err != nil { - return 0, fmt.Errorf("invalid format: %s", spec) - } - if low != 0 { - return 0, fmt.Errorf("CPU spec doesn't start at zero: %s", spec) - } - - // cpus is 0 indexed - return high + 1, nil -} diff --git a/vendor/github.com/cilium/ebpf/internal/elf.go b/vendor/github.com/cilium/ebpf/internal/elf.go deleted file mode 100644 index 01158193..00000000 --- a/vendor/github.com/cilium/ebpf/internal/elf.go +++ /dev/null @@ -1,102 +0,0 @@ -package internal - -import ( - "debug/elf" - "fmt" - "io" -) - -type SafeELFFile struct { - *elf.File -} - -// NewSafeELFFile reads an ELF safely. -// -// Any panic during parsing is turned into an error. This is necessary since -// there are a bunch of unfixed bugs in debug/elf. -// -// https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+debug%2Felf+in%3Atitle -func NewSafeELFFile(r io.ReaderAt) (safe *SafeELFFile, err error) { - defer func() { - r := recover() - if r == nil { - return - } - - safe = nil - err = fmt.Errorf("reading ELF file panicked: %s", r) - }() - - file, err := elf.NewFile(r) - if err != nil { - return nil, err - } - - return &SafeELFFile{file}, nil -} - -// OpenSafeELFFile reads an ELF from a file. -// -// It works like NewSafeELFFile, with the exception that safe.Close will -// close the underlying file. -func OpenSafeELFFile(path string) (safe *SafeELFFile, err error) { - defer func() { - r := recover() - if r == nil { - return - } - - safe = nil - err = fmt.Errorf("reading ELF file panicked: %s", r) - }() - - file, err := elf.Open(path) - if err != nil { - return nil, err - } - - return &SafeELFFile{file}, nil -} - -// Symbols is the safe version of elf.File.Symbols. -func (se *SafeELFFile) Symbols() (syms []elf.Symbol, err error) { - defer func() { - r := recover() - if r == nil { - return - } - - syms = nil - err = fmt.Errorf("reading ELF symbols panicked: %s", r) - }() - - syms, err = se.File.Symbols() - return -} - -// DynamicSymbols is the safe version of elf.File.DynamicSymbols. -func (se *SafeELFFile) DynamicSymbols() (syms []elf.Symbol, err error) { - defer func() { - r := recover() - if r == nil { - return - } - - syms = nil - err = fmt.Errorf("reading ELF dynamic symbols panicked: %s", r) - }() - - syms, err = se.File.DynamicSymbols() - return -} - -// SectionsByType returns all sections in the file with the specified section type. -func (se *SafeELFFile) SectionsByType(typ elf.SectionType) []*elf.Section { - sections := make([]*elf.Section, 0, 1) - for _, section := range se.Sections { - if section.Type == typ { - sections = append(sections, section) - } - } - return sections -} diff --git a/vendor/github.com/cilium/ebpf/internal/endian_be.go b/vendor/github.com/cilium/ebpf/internal/endian_be.go deleted file mode 100644 index ad33cda8..00000000 --- a/vendor/github.com/cilium/ebpf/internal/endian_be.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build armbe || arm64be || mips || mips64 || mips64p32 || ppc64 || s390 || s390x || sparc || sparc64 -// +build armbe arm64be mips mips64 mips64p32 ppc64 s390 s390x sparc sparc64 - -package internal - -import "encoding/binary" - -// NativeEndian is set to either binary.BigEndian or binary.LittleEndian, -// depending on the host's endianness. -var NativeEndian binary.ByteOrder = binary.BigEndian - -// ClangEndian is set to either "el" or "eb" depending on the host's endianness. -const ClangEndian = "eb" diff --git a/vendor/github.com/cilium/ebpf/internal/endian_le.go b/vendor/github.com/cilium/ebpf/internal/endian_le.go deleted file mode 100644 index 41a68224..00000000 --- a/vendor/github.com/cilium/ebpf/internal/endian_le.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build 386 || amd64 || amd64p32 || arm || arm64 || mipsle || mips64le || mips64p32le || ppc64le || riscv64 -// +build 386 amd64 amd64p32 arm arm64 mipsle mips64le mips64p32le ppc64le riscv64 - -package internal - -import "encoding/binary" - -// NativeEndian is set to either binary.BigEndian or binary.LittleEndian, -// depending on the host's endianness. -var NativeEndian binary.ByteOrder = binary.LittleEndian - -// ClangEndian is set to either "el" or "eb" depending on the host's endianness. -const ClangEndian = "el" diff --git a/vendor/github.com/cilium/ebpf/internal/errors.go b/vendor/github.com/cilium/ebpf/internal/errors.go deleted file mode 100644 index b5ccdd7d..00000000 --- a/vendor/github.com/cilium/ebpf/internal/errors.go +++ /dev/null @@ -1,206 +0,0 @@ -package internal - -import ( - "bytes" - "fmt" - "io" - "strings" -) - -// ErrorWithLog returns an error which includes logs from the kernel verifier. -// -// The default error output is a summary of the full log. The latter can be -// accessed via VerifierError.Log or by formatting the error, see Format. -// -// A set of heuristics is used to determine whether the log has been truncated. -func ErrorWithLog(err error, log []byte) *VerifierError { - const whitespace = "\t\r\v\n " - - // Convert verifier log C string by truncating it on the first 0 byte - // and trimming trailing whitespace before interpreting as a Go string. - truncated := false - if i := bytes.IndexByte(log, 0); i != -1 { - if i == len(log)-1 && !bytes.HasSuffix(log[:i], []byte{'\n'}) { - // The null byte is at the end of the buffer and it's not preceded - // by a newline character. Most likely the buffer was too short. - truncated = true - } - - log = log[:i] - } else if len(log) > 0 { - // No null byte? Dodgy! - truncated = true - } - - log = bytes.Trim(log, whitespace) - logLines := bytes.Split(log, []byte{'\n'}) - lines := make([]string, 0, len(logLines)) - for _, line := range logLines { - // Don't remove leading white space on individual lines. We rely on it - // when outputting logs. - lines = append(lines, string(bytes.TrimRight(line, whitespace))) - } - - return &VerifierError{err, lines, truncated} -} - -// VerifierError includes information from the eBPF verifier. -// -// It summarises the log output, see Format if you want to output the full contents. -type VerifierError struct { - // The error which caused this error. - Cause error - // The verifier output split into lines. - Log []string - // Whether the log output is truncated, based on several heuristics. - Truncated bool -} - -func (le *VerifierError) Unwrap() error { - return le.Cause -} - -func (le *VerifierError) Error() string { - log := le.Log - if n := len(log); n > 0 && strings.HasPrefix(log[n-1], "processed ") { - // Get rid of "processed 39 insns (limit 1000000) ..." from summary. - log = log[:n-1] - } - - n := len(log) - if n == 0 { - return le.Cause.Error() - } - - lines := log[n-1:] - if n >= 2 && (includePreviousLine(log[n-1]) || le.Truncated) { - // Add one more line of context if it aids understanding the error. - lines = log[n-2:] - } - - var b strings.Builder - fmt.Fprintf(&b, "%s: ", le.Cause.Error()) - - for i, line := range lines { - b.WriteString(strings.TrimSpace(line)) - if i != len(lines)-1 { - b.WriteString(": ") - } - } - - omitted := len(le.Log) - len(lines) - if omitted == 0 && !le.Truncated { - return b.String() - } - - b.WriteString(" (") - if le.Truncated { - b.WriteString("truncated") - } - - if omitted > 0 { - if le.Truncated { - b.WriteString(", ") - } - fmt.Fprintf(&b, "%d line(s) omitted", omitted) - } - b.WriteString(")") - - return b.String() -} - -// includePreviousLine returns true if the given line likely is better -// understood with additional context from the preceding line. -func includePreviousLine(line string) bool { - // We need to find a good trade off between understandable error messages - // and too much complexity here. Checking the string prefix is ok, requiring - // regular expressions to do it is probably overkill. - - if strings.HasPrefix(line, "\t") { - // [13] STRUCT drm_rect size=16 vlen=4 - // \tx1 type_id=2 - return true - } - - if len(line) >= 2 && line[0] == 'R' && line[1] >= '0' && line[1] <= '9' { - // 0: (95) exit - // R0 !read_ok - return true - } - - if strings.HasPrefix(line, "invalid bpf_context access") { - // 0: (79) r6 = *(u64 *)(r1 +0) - // func '__x64_sys_recvfrom' arg0 type FWD is not a struct - // invalid bpf_context access off=0 size=8 - return true - } - - return false -} - -// Format the error. -// -// Understood verbs are %s and %v, which are equivalent to calling Error(). %v -// allows outputting additional information using the following flags: -// -// + Output the first lines, or all lines if no width is given. -// - Output the last lines, or all lines if no width is given. -// -// Use width to specify how many lines to output. Use the '-' flag to output -// lines from the end of the log instead of the beginning. -func (le *VerifierError) Format(f fmt.State, verb rune) { - switch verb { - case 's': - _, _ = io.WriteString(f, le.Error()) - - case 'v': - n, haveWidth := f.Width() - if !haveWidth || n > len(le.Log) { - n = len(le.Log) - } - - if !f.Flag('+') && !f.Flag('-') { - if haveWidth { - _, _ = io.WriteString(f, "%!v(BADWIDTH)") - return - } - - _, _ = io.WriteString(f, le.Error()) - return - } - - if f.Flag('+') && f.Flag('-') { - _, _ = io.WriteString(f, "%!v(BADFLAG)") - return - } - - fmt.Fprintf(f, "%s:", le.Cause.Error()) - - omitted := len(le.Log) - n - lines := le.Log[:n] - if f.Flag('-') { - // Print last instead of first lines. - lines = le.Log[len(le.Log)-n:] - if omitted > 0 { - fmt.Fprintf(f, "\n\t(%d line(s) omitted)", omitted) - } - } - - for _, line := range lines { - fmt.Fprintf(f, "\n\t%s", line) - } - - if !f.Flag('-') { - if omitted > 0 { - fmt.Fprintf(f, "\n\t(%d line(s) omitted)", omitted) - } - } - - if le.Truncated { - fmt.Fprintf(f, "\n\t(truncated)") - } - - default: - fmt.Fprintf(f, "%%!%c(BADVERB)", verb) - } -} diff --git a/vendor/github.com/cilium/ebpf/internal/feature.go b/vendor/github.com/cilium/ebpf/internal/feature.go deleted file mode 100644 index 0a6c2d1d..00000000 --- a/vendor/github.com/cilium/ebpf/internal/feature.go +++ /dev/null @@ -1,100 +0,0 @@ -package internal - -import ( - "errors" - "fmt" - "sync" -) - -// ErrNotSupported indicates that a feature is not supported by the current kernel. -var ErrNotSupported = errors.New("not supported") - -// UnsupportedFeatureError is returned by FeatureTest() functions. -type UnsupportedFeatureError struct { - // The minimum Linux mainline version required for this feature. - // Used for the error string, and for sanity checking during testing. - MinimumVersion Version - - // The name of the feature that isn't supported. - Name string -} - -func (ufe *UnsupportedFeatureError) Error() string { - if ufe.MinimumVersion.Unspecified() { - return fmt.Sprintf("%s not supported", ufe.Name) - } - return fmt.Sprintf("%s not supported (requires >= %s)", ufe.Name, ufe.MinimumVersion) -} - -// Is indicates that UnsupportedFeatureError is ErrNotSupported. -func (ufe *UnsupportedFeatureError) Is(target error) bool { - return target == ErrNotSupported -} - -type featureTest struct { - sync.RWMutex - successful bool - result error -} - -// FeatureTestFn is used to determine whether the kernel supports -// a certain feature. -// -// The return values have the following semantics: -// -// err == ErrNotSupported: the feature is not available -// err == nil: the feature is available -// err != nil: the test couldn't be executed -type FeatureTestFn func() error - -// FeatureTest wraps a function so that it is run at most once. -// -// name should identify the tested feature, while version must be in the -// form Major.Minor[.Patch]. -// -// Returns an error wrapping ErrNotSupported if the feature is not supported. -func FeatureTest(name, version string, fn FeatureTestFn) func() error { - ft := new(featureTest) - return func() error { - ft.RLock() - if ft.successful { - defer ft.RUnlock() - return ft.result - } - ft.RUnlock() - ft.Lock() - defer ft.Unlock() - // check one more time on the off - // chance that two go routines - // were able to call into the write - // lock - if ft.successful { - return ft.result - } - err := fn() - switch { - case errors.Is(err, ErrNotSupported): - v, err := NewVersion(version) - if err != nil { - return err - } - - ft.result = &UnsupportedFeatureError{ - MinimumVersion: v, - Name: name, - } - fallthrough - - case err == nil: - ft.successful = true - - default: - // We couldn't execute the feature test to a point - // where it could make a determination. - // Don't cache the result, just return it. - return fmt.Errorf("detect support for %s: %w", name, err) - } - - return ft.result - } -} diff --git a/vendor/github.com/cilium/ebpf/internal/io.go b/vendor/github.com/cilium/ebpf/internal/io.go deleted file mode 100644 index 30b6641f..00000000 --- a/vendor/github.com/cilium/ebpf/internal/io.go +++ /dev/null @@ -1,62 +0,0 @@ -package internal - -import ( - "bufio" - "compress/gzip" - "errors" - "io" - "os" -) - -// NewBufferedSectionReader wraps an io.ReaderAt in an appropriately-sized -// buffered reader. It is a convenience function for reading subsections of -// ELF sections while minimizing the amount of read() syscalls made. -// -// Syscall overhead is non-negligible in continuous integration context -// where ELFs might be accessed over virtual filesystems with poor random -// access performance. Buffering reads makes sense because (sub)sections -// end up being read completely anyway. -// -// Use instead of the r.Seek() + io.LimitReader() pattern. -func NewBufferedSectionReader(ra io.ReaderAt, off, n int64) *bufio.Reader { - // Clamp the size of the buffer to one page to avoid slurping large parts - // of a file into memory. bufio.NewReader uses a hardcoded default buffer - // of 4096. Allow arches with larger pages to allocate more, but don't - // allocate a fixed 4k buffer if we only need to read a small segment. - buf := n - if ps := int64(os.Getpagesize()); n > ps { - buf = ps - } - - return bufio.NewReaderSize(io.NewSectionReader(ra, off, n), int(buf)) -} - -// DiscardZeroes makes sure that all written bytes are zero -// before discarding them. -type DiscardZeroes struct{} - -func (DiscardZeroes) Write(p []byte) (int, error) { - for _, b := range p { - if b != 0 { - return 0, errors.New("encountered non-zero byte") - } - } - return len(p), nil -} - -// ReadAllCompressed decompresses a gzipped file into memory. -func ReadAllCompressed(file string) ([]byte, error) { - fh, err := os.Open(file) - if err != nil { - return nil, err - } - defer fh.Close() - - gz, err := gzip.NewReader(fh) - if err != nil { - return nil, err - } - defer gz.Close() - - return io.ReadAll(gz) -} diff --git a/vendor/github.com/cilium/ebpf/internal/output.go b/vendor/github.com/cilium/ebpf/internal/output.go deleted file mode 100644 index aeab37fc..00000000 --- a/vendor/github.com/cilium/ebpf/internal/output.go +++ /dev/null @@ -1,84 +0,0 @@ -package internal - -import ( - "bytes" - "errors" - "go/format" - "go/scanner" - "io" - "strings" - "unicode" -) - -// Identifier turns a C style type or field name into an exportable Go equivalent. -func Identifier(str string) string { - prev := rune(-1) - return strings.Map(func(r rune) rune { - // See https://golang.org/ref/spec#Identifiers - switch { - case unicode.IsLetter(r): - if prev == -1 { - r = unicode.ToUpper(r) - } - - case r == '_': - switch { - // The previous rune was deleted, or we are at the - // beginning of the string. - case prev == -1: - fallthrough - - // The previous rune is a lower case letter or a digit. - case unicode.IsDigit(prev) || (unicode.IsLetter(prev) && unicode.IsLower(prev)): - // delete the current rune, and force the - // next character to be uppercased. - r = -1 - } - - case unicode.IsDigit(r): - - default: - // Delete the current rune. prev is unchanged. - return -1 - } - - prev = r - return r - }, str) -} - -// WriteFormatted outputs a formatted src into out. -// -// If formatting fails it returns an informative error message. -func WriteFormatted(src []byte, out io.Writer) error { - formatted, err := format.Source(src) - if err == nil { - _, err = out.Write(formatted) - return err - } - - var el scanner.ErrorList - if !errors.As(err, &el) { - return err - } - - var nel scanner.ErrorList - for _, err := range el { - if !err.Pos.IsValid() { - nel = append(nel, err) - continue - } - - buf := src[err.Pos.Offset:] - nl := bytes.IndexRune(buf, '\n') - if nl == -1 { - nel = append(nel, err) - continue - } - - err.Msg += ": " + string(buf[:nl]) - nel = append(nel, err) - } - - return nel -} diff --git a/vendor/github.com/cilium/ebpf/internal/pinning.go b/vendor/github.com/cilium/ebpf/internal/pinning.go deleted file mode 100644 index c711353c..00000000 --- a/vendor/github.com/cilium/ebpf/internal/pinning.go +++ /dev/null @@ -1,77 +0,0 @@ -package internal - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "runtime" - "unsafe" - - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -func Pin(currentPath, newPath string, fd *sys.FD) error { - const bpfFSType = 0xcafe4a11 - - if newPath == "" { - return errors.New("given pinning path cannot be empty") - } - if currentPath == newPath { - return nil - } - - var statfs unix.Statfs_t - if err := unix.Statfs(filepath.Dir(newPath), &statfs); err != nil { - return err - } - - fsType := int64(statfs.Type) - if unsafe.Sizeof(statfs.Type) == 4 { - // We're on a 32 bit arch, where statfs.Type is int32. bpfFSType is a - // negative number when interpreted as int32 so we need to cast via - // uint32 to avoid sign extension. - fsType = int64(uint32(statfs.Type)) - } - - if fsType != bpfFSType { - return fmt.Errorf("%s is not on a bpf filesystem", newPath) - } - - defer runtime.KeepAlive(fd) - - if currentPath == "" { - return sys.ObjPin(&sys.ObjPinAttr{ - Pathname: sys.NewStringPointer(newPath), - BpfFd: fd.Uint(), - }) - } - - // Renameat2 is used instead of os.Rename to disallow the new path replacing - // an existing path. - err := unix.Renameat2(unix.AT_FDCWD, currentPath, unix.AT_FDCWD, newPath, unix.RENAME_NOREPLACE) - if err == nil { - // Object is now moved to the new pinning path. - return nil - } - if !os.IsNotExist(err) { - return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err) - } - // Internal state not in sync with the file system so let's fix it. - return sys.ObjPin(&sys.ObjPinAttr{ - Pathname: sys.NewStringPointer(newPath), - BpfFd: fd.Uint(), - }) -} - -func Unpin(pinnedPath string) error { - if pinnedPath == "" { - return nil - } - err := os.Remove(pinnedPath) - if err == nil || os.IsNotExist(err) { - return nil - } - return err -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/doc.go b/vendor/github.com/cilium/ebpf/internal/sys/doc.go deleted file mode 100644 index dfe17444..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package sys contains bindings for the BPF syscall. -package sys - -// Regenerate types.go by invoking go generate in the current directory. - -//go:generate go run github.com/cilium/ebpf/internal/cmd/gentypes ../../btf/testdata/vmlinux.btf.gz diff --git a/vendor/github.com/cilium/ebpf/internal/sys/fd.go b/vendor/github.com/cilium/ebpf/internal/sys/fd.go deleted file mode 100644 index 65517d45..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/fd.go +++ /dev/null @@ -1,96 +0,0 @@ -package sys - -import ( - "fmt" - "math" - "os" - "runtime" - "strconv" - - "github.com/cilium/ebpf/internal/unix" -) - -var ErrClosedFd = unix.EBADF - -type FD struct { - raw int -} - -func newFD(value int) *FD { - fd := &FD{value} - runtime.SetFinalizer(fd, (*FD).Close) - return fd -} - -// NewFD wraps a raw fd with a finalizer. -// -// You must not use the raw fd after calling this function, since the underlying -// file descriptor number may change. This is because the BPF UAPI assumes that -// zero is not a valid fd value. -func NewFD(value int) (*FD, error) { - if value < 0 { - return nil, fmt.Errorf("invalid fd %d", value) - } - - fd := newFD(value) - if value != 0 { - return fd, nil - } - - dup, err := fd.Dup() - _ = fd.Close() - return dup, err -} - -func (fd *FD) String() string { - return strconv.FormatInt(int64(fd.raw), 10) -} - -func (fd *FD) Int() int { - return fd.raw -} - -func (fd *FD) Uint() uint32 { - if fd.raw < 0 || int64(fd.raw) > math.MaxUint32 { - // Best effort: this is the number most likely to be an invalid file - // descriptor. It is equal to -1 (on two's complement arches). - return math.MaxUint32 - } - return uint32(fd.raw) -} - -func (fd *FD) Close() error { - if fd.raw < 0 { - return nil - } - - value := int(fd.raw) - fd.raw = -1 - - fd.Forget() - return unix.Close(value) -} - -func (fd *FD) Forget() { - runtime.SetFinalizer(fd, nil) -} - -func (fd *FD) Dup() (*FD, error) { - if fd.raw < 0 { - return nil, ErrClosedFd - } - - // Always require the fd to be larger than zero: the BPF API treats the value - // as "no argument provided". - dup, err := unix.FcntlInt(uintptr(fd.raw), unix.F_DUPFD_CLOEXEC, 1) - if err != nil { - return nil, fmt.Errorf("can't dup fd: %v", err) - } - - return newFD(dup), nil -} - -func (fd *FD) File(name string) *os.File { - fd.Forget() - return os.NewFile(uintptr(fd.raw), name) -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/ptr.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr.go deleted file mode 100644 index a2210068..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/ptr.go +++ /dev/null @@ -1,38 +0,0 @@ -package sys - -import ( - "unsafe" - - "github.com/cilium/ebpf/internal/unix" -) - -// NewPointer creates a 64-bit pointer from an unsafe Pointer. -func NewPointer(ptr unsafe.Pointer) Pointer { - return Pointer{ptr: ptr} -} - -// NewSlicePointer creates a 64-bit pointer from a byte slice. -func NewSlicePointer(buf []byte) Pointer { - if len(buf) == 0 { - return Pointer{} - } - - return Pointer{ptr: unsafe.Pointer(&buf[0])} -} - -// NewSlicePointer creates a 64-bit pointer from a byte slice. -// -// Useful to assign both the pointer and the length in one go. -func NewSlicePointerLen(buf []byte) (Pointer, uint32) { - return NewSlicePointer(buf), uint32(len(buf)) -} - -// NewStringPointer creates a 64-bit pointer from a string. -func NewStringPointer(str string) Pointer { - p, err := unix.BytePtrFromString(str) - if err != nil { - return Pointer{} - } - - return Pointer{ptr: unsafe.Pointer(p)} -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_be.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_be.go deleted file mode 100644 index df903d78..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_be.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build armbe || mips || mips64p32 -// +build armbe mips mips64p32 - -package sys - -import ( - "unsafe" -) - -// Pointer wraps an unsafe.Pointer to be 64bit to -// conform to the syscall specification. -type Pointer struct { - pad uint32 - ptr unsafe.Pointer -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_le.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_le.go deleted file mode 100644 index a6a51edb..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/ptr_32_le.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build 386 || amd64p32 || arm || mipsle || mips64p32le -// +build 386 amd64p32 arm mipsle mips64p32le - -package sys - -import ( - "unsafe" -) - -// Pointer wraps an unsafe.Pointer to be 64bit to -// conform to the syscall specification. -type Pointer struct { - ptr unsafe.Pointer - pad uint32 -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/ptr_64.go b/vendor/github.com/cilium/ebpf/internal/sys/ptr_64.go deleted file mode 100644 index 7c0279e4..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/ptr_64.go +++ /dev/null @@ -1,14 +0,0 @@ -//go:build !386 && !amd64p32 && !arm && !mipsle && !mips64p32le && !armbe && !mips && !mips64p32 -// +build !386,!amd64p32,!arm,!mipsle,!mips64p32le,!armbe,!mips,!mips64p32 - -package sys - -import ( - "unsafe" -) - -// Pointer wraps an unsafe.Pointer to be 64bit to -// conform to the syscall specification. -type Pointer struct { - ptr unsafe.Pointer -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/syscall.go b/vendor/github.com/cilium/ebpf/internal/sys/syscall.go deleted file mode 100644 index 2a5935dc..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/syscall.go +++ /dev/null @@ -1,126 +0,0 @@ -package sys - -import ( - "runtime" - "syscall" - "unsafe" - - "github.com/cilium/ebpf/internal/unix" -) - -// BPF wraps SYS_BPF. -// -// Any pointers contained in attr must use the Pointer type from this package. -func BPF(cmd Cmd, attr unsafe.Pointer, size uintptr) (uintptr, error) { - for { - r1, _, errNo := unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size) - runtime.KeepAlive(attr) - - // As of ~4.20 the verifier can be interrupted by a signal, - // and returns EAGAIN in that case. - if errNo == unix.EAGAIN && cmd == BPF_PROG_LOAD { - continue - } - - var err error - if errNo != 0 { - err = wrappedErrno{errNo} - } - - return r1, err - } -} - -// Info is implemented by all structs that can be passed to the ObjInfo syscall. -// -// MapInfo -// ProgInfo -// LinkInfo -// BtfInfo -type Info interface { - info() (unsafe.Pointer, uint32) -} - -var _ Info = (*MapInfo)(nil) - -func (i *MapInfo) info() (unsafe.Pointer, uint32) { - return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) -} - -var _ Info = (*ProgInfo)(nil) - -func (i *ProgInfo) info() (unsafe.Pointer, uint32) { - return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) -} - -var _ Info = (*LinkInfo)(nil) - -func (i *LinkInfo) info() (unsafe.Pointer, uint32) { - return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) -} - -var _ Info = (*BtfInfo)(nil) - -func (i *BtfInfo) info() (unsafe.Pointer, uint32) { - return unsafe.Pointer(i), uint32(unsafe.Sizeof(*i)) -} - -// ObjInfo retrieves information about a BPF Fd. -// -// info may be one of MapInfo, ProgInfo, LinkInfo and BtfInfo. -func ObjInfo(fd *FD, info Info) error { - ptr, len := info.info() - err := ObjGetInfoByFd(&ObjGetInfoByFdAttr{ - BpfFd: fd.Uint(), - InfoLen: len, - Info: NewPointer(ptr), - }) - runtime.KeepAlive(fd) - return err -} - -// BPFObjName is a null-terminated string made up of -// 'A-Za-z0-9_' characters. -type ObjName [unix.BPF_OBJ_NAME_LEN]byte - -// NewObjName truncates the result if it is too long. -func NewObjName(name string) ObjName { - var result ObjName - copy(result[:unix.BPF_OBJ_NAME_LEN-1], name) - return result -} - -// LinkID uniquely identifies a bpf_link. -type LinkID uint32 - -// BTFID uniquely identifies a BTF blob loaded into the kernel. -type BTFID uint32 - -// wrappedErrno wraps syscall.Errno to prevent direct comparisons with -// syscall.E* or unix.E* constants. -// -// You should never export an error of this type. -type wrappedErrno struct { - syscall.Errno -} - -func (we wrappedErrno) Unwrap() error { - return we.Errno -} - -type syscallError struct { - error - errno syscall.Errno -} - -func Error(err error, errno syscall.Errno) error { - return &syscallError{err, errno} -} - -func (se *syscallError) Is(target error) bool { - return target == se.error -} - -func (se *syscallError) Unwrap() error { - return se.errno -} diff --git a/vendor/github.com/cilium/ebpf/internal/sys/types.go b/vendor/github.com/cilium/ebpf/internal/sys/types.go deleted file mode 100644 index 291e3a61..00000000 --- a/vendor/github.com/cilium/ebpf/internal/sys/types.go +++ /dev/null @@ -1,1052 +0,0 @@ -// Code generated by internal/cmd/gentypes; DO NOT EDIT. - -package sys - -import ( - "unsafe" -) - -type AdjRoomMode int32 - -const ( - BPF_ADJ_ROOM_NET AdjRoomMode = 0 - BPF_ADJ_ROOM_MAC AdjRoomMode = 1 -) - -type AttachType int32 - -const ( - BPF_CGROUP_INET_INGRESS AttachType = 0 - BPF_CGROUP_INET_EGRESS AttachType = 1 - BPF_CGROUP_INET_SOCK_CREATE AttachType = 2 - BPF_CGROUP_SOCK_OPS AttachType = 3 - BPF_SK_SKB_STREAM_PARSER AttachType = 4 - BPF_SK_SKB_STREAM_VERDICT AttachType = 5 - BPF_CGROUP_DEVICE AttachType = 6 - BPF_SK_MSG_VERDICT AttachType = 7 - BPF_CGROUP_INET4_BIND AttachType = 8 - BPF_CGROUP_INET6_BIND AttachType = 9 - BPF_CGROUP_INET4_CONNECT AttachType = 10 - BPF_CGROUP_INET6_CONNECT AttachType = 11 - BPF_CGROUP_INET4_POST_BIND AttachType = 12 - BPF_CGROUP_INET6_POST_BIND AttachType = 13 - BPF_CGROUP_UDP4_SENDMSG AttachType = 14 - BPF_CGROUP_UDP6_SENDMSG AttachType = 15 - BPF_LIRC_MODE2 AttachType = 16 - BPF_FLOW_DISSECTOR AttachType = 17 - BPF_CGROUP_SYSCTL AttachType = 18 - BPF_CGROUP_UDP4_RECVMSG AttachType = 19 - BPF_CGROUP_UDP6_RECVMSG AttachType = 20 - BPF_CGROUP_GETSOCKOPT AttachType = 21 - BPF_CGROUP_SETSOCKOPT AttachType = 22 - BPF_TRACE_RAW_TP AttachType = 23 - BPF_TRACE_FENTRY AttachType = 24 - BPF_TRACE_FEXIT AttachType = 25 - BPF_MODIFY_RETURN AttachType = 26 - BPF_LSM_MAC AttachType = 27 - BPF_TRACE_ITER AttachType = 28 - BPF_CGROUP_INET4_GETPEERNAME AttachType = 29 - BPF_CGROUP_INET6_GETPEERNAME AttachType = 30 - BPF_CGROUP_INET4_GETSOCKNAME AttachType = 31 - BPF_CGROUP_INET6_GETSOCKNAME AttachType = 32 - BPF_XDP_DEVMAP AttachType = 33 - BPF_CGROUP_INET_SOCK_RELEASE AttachType = 34 - BPF_XDP_CPUMAP AttachType = 35 - BPF_SK_LOOKUP AttachType = 36 - BPF_XDP AttachType = 37 - BPF_SK_SKB_VERDICT AttachType = 38 - BPF_SK_REUSEPORT_SELECT AttachType = 39 - BPF_SK_REUSEPORT_SELECT_OR_MIGRATE AttachType = 40 - BPF_PERF_EVENT AttachType = 41 - BPF_TRACE_KPROBE_MULTI AttachType = 42 - __MAX_BPF_ATTACH_TYPE AttachType = 43 -) - -type Cmd int32 - -const ( - BPF_MAP_CREATE Cmd = 0 - BPF_MAP_LOOKUP_ELEM Cmd = 1 - BPF_MAP_UPDATE_ELEM Cmd = 2 - BPF_MAP_DELETE_ELEM Cmd = 3 - BPF_MAP_GET_NEXT_KEY Cmd = 4 - BPF_PROG_LOAD Cmd = 5 - BPF_OBJ_PIN Cmd = 6 - BPF_OBJ_GET Cmd = 7 - BPF_PROG_ATTACH Cmd = 8 - BPF_PROG_DETACH Cmd = 9 - BPF_PROG_TEST_RUN Cmd = 10 - BPF_PROG_RUN Cmd = 10 - BPF_PROG_GET_NEXT_ID Cmd = 11 - BPF_MAP_GET_NEXT_ID Cmd = 12 - BPF_PROG_GET_FD_BY_ID Cmd = 13 - BPF_MAP_GET_FD_BY_ID Cmd = 14 - BPF_OBJ_GET_INFO_BY_FD Cmd = 15 - BPF_PROG_QUERY Cmd = 16 - BPF_RAW_TRACEPOINT_OPEN Cmd = 17 - BPF_BTF_LOAD Cmd = 18 - BPF_BTF_GET_FD_BY_ID Cmd = 19 - BPF_TASK_FD_QUERY Cmd = 20 - BPF_MAP_LOOKUP_AND_DELETE_ELEM Cmd = 21 - BPF_MAP_FREEZE Cmd = 22 - BPF_BTF_GET_NEXT_ID Cmd = 23 - BPF_MAP_LOOKUP_BATCH Cmd = 24 - BPF_MAP_LOOKUP_AND_DELETE_BATCH Cmd = 25 - BPF_MAP_UPDATE_BATCH Cmd = 26 - BPF_MAP_DELETE_BATCH Cmd = 27 - BPF_LINK_CREATE Cmd = 28 - BPF_LINK_UPDATE Cmd = 29 - BPF_LINK_GET_FD_BY_ID Cmd = 30 - BPF_LINK_GET_NEXT_ID Cmd = 31 - BPF_ENABLE_STATS Cmd = 32 - BPF_ITER_CREATE Cmd = 33 - BPF_LINK_DETACH Cmd = 34 - BPF_PROG_BIND_MAP Cmd = 35 -) - -type FunctionId int32 - -const ( - BPF_FUNC_unspec FunctionId = 0 - BPF_FUNC_map_lookup_elem FunctionId = 1 - BPF_FUNC_map_update_elem FunctionId = 2 - BPF_FUNC_map_delete_elem FunctionId = 3 - BPF_FUNC_probe_read FunctionId = 4 - BPF_FUNC_ktime_get_ns FunctionId = 5 - BPF_FUNC_trace_printk FunctionId = 6 - BPF_FUNC_get_prandom_u32 FunctionId = 7 - BPF_FUNC_get_smp_processor_id FunctionId = 8 - BPF_FUNC_skb_store_bytes FunctionId = 9 - BPF_FUNC_l3_csum_replace FunctionId = 10 - BPF_FUNC_l4_csum_replace FunctionId = 11 - BPF_FUNC_tail_call FunctionId = 12 - BPF_FUNC_clone_redirect FunctionId = 13 - BPF_FUNC_get_current_pid_tgid FunctionId = 14 - BPF_FUNC_get_current_uid_gid FunctionId = 15 - BPF_FUNC_get_current_comm FunctionId = 16 - BPF_FUNC_get_cgroup_classid FunctionId = 17 - BPF_FUNC_skb_vlan_push FunctionId = 18 - BPF_FUNC_skb_vlan_pop FunctionId = 19 - BPF_FUNC_skb_get_tunnel_key FunctionId = 20 - BPF_FUNC_skb_set_tunnel_key FunctionId = 21 - BPF_FUNC_perf_event_read FunctionId = 22 - BPF_FUNC_redirect FunctionId = 23 - BPF_FUNC_get_route_realm FunctionId = 24 - BPF_FUNC_perf_event_output FunctionId = 25 - BPF_FUNC_skb_load_bytes FunctionId = 26 - BPF_FUNC_get_stackid FunctionId = 27 - BPF_FUNC_csum_diff FunctionId = 28 - BPF_FUNC_skb_get_tunnel_opt FunctionId = 29 - BPF_FUNC_skb_set_tunnel_opt FunctionId = 30 - BPF_FUNC_skb_change_proto FunctionId = 31 - BPF_FUNC_skb_change_type FunctionId = 32 - BPF_FUNC_skb_under_cgroup FunctionId = 33 - BPF_FUNC_get_hash_recalc FunctionId = 34 - BPF_FUNC_get_current_task FunctionId = 35 - BPF_FUNC_probe_write_user FunctionId = 36 - BPF_FUNC_current_task_under_cgroup FunctionId = 37 - BPF_FUNC_skb_change_tail FunctionId = 38 - BPF_FUNC_skb_pull_data FunctionId = 39 - BPF_FUNC_csum_update FunctionId = 40 - BPF_FUNC_set_hash_invalid FunctionId = 41 - BPF_FUNC_get_numa_node_id FunctionId = 42 - BPF_FUNC_skb_change_head FunctionId = 43 - BPF_FUNC_xdp_adjust_head FunctionId = 44 - BPF_FUNC_probe_read_str FunctionId = 45 - BPF_FUNC_get_socket_cookie FunctionId = 46 - BPF_FUNC_get_socket_uid FunctionId = 47 - BPF_FUNC_set_hash FunctionId = 48 - BPF_FUNC_setsockopt FunctionId = 49 - BPF_FUNC_skb_adjust_room FunctionId = 50 - BPF_FUNC_redirect_map FunctionId = 51 - BPF_FUNC_sk_redirect_map FunctionId = 52 - BPF_FUNC_sock_map_update FunctionId = 53 - BPF_FUNC_xdp_adjust_meta FunctionId = 54 - BPF_FUNC_perf_event_read_value FunctionId = 55 - BPF_FUNC_perf_prog_read_value FunctionId = 56 - BPF_FUNC_getsockopt FunctionId = 57 - BPF_FUNC_override_return FunctionId = 58 - BPF_FUNC_sock_ops_cb_flags_set FunctionId = 59 - BPF_FUNC_msg_redirect_map FunctionId = 60 - BPF_FUNC_msg_apply_bytes FunctionId = 61 - BPF_FUNC_msg_cork_bytes FunctionId = 62 - BPF_FUNC_msg_pull_data FunctionId = 63 - BPF_FUNC_bind FunctionId = 64 - BPF_FUNC_xdp_adjust_tail FunctionId = 65 - BPF_FUNC_skb_get_xfrm_state FunctionId = 66 - BPF_FUNC_get_stack FunctionId = 67 - BPF_FUNC_skb_load_bytes_relative FunctionId = 68 - BPF_FUNC_fib_lookup FunctionId = 69 - BPF_FUNC_sock_hash_update FunctionId = 70 - BPF_FUNC_msg_redirect_hash FunctionId = 71 - BPF_FUNC_sk_redirect_hash FunctionId = 72 - BPF_FUNC_lwt_push_encap FunctionId = 73 - BPF_FUNC_lwt_seg6_store_bytes FunctionId = 74 - BPF_FUNC_lwt_seg6_adjust_srh FunctionId = 75 - BPF_FUNC_lwt_seg6_action FunctionId = 76 - BPF_FUNC_rc_repeat FunctionId = 77 - BPF_FUNC_rc_keydown FunctionId = 78 - BPF_FUNC_skb_cgroup_id FunctionId = 79 - BPF_FUNC_get_current_cgroup_id FunctionId = 80 - BPF_FUNC_get_local_storage FunctionId = 81 - BPF_FUNC_sk_select_reuseport FunctionId = 82 - BPF_FUNC_skb_ancestor_cgroup_id FunctionId = 83 - BPF_FUNC_sk_lookup_tcp FunctionId = 84 - BPF_FUNC_sk_lookup_udp FunctionId = 85 - BPF_FUNC_sk_release FunctionId = 86 - BPF_FUNC_map_push_elem FunctionId = 87 - BPF_FUNC_map_pop_elem FunctionId = 88 - BPF_FUNC_map_peek_elem FunctionId = 89 - BPF_FUNC_msg_push_data FunctionId = 90 - BPF_FUNC_msg_pop_data FunctionId = 91 - BPF_FUNC_rc_pointer_rel FunctionId = 92 - BPF_FUNC_spin_lock FunctionId = 93 - BPF_FUNC_spin_unlock FunctionId = 94 - BPF_FUNC_sk_fullsock FunctionId = 95 - BPF_FUNC_tcp_sock FunctionId = 96 - BPF_FUNC_skb_ecn_set_ce FunctionId = 97 - BPF_FUNC_get_listener_sock FunctionId = 98 - BPF_FUNC_skc_lookup_tcp FunctionId = 99 - BPF_FUNC_tcp_check_syncookie FunctionId = 100 - BPF_FUNC_sysctl_get_name FunctionId = 101 - BPF_FUNC_sysctl_get_current_value FunctionId = 102 - BPF_FUNC_sysctl_get_new_value FunctionId = 103 - BPF_FUNC_sysctl_set_new_value FunctionId = 104 - BPF_FUNC_strtol FunctionId = 105 - BPF_FUNC_strtoul FunctionId = 106 - BPF_FUNC_sk_storage_get FunctionId = 107 - BPF_FUNC_sk_storage_delete FunctionId = 108 - BPF_FUNC_send_signal FunctionId = 109 - BPF_FUNC_tcp_gen_syncookie FunctionId = 110 - BPF_FUNC_skb_output FunctionId = 111 - BPF_FUNC_probe_read_user FunctionId = 112 - BPF_FUNC_probe_read_kernel FunctionId = 113 - BPF_FUNC_probe_read_user_str FunctionId = 114 - BPF_FUNC_probe_read_kernel_str FunctionId = 115 - BPF_FUNC_tcp_send_ack FunctionId = 116 - BPF_FUNC_send_signal_thread FunctionId = 117 - BPF_FUNC_jiffies64 FunctionId = 118 - BPF_FUNC_read_branch_records FunctionId = 119 - BPF_FUNC_get_ns_current_pid_tgid FunctionId = 120 - BPF_FUNC_xdp_output FunctionId = 121 - BPF_FUNC_get_netns_cookie FunctionId = 122 - BPF_FUNC_get_current_ancestor_cgroup_id FunctionId = 123 - BPF_FUNC_sk_assign FunctionId = 124 - BPF_FUNC_ktime_get_boot_ns FunctionId = 125 - BPF_FUNC_seq_printf FunctionId = 126 - BPF_FUNC_seq_write FunctionId = 127 - BPF_FUNC_sk_cgroup_id FunctionId = 128 - BPF_FUNC_sk_ancestor_cgroup_id FunctionId = 129 - BPF_FUNC_ringbuf_output FunctionId = 130 - BPF_FUNC_ringbuf_reserve FunctionId = 131 - BPF_FUNC_ringbuf_submit FunctionId = 132 - BPF_FUNC_ringbuf_discard FunctionId = 133 - BPF_FUNC_ringbuf_query FunctionId = 134 - BPF_FUNC_csum_level FunctionId = 135 - BPF_FUNC_skc_to_tcp6_sock FunctionId = 136 - BPF_FUNC_skc_to_tcp_sock FunctionId = 137 - BPF_FUNC_skc_to_tcp_timewait_sock FunctionId = 138 - BPF_FUNC_skc_to_tcp_request_sock FunctionId = 139 - BPF_FUNC_skc_to_udp6_sock FunctionId = 140 - BPF_FUNC_get_task_stack FunctionId = 141 - BPF_FUNC_load_hdr_opt FunctionId = 142 - BPF_FUNC_store_hdr_opt FunctionId = 143 - BPF_FUNC_reserve_hdr_opt FunctionId = 144 - BPF_FUNC_inode_storage_get FunctionId = 145 - BPF_FUNC_inode_storage_delete FunctionId = 146 - BPF_FUNC_d_path FunctionId = 147 - BPF_FUNC_copy_from_user FunctionId = 148 - BPF_FUNC_snprintf_btf FunctionId = 149 - BPF_FUNC_seq_printf_btf FunctionId = 150 - BPF_FUNC_skb_cgroup_classid FunctionId = 151 - BPF_FUNC_redirect_neigh FunctionId = 152 - BPF_FUNC_per_cpu_ptr FunctionId = 153 - BPF_FUNC_this_cpu_ptr FunctionId = 154 - BPF_FUNC_redirect_peer FunctionId = 155 - BPF_FUNC_task_storage_get FunctionId = 156 - BPF_FUNC_task_storage_delete FunctionId = 157 - BPF_FUNC_get_current_task_btf FunctionId = 158 - BPF_FUNC_bprm_opts_set FunctionId = 159 - BPF_FUNC_ktime_get_coarse_ns FunctionId = 160 - BPF_FUNC_ima_inode_hash FunctionId = 161 - BPF_FUNC_sock_from_file FunctionId = 162 - BPF_FUNC_check_mtu FunctionId = 163 - BPF_FUNC_for_each_map_elem FunctionId = 164 - BPF_FUNC_snprintf FunctionId = 165 - BPF_FUNC_sys_bpf FunctionId = 166 - BPF_FUNC_btf_find_by_name_kind FunctionId = 167 - BPF_FUNC_sys_close FunctionId = 168 - BPF_FUNC_timer_init FunctionId = 169 - BPF_FUNC_timer_set_callback FunctionId = 170 - BPF_FUNC_timer_start FunctionId = 171 - BPF_FUNC_timer_cancel FunctionId = 172 - BPF_FUNC_get_func_ip FunctionId = 173 - BPF_FUNC_get_attach_cookie FunctionId = 174 - BPF_FUNC_task_pt_regs FunctionId = 175 - BPF_FUNC_get_branch_snapshot FunctionId = 176 - BPF_FUNC_trace_vprintk FunctionId = 177 - BPF_FUNC_skc_to_unix_sock FunctionId = 178 - BPF_FUNC_kallsyms_lookup_name FunctionId = 179 - BPF_FUNC_find_vma FunctionId = 180 - BPF_FUNC_loop FunctionId = 181 - BPF_FUNC_strncmp FunctionId = 182 - BPF_FUNC_get_func_arg FunctionId = 183 - BPF_FUNC_get_func_ret FunctionId = 184 - BPF_FUNC_get_func_arg_cnt FunctionId = 185 - BPF_FUNC_get_retval FunctionId = 186 - BPF_FUNC_set_retval FunctionId = 187 - BPF_FUNC_xdp_get_buff_len FunctionId = 188 - BPF_FUNC_xdp_load_bytes FunctionId = 189 - BPF_FUNC_xdp_store_bytes FunctionId = 190 - BPF_FUNC_copy_from_user_task FunctionId = 191 - BPF_FUNC_skb_set_tstamp FunctionId = 192 - BPF_FUNC_ima_file_hash FunctionId = 193 - __BPF_FUNC_MAX_ID FunctionId = 194 -) - -type HdrStartOff int32 - -const ( - BPF_HDR_START_MAC HdrStartOff = 0 - BPF_HDR_START_NET HdrStartOff = 1 -) - -type LinkType int32 - -const ( - BPF_LINK_TYPE_UNSPEC LinkType = 0 - BPF_LINK_TYPE_RAW_TRACEPOINT LinkType = 1 - BPF_LINK_TYPE_TRACING LinkType = 2 - BPF_LINK_TYPE_CGROUP LinkType = 3 - BPF_LINK_TYPE_ITER LinkType = 4 - BPF_LINK_TYPE_NETNS LinkType = 5 - BPF_LINK_TYPE_XDP LinkType = 6 - BPF_LINK_TYPE_PERF_EVENT LinkType = 7 - BPF_LINK_TYPE_KPROBE_MULTI LinkType = 8 - MAX_BPF_LINK_TYPE LinkType = 9 -) - -type MapType int32 - -const ( - BPF_MAP_TYPE_UNSPEC MapType = 0 - BPF_MAP_TYPE_HASH MapType = 1 - BPF_MAP_TYPE_ARRAY MapType = 2 - BPF_MAP_TYPE_PROG_ARRAY MapType = 3 - BPF_MAP_TYPE_PERF_EVENT_ARRAY MapType = 4 - BPF_MAP_TYPE_PERCPU_HASH MapType = 5 - BPF_MAP_TYPE_PERCPU_ARRAY MapType = 6 - BPF_MAP_TYPE_STACK_TRACE MapType = 7 - BPF_MAP_TYPE_CGROUP_ARRAY MapType = 8 - BPF_MAP_TYPE_LRU_HASH MapType = 9 - BPF_MAP_TYPE_LRU_PERCPU_HASH MapType = 10 - BPF_MAP_TYPE_LPM_TRIE MapType = 11 - BPF_MAP_TYPE_ARRAY_OF_MAPS MapType = 12 - BPF_MAP_TYPE_HASH_OF_MAPS MapType = 13 - BPF_MAP_TYPE_DEVMAP MapType = 14 - BPF_MAP_TYPE_SOCKMAP MapType = 15 - BPF_MAP_TYPE_CPUMAP MapType = 16 - BPF_MAP_TYPE_XSKMAP MapType = 17 - BPF_MAP_TYPE_SOCKHASH MapType = 18 - BPF_MAP_TYPE_CGROUP_STORAGE MapType = 19 - BPF_MAP_TYPE_REUSEPORT_SOCKARRAY MapType = 20 - BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE MapType = 21 - BPF_MAP_TYPE_QUEUE MapType = 22 - BPF_MAP_TYPE_STACK MapType = 23 - BPF_MAP_TYPE_SK_STORAGE MapType = 24 - BPF_MAP_TYPE_DEVMAP_HASH MapType = 25 - BPF_MAP_TYPE_STRUCT_OPS MapType = 26 - BPF_MAP_TYPE_RINGBUF MapType = 27 - BPF_MAP_TYPE_INODE_STORAGE MapType = 28 - BPF_MAP_TYPE_TASK_STORAGE MapType = 29 - BPF_MAP_TYPE_BLOOM_FILTER MapType = 30 -) - -type ProgType int32 - -const ( - BPF_PROG_TYPE_UNSPEC ProgType = 0 - BPF_PROG_TYPE_SOCKET_FILTER ProgType = 1 - BPF_PROG_TYPE_KPROBE ProgType = 2 - BPF_PROG_TYPE_SCHED_CLS ProgType = 3 - BPF_PROG_TYPE_SCHED_ACT ProgType = 4 - BPF_PROG_TYPE_TRACEPOINT ProgType = 5 - BPF_PROG_TYPE_XDP ProgType = 6 - BPF_PROG_TYPE_PERF_EVENT ProgType = 7 - BPF_PROG_TYPE_CGROUP_SKB ProgType = 8 - BPF_PROG_TYPE_CGROUP_SOCK ProgType = 9 - BPF_PROG_TYPE_LWT_IN ProgType = 10 - BPF_PROG_TYPE_LWT_OUT ProgType = 11 - BPF_PROG_TYPE_LWT_XMIT ProgType = 12 - BPF_PROG_TYPE_SOCK_OPS ProgType = 13 - BPF_PROG_TYPE_SK_SKB ProgType = 14 - BPF_PROG_TYPE_CGROUP_DEVICE ProgType = 15 - BPF_PROG_TYPE_SK_MSG ProgType = 16 - BPF_PROG_TYPE_RAW_TRACEPOINT ProgType = 17 - BPF_PROG_TYPE_CGROUP_SOCK_ADDR ProgType = 18 - BPF_PROG_TYPE_LWT_SEG6LOCAL ProgType = 19 - BPF_PROG_TYPE_LIRC_MODE2 ProgType = 20 - BPF_PROG_TYPE_SK_REUSEPORT ProgType = 21 - BPF_PROG_TYPE_FLOW_DISSECTOR ProgType = 22 - BPF_PROG_TYPE_CGROUP_SYSCTL ProgType = 23 - BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE ProgType = 24 - BPF_PROG_TYPE_CGROUP_SOCKOPT ProgType = 25 - BPF_PROG_TYPE_TRACING ProgType = 26 - BPF_PROG_TYPE_STRUCT_OPS ProgType = 27 - BPF_PROG_TYPE_EXT ProgType = 28 - BPF_PROG_TYPE_LSM ProgType = 29 - BPF_PROG_TYPE_SK_LOOKUP ProgType = 30 - BPF_PROG_TYPE_SYSCALL ProgType = 31 -) - -type RetCode int32 - -const ( - BPF_OK RetCode = 0 - BPF_DROP RetCode = 2 - BPF_REDIRECT RetCode = 7 - BPF_LWT_REROUTE RetCode = 128 -) - -type SkAction int32 - -const ( - SK_DROP SkAction = 0 - SK_PASS SkAction = 1 -) - -type StackBuildIdStatus int32 - -const ( - BPF_STACK_BUILD_ID_EMPTY StackBuildIdStatus = 0 - BPF_STACK_BUILD_ID_VALID StackBuildIdStatus = 1 - BPF_STACK_BUILD_ID_IP StackBuildIdStatus = 2 -) - -type StatsType int32 - -const ( - BPF_STATS_RUN_TIME StatsType = 0 -) - -type XdpAction int32 - -const ( - XDP_ABORTED XdpAction = 0 - XDP_DROP XdpAction = 1 - XDP_PASS XdpAction = 2 - XDP_TX XdpAction = 3 - XDP_REDIRECT XdpAction = 4 -) - -type BtfInfo struct { - Btf Pointer - BtfSize uint32 - Id BTFID - Name Pointer - NameLen uint32 - KernelBtf uint32 -} - -type FuncInfo struct { - InsnOff uint32 - TypeId uint32 -} - -type LineInfo struct { - InsnOff uint32 - FileNameOff uint32 - LineOff uint32 - LineCol uint32 -} - -type LinkInfo struct { - Type LinkType - Id LinkID - ProgId uint32 - _ [4]byte - Extra [16]uint8 -} - -type MapInfo struct { - Type uint32 - Id uint32 - KeySize uint32 - ValueSize uint32 - MaxEntries uint32 - MapFlags uint32 - Name ObjName - Ifindex uint32 - BtfVmlinuxValueTypeId uint32 - NetnsDev uint64 - NetnsIno uint64 - BtfId uint32 - BtfKeyTypeId uint32 - BtfValueTypeId uint32 - _ [4]byte - MapExtra uint64 -} - -type ProgInfo struct { - Type uint32 - Id uint32 - Tag [8]uint8 - JitedProgLen uint32 - XlatedProgLen uint32 - JitedProgInsns uint64 - XlatedProgInsns Pointer - LoadTime uint64 - CreatedByUid uint32 - NrMapIds uint32 - MapIds Pointer - Name ObjName - Ifindex uint32 - _ [4]byte /* unsupported bitfield */ - NetnsDev uint64 - NetnsIno uint64 - NrJitedKsyms uint32 - NrJitedFuncLens uint32 - JitedKsyms uint64 - JitedFuncLens uint64 - BtfId uint32 - FuncInfoRecSize uint32 - FuncInfo uint64 - NrFuncInfo uint32 - NrLineInfo uint32 - LineInfo uint64 - JitedLineInfo uint64 - NrJitedLineInfo uint32 - LineInfoRecSize uint32 - JitedLineInfoRecSize uint32 - NrProgTags uint32 - ProgTags uint64 - RunTimeNs uint64 - RunCnt uint64 - RecursionMisses uint64 - VerifiedInsns uint32 - _ [4]byte -} - -type SkLookup struct { - Cookie uint64 - Family uint32 - Protocol uint32 - RemoteIp4 [4]uint8 - RemoteIp6 [16]uint8 - RemotePort uint16 - _ [2]byte - LocalIp4 [4]uint8 - LocalIp6 [16]uint8 - LocalPort uint32 - IngressIfindex uint32 - _ [4]byte -} - -type XdpMd struct { - Data uint32 - DataEnd uint32 - DataMeta uint32 - IngressIfindex uint32 - RxQueueIndex uint32 - EgressIfindex uint32 -} - -type BtfGetFdByIdAttr struct{ Id uint32 } - -func BtfGetFdById(attr *BtfGetFdByIdAttr) (*FD, error) { - fd, err := BPF(BPF_BTF_GET_FD_BY_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type BtfGetNextIdAttr struct { - Id BTFID - NextId BTFID -} - -func BtfGetNextId(attr *BtfGetNextIdAttr) error { - _, err := BPF(BPF_BTF_GET_NEXT_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type BtfLoadAttr struct { - Btf Pointer - BtfLogBuf Pointer - BtfSize uint32 - BtfLogSize uint32 - BtfLogLevel uint32 - _ [4]byte -} - -func BtfLoad(attr *BtfLoadAttr) (*FD, error) { - fd, err := BPF(BPF_BTF_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type EnableStatsAttr struct{ Type uint32 } - -func EnableStats(attr *EnableStatsAttr) (*FD, error) { - fd, err := BPF(BPF_ENABLE_STATS, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type IterCreateAttr struct { - LinkFd uint32 - Flags uint32 -} - -func IterCreate(attr *IterCreateAttr) (*FD, error) { - fd, err := BPF(BPF_ITER_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type LinkCreateAttr struct { - ProgFd uint32 - TargetFd uint32 - AttachType AttachType - Flags uint32 - TargetBtfId uint32 - _ [28]byte -} - -func LinkCreate(attr *LinkCreateAttr) (*FD, error) { - fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type LinkCreateIterAttr struct { - ProgFd uint32 - TargetFd uint32 - AttachType AttachType - Flags uint32 - IterInfo Pointer - IterInfoLen uint32 - _ [20]byte -} - -func LinkCreateIter(attr *LinkCreateIterAttr) (*FD, error) { - fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type LinkCreatePerfEventAttr struct { - ProgFd uint32 - TargetFd uint32 - AttachType AttachType - Flags uint32 - BpfCookie uint64 - _ [24]byte -} - -func LinkCreatePerfEvent(attr *LinkCreatePerfEventAttr) (*FD, error) { - fd, err := BPF(BPF_LINK_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type LinkUpdateAttr struct { - LinkFd uint32 - NewProgFd uint32 - Flags uint32 - OldProgFd uint32 -} - -func LinkUpdate(attr *LinkUpdateAttr) error { - _, err := BPF(BPF_LINK_UPDATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapCreateAttr struct { - MapType MapType - KeySize uint32 - ValueSize uint32 - MaxEntries uint32 - MapFlags uint32 - InnerMapFd uint32 - NumaNode uint32 - MapName ObjName - MapIfindex uint32 - BtfFd uint32 - BtfKeyTypeId uint32 - BtfValueTypeId uint32 - BtfVmlinuxValueTypeId uint32 - MapExtra uint64 -} - -func MapCreate(attr *MapCreateAttr) (*FD, error) { - fd, err := BPF(BPF_MAP_CREATE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type MapDeleteBatchAttr struct { - InBatch Pointer - OutBatch Pointer - Keys Pointer - Values Pointer - Count uint32 - MapFd uint32 - ElemFlags uint64 - Flags uint64 -} - -func MapDeleteBatch(attr *MapDeleteBatchAttr) error { - _, err := BPF(BPF_MAP_DELETE_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapDeleteElemAttr struct { - MapFd uint32 - _ [4]byte - Key Pointer - Value Pointer - Flags uint64 -} - -func MapDeleteElem(attr *MapDeleteElemAttr) error { - _, err := BPF(BPF_MAP_DELETE_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapFreezeAttr struct{ MapFd uint32 } - -func MapFreeze(attr *MapFreezeAttr) error { - _, err := BPF(BPF_MAP_FREEZE, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapGetFdByIdAttr struct{ Id uint32 } - -func MapGetFdById(attr *MapGetFdByIdAttr) (*FD, error) { - fd, err := BPF(BPF_MAP_GET_FD_BY_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type MapGetNextIdAttr struct { - Id uint32 - NextId uint32 -} - -func MapGetNextId(attr *MapGetNextIdAttr) error { - _, err := BPF(BPF_MAP_GET_NEXT_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapGetNextKeyAttr struct { - MapFd uint32 - _ [4]byte - Key Pointer - NextKey Pointer -} - -func MapGetNextKey(attr *MapGetNextKeyAttr) error { - _, err := BPF(BPF_MAP_GET_NEXT_KEY, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapLookupAndDeleteBatchAttr struct { - InBatch Pointer - OutBatch Pointer - Keys Pointer - Values Pointer - Count uint32 - MapFd uint32 - ElemFlags uint64 - Flags uint64 -} - -func MapLookupAndDeleteBatch(attr *MapLookupAndDeleteBatchAttr) error { - _, err := BPF(BPF_MAP_LOOKUP_AND_DELETE_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapLookupAndDeleteElemAttr struct { - MapFd uint32 - _ [4]byte - Key Pointer - Value Pointer - Flags uint64 -} - -func MapLookupAndDeleteElem(attr *MapLookupAndDeleteElemAttr) error { - _, err := BPF(BPF_MAP_LOOKUP_AND_DELETE_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapLookupBatchAttr struct { - InBatch Pointer - OutBatch Pointer - Keys Pointer - Values Pointer - Count uint32 - MapFd uint32 - ElemFlags uint64 - Flags uint64 -} - -func MapLookupBatch(attr *MapLookupBatchAttr) error { - _, err := BPF(BPF_MAP_LOOKUP_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapLookupElemAttr struct { - MapFd uint32 - _ [4]byte - Key Pointer - Value Pointer - Flags uint64 -} - -func MapLookupElem(attr *MapLookupElemAttr) error { - _, err := BPF(BPF_MAP_LOOKUP_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapUpdateBatchAttr struct { - InBatch Pointer - OutBatch Pointer - Keys Pointer - Values Pointer - Count uint32 - MapFd uint32 - ElemFlags uint64 - Flags uint64 -} - -func MapUpdateBatch(attr *MapUpdateBatchAttr) error { - _, err := BPF(BPF_MAP_UPDATE_BATCH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type MapUpdateElemAttr struct { - MapFd uint32 - _ [4]byte - Key Pointer - Value Pointer - Flags uint64 -} - -func MapUpdateElem(attr *MapUpdateElemAttr) error { - _, err := BPF(BPF_MAP_UPDATE_ELEM, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type ObjGetAttr struct { - Pathname Pointer - BpfFd uint32 - FileFlags uint32 -} - -func ObjGet(attr *ObjGetAttr) (*FD, error) { - fd, err := BPF(BPF_OBJ_GET, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type ObjGetInfoByFdAttr struct { - BpfFd uint32 - InfoLen uint32 - Info Pointer -} - -func ObjGetInfoByFd(attr *ObjGetInfoByFdAttr) error { - _, err := BPF(BPF_OBJ_GET_INFO_BY_FD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type ObjPinAttr struct { - Pathname Pointer - BpfFd uint32 - FileFlags uint32 -} - -func ObjPin(attr *ObjPinAttr) error { - _, err := BPF(BPF_OBJ_PIN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type ProgAttachAttr struct { - TargetFd uint32 - AttachBpfFd uint32 - AttachType uint32 - AttachFlags uint32 - ReplaceBpfFd uint32 -} - -func ProgAttach(attr *ProgAttachAttr) error { - _, err := BPF(BPF_PROG_ATTACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type ProgBindMapAttr struct { - ProgFd uint32 - MapFd uint32 - Flags uint32 -} - -func ProgBindMap(attr *ProgBindMapAttr) error { - _, err := BPF(BPF_PROG_BIND_MAP, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type ProgDetachAttr struct { - TargetFd uint32 - AttachBpfFd uint32 - AttachType uint32 -} - -func ProgDetach(attr *ProgDetachAttr) error { - _, err := BPF(BPF_PROG_DETACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type ProgGetFdByIdAttr struct{ Id uint32 } - -func ProgGetFdById(attr *ProgGetFdByIdAttr) (*FD, error) { - fd, err := BPF(BPF_PROG_GET_FD_BY_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type ProgGetNextIdAttr struct { - Id uint32 - NextId uint32 -} - -func ProgGetNextId(attr *ProgGetNextIdAttr) error { - _, err := BPF(BPF_PROG_GET_NEXT_ID, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type ProgLoadAttr struct { - ProgType ProgType - InsnCnt uint32 - Insns Pointer - License Pointer - LogLevel uint32 - LogSize uint32 - LogBuf Pointer - KernVersion uint32 - ProgFlags uint32 - ProgName ObjName - ProgIfindex uint32 - ExpectedAttachType AttachType - ProgBtfFd uint32 - FuncInfoRecSize uint32 - FuncInfo Pointer - FuncInfoCnt uint32 - LineInfoRecSize uint32 - LineInfo Pointer - LineInfoCnt uint32 - AttachBtfId uint32 - AttachProgFd uint32 - CoreReloCnt uint32 - FdArray Pointer - CoreRelos Pointer - CoreReloRecSize uint32 - _ [4]byte -} - -func ProgLoad(attr *ProgLoadAttr) (*FD, error) { - fd, err := BPF(BPF_PROG_LOAD, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type ProgRunAttr struct { - ProgFd uint32 - Retval uint32 - DataSizeIn uint32 - DataSizeOut uint32 - DataIn Pointer - DataOut Pointer - Repeat uint32 - Duration uint32 - CtxSizeIn uint32 - CtxSizeOut uint32 - CtxIn Pointer - CtxOut Pointer - Flags uint32 - Cpu uint32 - BatchSize uint32 - _ [4]byte -} - -func ProgRun(attr *ProgRunAttr) error { - _, err := BPF(BPF_PROG_TEST_RUN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - return err -} - -type RawTracepointOpenAttr struct { - Name Pointer - ProgFd uint32 - _ [4]byte -} - -func RawTracepointOpen(attr *RawTracepointOpenAttr) (*FD, error) { - fd, err := BPF(BPF_RAW_TRACEPOINT_OPEN, unsafe.Pointer(attr), unsafe.Sizeof(*attr)) - if err != nil { - return nil, err - } - return NewFD(int(fd)) -} - -type CgroupLinkInfo struct { - CgroupId uint64 - AttachType AttachType - _ [4]byte -} - -type IterLinkInfo struct { - TargetName Pointer - TargetNameLen uint32 -} - -type NetNsLinkInfo struct { - NetnsIno uint32 - AttachType AttachType -} - -type RawTracepointLinkInfo struct { - TpName Pointer - TpNameLen uint32 - _ [4]byte -} - -type TracingLinkInfo struct { - AttachType AttachType - TargetObjId uint32 - TargetBtfId uint32 -} - -type XDPLinkInfo struct{ Ifindex uint32 } diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go b/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go deleted file mode 100644 index db4a1f5b..00000000 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_linux.go +++ /dev/null @@ -1,210 +0,0 @@ -//go:build linux -// +build linux - -package unix - -import ( - "syscall" - - linux "golang.org/x/sys/unix" -) - -const ( - ENOENT = linux.ENOENT - EEXIST = linux.EEXIST - EAGAIN = linux.EAGAIN - ENOSPC = linux.ENOSPC - EINVAL = linux.EINVAL - EPOLLIN = linux.EPOLLIN - EINTR = linux.EINTR - EPERM = linux.EPERM - ESRCH = linux.ESRCH - ENODEV = linux.ENODEV - EBADF = linux.EBADF - E2BIG = linux.E2BIG - EFAULT = linux.EFAULT - EACCES = linux.EACCES - // ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP - ENOTSUPP = syscall.Errno(0x20c) - - BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC - BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE - BPF_F_RDONLY = linux.BPF_F_RDONLY - BPF_F_WRONLY = linux.BPF_F_WRONLY - BPF_F_RDONLY_PROG = linux.BPF_F_RDONLY_PROG - BPF_F_WRONLY_PROG = linux.BPF_F_WRONLY_PROG - BPF_F_SLEEPABLE = linux.BPF_F_SLEEPABLE - BPF_F_MMAPABLE = linux.BPF_F_MMAPABLE - BPF_F_INNER_MAP = linux.BPF_F_INNER_MAP - BPF_OBJ_NAME_LEN = linux.BPF_OBJ_NAME_LEN - BPF_TAG_SIZE = linux.BPF_TAG_SIZE - BPF_RINGBUF_BUSY_BIT = linux.BPF_RINGBUF_BUSY_BIT - BPF_RINGBUF_DISCARD_BIT = linux.BPF_RINGBUF_DISCARD_BIT - BPF_RINGBUF_HDR_SZ = linux.BPF_RINGBUF_HDR_SZ - SYS_BPF = linux.SYS_BPF - F_DUPFD_CLOEXEC = linux.F_DUPFD_CLOEXEC - EPOLL_CTL_ADD = linux.EPOLL_CTL_ADD - EPOLL_CLOEXEC = linux.EPOLL_CLOEXEC - O_CLOEXEC = linux.O_CLOEXEC - O_NONBLOCK = linux.O_NONBLOCK - PROT_READ = linux.PROT_READ - PROT_WRITE = linux.PROT_WRITE - MAP_SHARED = linux.MAP_SHARED - PERF_ATTR_SIZE_VER1 = linux.PERF_ATTR_SIZE_VER1 - PERF_TYPE_SOFTWARE = linux.PERF_TYPE_SOFTWARE - PERF_TYPE_TRACEPOINT = linux.PERF_TYPE_TRACEPOINT - PERF_COUNT_SW_BPF_OUTPUT = linux.PERF_COUNT_SW_BPF_OUTPUT - PERF_EVENT_IOC_DISABLE = linux.PERF_EVENT_IOC_DISABLE - PERF_EVENT_IOC_ENABLE = linux.PERF_EVENT_IOC_ENABLE - PERF_EVENT_IOC_SET_BPF = linux.PERF_EVENT_IOC_SET_BPF - PerfBitWatermark = linux.PerfBitWatermark - PERF_SAMPLE_RAW = linux.PERF_SAMPLE_RAW - PERF_FLAG_FD_CLOEXEC = linux.PERF_FLAG_FD_CLOEXEC - RLIM_INFINITY = linux.RLIM_INFINITY - RLIMIT_MEMLOCK = linux.RLIMIT_MEMLOCK - BPF_STATS_RUN_TIME = linux.BPF_STATS_RUN_TIME - PERF_RECORD_LOST = linux.PERF_RECORD_LOST - PERF_RECORD_SAMPLE = linux.PERF_RECORD_SAMPLE - AT_FDCWD = linux.AT_FDCWD - RENAME_NOREPLACE = linux.RENAME_NOREPLACE - SO_ATTACH_BPF = linux.SO_ATTACH_BPF - SO_DETACH_BPF = linux.SO_DETACH_BPF - SOL_SOCKET = linux.SOL_SOCKET -) - -// Statfs_t is a wrapper -type Statfs_t = linux.Statfs_t - -type Stat_t = linux.Stat_t - -// Rlimit is a wrapper -type Rlimit = linux.Rlimit - -// Syscall is a wrapper -func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { - return linux.Syscall(trap, a1, a2, a3) -} - -// FcntlInt is a wrapper -func FcntlInt(fd uintptr, cmd, arg int) (int, error) { - return linux.FcntlInt(fd, cmd, arg) -} - -// IoctlSetInt is a wrapper -func IoctlSetInt(fd int, req uint, value int) error { - return linux.IoctlSetInt(fd, req, value) -} - -// Statfs is a wrapper -func Statfs(path string, buf *Statfs_t) (err error) { - return linux.Statfs(path, buf) -} - -// Close is a wrapper -func Close(fd int) (err error) { - return linux.Close(fd) -} - -// EpollEvent is a wrapper -type EpollEvent = linux.EpollEvent - -// EpollWait is a wrapper -func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { - return linux.EpollWait(epfd, events, msec) -} - -// EpollCtl is a wrapper -func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { - return linux.EpollCtl(epfd, op, fd, event) -} - -// Eventfd is a wrapper -func Eventfd(initval uint, flags int) (fd int, err error) { - return linux.Eventfd(initval, flags) -} - -// Write is a wrapper -func Write(fd int, p []byte) (n int, err error) { - return linux.Write(fd, p) -} - -// EpollCreate1 is a wrapper -func EpollCreate1(flag int) (fd int, err error) { - return linux.EpollCreate1(flag) -} - -// PerfEventMmapPage is a wrapper -type PerfEventMmapPage linux.PerfEventMmapPage - -// SetNonblock is a wrapper -func SetNonblock(fd int, nonblocking bool) (err error) { - return linux.SetNonblock(fd, nonblocking) -} - -// Mmap is a wrapper -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return linux.Mmap(fd, offset, length, prot, flags) -} - -// Munmap is a wrapper -func Munmap(b []byte) (err error) { - return linux.Munmap(b) -} - -// PerfEventAttr is a wrapper -type PerfEventAttr = linux.PerfEventAttr - -// PerfEventOpen is a wrapper -func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { - return linux.PerfEventOpen(attr, pid, cpu, groupFd, flags) -} - -// Utsname is a wrapper -type Utsname = linux.Utsname - -// Uname is a wrapper -func Uname(buf *Utsname) (err error) { - return linux.Uname(buf) -} - -// Getpid is a wrapper -func Getpid() int { - return linux.Getpid() -} - -// Gettid is a wrapper -func Gettid() int { - return linux.Gettid() -} - -// Tgkill is a wrapper -func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { - return linux.Tgkill(tgid, tid, sig) -} - -// BytePtrFromString is a wrapper -func BytePtrFromString(s string) (*byte, error) { - return linux.BytePtrFromString(s) -} - -// ByteSliceToString is a wrapper -func ByteSliceToString(s []byte) string { - return linux.ByteSliceToString(s) -} - -// Renameat2 is a wrapper -func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error { - return linux.Renameat2(olddirfd, oldpath, newdirfd, newpath, flags) -} - -func Prlimit(pid, resource int, new, old *Rlimit) error { - return linux.Prlimit(pid, resource, new, old) -} - -func Open(path string, mode int, perm uint32) (int, error) { - return linux.Open(path, mode, perm) -} - -func Fstat(fd int, stat *Stat_t) error { - return linux.Fstat(fd, stat) -} diff --git a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go b/vendor/github.com/cilium/ebpf/internal/unix/types_other.go deleted file mode 100644 index 133c267d..00000000 --- a/vendor/github.com/cilium/ebpf/internal/unix/types_other.go +++ /dev/null @@ -1,278 +0,0 @@ -//go:build !linux -// +build !linux - -package unix - -import ( - "fmt" - "runtime" - "syscall" -) - -var errNonLinux = fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH) - -const ( - ENOENT = syscall.ENOENT - EEXIST = syscall.EEXIST - EAGAIN = syscall.EAGAIN - ENOSPC = syscall.ENOSPC - EINVAL = syscall.EINVAL - EINTR = syscall.EINTR - EPERM = syscall.EPERM - ESRCH = syscall.ESRCH - ENODEV = syscall.ENODEV - EBADF = syscall.Errno(0) - E2BIG = syscall.Errno(0) - EFAULT = syscall.EFAULT - EACCES = syscall.Errno(0) - // ENOTSUPP is not the same as ENOTSUP or EOPNOTSUP - ENOTSUPP = syscall.Errno(0x20c) - - BPF_F_NO_PREALLOC = 0 - BPF_F_NUMA_NODE = 0 - BPF_F_RDONLY = 0 - BPF_F_WRONLY = 0 - BPF_F_RDONLY_PROG = 0 - BPF_F_WRONLY_PROG = 0 - BPF_F_SLEEPABLE = 0 - BPF_F_MMAPABLE = 0 - BPF_F_INNER_MAP = 0 - BPF_OBJ_NAME_LEN = 0x10 - BPF_TAG_SIZE = 0x8 - BPF_RINGBUF_BUSY_BIT = 0 - BPF_RINGBUF_DISCARD_BIT = 0 - BPF_RINGBUF_HDR_SZ = 0 - SYS_BPF = 321 - F_DUPFD_CLOEXEC = 0x406 - EPOLLIN = 0x1 - EPOLL_CTL_ADD = 0x1 - EPOLL_CLOEXEC = 0x80000 - O_CLOEXEC = 0x80000 - O_NONBLOCK = 0x800 - PROT_READ = 0x1 - PROT_WRITE = 0x2 - MAP_SHARED = 0x1 - PERF_ATTR_SIZE_VER1 = 0 - PERF_TYPE_SOFTWARE = 0x1 - PERF_TYPE_TRACEPOINT = 0 - PERF_COUNT_SW_BPF_OUTPUT = 0xa - PERF_EVENT_IOC_DISABLE = 0 - PERF_EVENT_IOC_ENABLE = 0 - PERF_EVENT_IOC_SET_BPF = 0 - PerfBitWatermark = 0x4000 - PERF_SAMPLE_RAW = 0x400 - PERF_FLAG_FD_CLOEXEC = 0x8 - RLIM_INFINITY = 0x7fffffffffffffff - RLIMIT_MEMLOCK = 8 - BPF_STATS_RUN_TIME = 0 - PERF_RECORD_LOST = 2 - PERF_RECORD_SAMPLE = 9 - AT_FDCWD = -0x2 - RENAME_NOREPLACE = 0x1 - SO_ATTACH_BPF = 0x32 - SO_DETACH_BPF = 0x1b - SOL_SOCKET = 0x1 -) - -// Statfs_t is a wrapper -type Statfs_t struct { - Type int64 - Bsize int64 - Blocks uint64 - Bfree uint64 - Bavail uint64 - Files uint64 - Ffree uint64 - Fsid [2]int32 - Namelen int64 - Frsize int64 - Flags int64 - Spare [4]int64 -} - -type Stat_t struct{} - -// Rlimit is a wrapper -type Rlimit struct { - Cur uint64 - Max uint64 -} - -// Syscall is a wrapper -func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) { - return 0, 0, syscall.Errno(1) -} - -// FcntlInt is a wrapper -func FcntlInt(fd uintptr, cmd, arg int) (int, error) { - return -1, errNonLinux -} - -// IoctlSetInt is a wrapper -func IoctlSetInt(fd int, req uint, value int) error { - return errNonLinux -} - -// Statfs is a wrapper -func Statfs(path string, buf *Statfs_t) error { - return errNonLinux -} - -// Close is a wrapper -func Close(fd int) (err error) { - return errNonLinux -} - -// EpollEvent is a wrapper -type EpollEvent struct { - Events uint32 - Fd int32 - Pad int32 -} - -// EpollWait is a wrapper -func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { - return 0, errNonLinux -} - -// EpollCtl is a wrapper -func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { - return errNonLinux -} - -// Eventfd is a wrapper -func Eventfd(initval uint, flags int) (fd int, err error) { - return 0, errNonLinux -} - -// Write is a wrapper -func Write(fd int, p []byte) (n int, err error) { - return 0, errNonLinux -} - -// EpollCreate1 is a wrapper -func EpollCreate1(flag int) (fd int, err error) { - return 0, errNonLinux -} - -// PerfEventMmapPage is a wrapper -type PerfEventMmapPage struct { - Version uint32 - Compat_version uint32 - Lock uint32 - Index uint32 - Offset int64 - Time_enabled uint64 - Time_running uint64 - Capabilities uint64 - Pmc_width uint16 - Time_shift uint16 - Time_mult uint32 - Time_offset uint64 - Time_zero uint64 - Size uint32 - - Data_head uint64 - Data_tail uint64 - Data_offset uint64 - Data_size uint64 - Aux_head uint64 - Aux_tail uint64 - Aux_offset uint64 - Aux_size uint64 -} - -// SetNonblock is a wrapper -func SetNonblock(fd int, nonblocking bool) (err error) { - return errNonLinux -} - -// Mmap is a wrapper -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return []byte{}, errNonLinux -} - -// Munmap is a wrapper -func Munmap(b []byte) (err error) { - return errNonLinux -} - -// PerfEventAttr is a wrapper -type PerfEventAttr struct { - Type uint32 - Size uint32 - Config uint64 - Sample uint64 - Sample_type uint64 - Read_format uint64 - Bits uint64 - Wakeup uint32 - Bp_type uint32 - Ext1 uint64 - Ext2 uint64 - Branch_sample_type uint64 - Sample_regs_user uint64 - Sample_stack_user uint32 - Clockid int32 - Sample_regs_intr uint64 - Aux_watermark uint32 - Sample_max_stack uint16 -} - -// PerfEventOpen is a wrapper -func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { - return 0, errNonLinux -} - -// Utsname is a wrapper -type Utsname struct { - Release [65]byte - Version [65]byte -} - -// Uname is a wrapper -func Uname(buf *Utsname) (err error) { - return errNonLinux -} - -// Getpid is a wrapper -func Getpid() int { - return -1 -} - -// Gettid is a wrapper -func Gettid() int { - return -1 -} - -// Tgkill is a wrapper -func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { - return errNonLinux -} - -// BytePtrFromString is a wrapper -func BytePtrFromString(s string) (*byte, error) { - return nil, errNonLinux -} - -// ByteSliceToString is a wrapper -func ByteSliceToString(s []byte) string { - return "" -} - -// Renameat2 is a wrapper -func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error { - return errNonLinux -} - -func Prlimit(pid, resource int, new, old *Rlimit) error { - return errNonLinux -} - -func Open(path string, mode int, perm uint32) (int, error) { - return -1, errNonLinux -} - -func Fstat(fd int, stat *Stat_t) error { - return errNonLinux -} diff --git a/vendor/github.com/cilium/ebpf/internal/vdso.go b/vendor/github.com/cilium/ebpf/internal/vdso.go deleted file mode 100644 index ae4821de..00000000 --- a/vendor/github.com/cilium/ebpf/internal/vdso.go +++ /dev/null @@ -1,150 +0,0 @@ -package internal - -import ( - "debug/elf" - "encoding/binary" - "errors" - "fmt" - "io" - "math" - "os" - - "github.com/cilium/ebpf/internal/unix" -) - -var ( - errAuxvNoVDSO = errors.New("no vdso address found in auxv") -) - -// vdsoVersion returns the LINUX_VERSION_CODE embedded in the vDSO library -// linked into the current process image. -func vdsoVersion() (uint32, error) { - // Read data from the auxiliary vector, which is normally passed directly - // to the process. Go does not expose that data, so we must read it from procfs. - // https://man7.org/linux/man-pages/man3/getauxval.3.html - av, err := os.Open("/proc/self/auxv") - if err != nil { - return 0, fmt.Errorf("opening auxv: %w", err) - } - defer av.Close() - - vdsoAddr, err := vdsoMemoryAddress(av) - if err != nil { - return 0, fmt.Errorf("finding vDSO memory address: %w", err) - } - - // Use /proc/self/mem rather than unsafe.Pointer tricks. - mem, err := os.Open("/proc/self/mem") - if err != nil { - return 0, fmt.Errorf("opening mem: %w", err) - } - defer mem.Close() - - // Open ELF at provided memory address, as offset into /proc/self/mem. - c, err := vdsoLinuxVersionCode(io.NewSectionReader(mem, int64(vdsoAddr), math.MaxInt64)) - if err != nil { - return 0, fmt.Errorf("reading linux version code: %w", err) - } - - return c, nil -} - -// vdsoMemoryAddress returns the memory address of the vDSO library -// linked into the current process image. r is an io.Reader into an auxv blob. -func vdsoMemoryAddress(r io.Reader) (uint64, error) { - const ( - _AT_NULL = 0 // End of vector - _AT_SYSINFO_EHDR = 33 // Offset to vDSO blob in process image - ) - - // Loop through all tag/value pairs in auxv until we find `AT_SYSINFO_EHDR`, - // the address of a page containing the virtual Dynamic Shared Object (vDSO). - aux := struct{ Tag, Val uint64 }{} - for { - if err := binary.Read(r, NativeEndian, &aux); err != nil { - return 0, fmt.Errorf("reading auxv entry: %w", err) - } - - switch aux.Tag { - case _AT_SYSINFO_EHDR: - if aux.Val != 0 { - return aux.Val, nil - } - return 0, fmt.Errorf("invalid vDSO address in auxv") - // _AT_NULL is always the last tag/val pair in the aux vector - // and can be treated like EOF. - case _AT_NULL: - return 0, errAuxvNoVDSO - } - } -} - -// format described at https://www.man7.org/linux/man-pages/man5/elf.5.html in section 'Notes (Nhdr)' -type elfNoteHeader struct { - NameSize int32 - DescSize int32 - Type int32 -} - -// vdsoLinuxVersionCode returns the LINUX_VERSION_CODE embedded in -// the ELF notes section of the binary provided by the reader. -func vdsoLinuxVersionCode(r io.ReaderAt) (uint32, error) { - hdr, err := NewSafeELFFile(r) - if err != nil { - return 0, fmt.Errorf("reading vDSO ELF: %w", err) - } - - sections := hdr.SectionsByType(elf.SHT_NOTE) - if len(sections) == 0 { - return 0, fmt.Errorf("no note section found in vDSO ELF") - } - - for _, sec := range sections { - sr := sec.Open() - var n elfNoteHeader - - // Read notes until we find one named 'Linux'. - for { - if err := binary.Read(sr, hdr.ByteOrder, &n); err != nil { - if errors.Is(err, io.EOF) { - // We looked at all the notes in this section - break - } - return 0, fmt.Errorf("reading note header: %w", err) - } - - // If a note name is defined, it follows the note header. - var name string - if n.NameSize > 0 { - // Read the note name, aligned to 4 bytes. - buf := make([]byte, Align(int(n.NameSize), 4)) - if err := binary.Read(sr, hdr.ByteOrder, &buf); err != nil { - return 0, fmt.Errorf("reading note name: %w", err) - } - - // Read nul-terminated string. - name = unix.ByteSliceToString(buf[:n.NameSize]) - } - - // If a note descriptor is defined, it follows the name. - // It is possible for a note to have a descriptor but not a name. - if n.DescSize > 0 { - // LINUX_VERSION_CODE is a uint32 value. - if name == "Linux" && n.DescSize == 4 && n.Type == 0 { - var version uint32 - if err := binary.Read(sr, hdr.ByteOrder, &version); err != nil { - return 0, fmt.Errorf("reading note descriptor: %w", err) - } - return version, nil - } - - // Discard the note descriptor if it exists but we're not interested in it. - if _, err := io.CopyN(io.Discard, sr, int64(Align(int(n.DescSize), 4))); err != nil { - return 0, err - } - } - } - } - - return 0, fmt.Errorf("no Linux note in ELF") -} diff --git a/vendor/github.com/cilium/ebpf/internal/version.go b/vendor/github.com/cilium/ebpf/internal/version.go deleted file mode 100644 index 370e01e4..00000000 --- a/vendor/github.com/cilium/ebpf/internal/version.go +++ /dev/null @@ -1,122 +0,0 @@ -package internal - -import ( - "fmt" - "sync" - - "github.com/cilium/ebpf/internal/unix" -) - -const ( - // Version constant used in ELF binaries indicating that the loader needs to - // substitute the eBPF program's version with the value of the kernel's - // KERNEL_VERSION compile-time macro. Used for compatibility with BCC, gobpf - // and RedSift. - MagicKernelVersion = 0xFFFFFFFE -) - -var ( - kernelVersion = struct { - once sync.Once - version Version - err error - }{} -) - -// A Version in the form Major.Minor.Patch. -type Version [3]uint16 - -// NewVersion creates a version from a string like "Major.Minor.Patch". -// -// Patch is optional. -func NewVersion(ver string) (Version, error) { - var major, minor, patch uint16 - n, _ := fmt.Sscanf(ver, "%d.%d.%d", &major, &minor, &patch) - if n < 2 { - return Version{}, fmt.Errorf("invalid version: %s", ver) - } - return Version{major, minor, patch}, nil -} - -// NewVersionFromCode creates a version from a LINUX_VERSION_CODE. -func NewVersionFromCode(code uint32) Version { - return Version{ - uint16(uint8(code >> 16)), - uint16(uint8(code >> 8)), - uint16(uint8(code)), - } -} - -func (v Version) String() string { - if v[2] == 0 { - return fmt.Sprintf("v%d.%d", v[0], v[1]) - } - return fmt.Sprintf("v%d.%d.%d", v[0], v[1], v[2]) -} - -// Less returns true if the version is less than another version. -func (v Version) Less(other Version) bool { - for i, a := range v { - if a == other[i] { - continue - } - return a < other[i] - } - return false -} - -// Unspecified returns true if the version is all zero. -func (v Version) Unspecified() bool { - return v[0] == 0 && v[1] == 0 && v[2] == 0 -} - -// Kernel implements the kernel's KERNEL_VERSION macro from linux/version.h. -// It represents the kernel version and patch level as a single value. -func (v Version) Kernel() uint32 { - - // Kernels 4.4 and 4.9 have their SUBLEVEL clamped to 255 to avoid - // overflowing into PATCHLEVEL. - // See kernel commit 9b82f13e7ef3 ("kbuild: clamp SUBLEVEL to 255"). - s := v[2] - if s > 255 { - s = 255 - } - - // Truncate members to uint8 to prevent them from spilling over into - // each other when overflowing 8 bits. - return uint32(uint8(v[0]))<<16 | uint32(uint8(v[1]))<<8 | uint32(uint8(s)) -} - -// KernelVersion returns the version of the currently running kernel. -func KernelVersion() (Version, error) { - kernelVersion.once.Do(func() { - kernelVersion.version, kernelVersion.err = detectKernelVersion() - }) - - if kernelVersion.err != nil { - return Version{}, kernelVersion.err - } - return kernelVersion.version, nil -} - -// detectKernelVersion returns the version of the running kernel. -func detectKernelVersion() (Version, error) { - vc, err := vdsoVersion() - if err != nil { - return Version{}, err - } - return NewVersionFromCode(vc), nil -} - -// KernelRelease returns the release string of the running kernel. -// Its format depends on the Linux distribution and corresponds to directory -// names in /lib/modules by convention. Some examples are 5.15.17-1-lts and -// 4.19.0-16-amd64. -func KernelRelease() (string, error) { - var uname unix.Utsname - if err := unix.Uname(&uname); err != nil { - return "", fmt.Errorf("uname failed: %w", err) - } - - return unix.ByteSliceToString(uname.Release[:]), nil -} diff --git a/vendor/github.com/cilium/ebpf/link/cgroup.go b/vendor/github.com/cilium/ebpf/link/cgroup.go deleted file mode 100644 index 003b0638..00000000 --- a/vendor/github.com/cilium/ebpf/link/cgroup.go +++ /dev/null @@ -1,165 +0,0 @@ -package link - -import ( - "errors" - "fmt" - "os" - - "github.com/cilium/ebpf" -) - -type cgroupAttachFlags uint32 - -// cgroup attach flags -const ( - flagAllowOverride cgroupAttachFlags = 1 << iota - flagAllowMulti - flagReplace -) - -type CgroupOptions struct { - // Path to a cgroupv2 folder. - Path string - // One of the AttachCgroup* constants - Attach ebpf.AttachType - // Program must be of type CGroup*, and the attach type must match Attach. - Program *ebpf.Program -} - -// AttachCgroup links a BPF program to a cgroup. -func AttachCgroup(opts CgroupOptions) (Link, error) { - cgroup, err := os.Open(opts.Path) - if err != nil { - return nil, fmt.Errorf("can't open cgroup: %s", err) - } - - clone, err := opts.Program.Clone() - if err != nil { - cgroup.Close() - return nil, err - } - - var cg Link - cg, err = newLinkCgroup(cgroup, opts.Attach, clone) - if errors.Is(err, ErrNotSupported) { - cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowMulti) - } - if errors.Is(err, ErrNotSupported) { - cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowOverride) - } - if err != nil { - cgroup.Close() - clone.Close() - return nil, err - } - - return cg, nil -} - -type progAttachCgroup struct { - cgroup *os.File - current *ebpf.Program - attachType ebpf.AttachType - flags cgroupAttachFlags -} - -var _ Link = (*progAttachCgroup)(nil) - -func (cg *progAttachCgroup) isLink() {} - -func newProgAttachCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program, flags cgroupAttachFlags) (*progAttachCgroup, error) { - if flags&flagAllowMulti > 0 { - if err := haveProgAttachReplace(); err != nil { - return nil, fmt.Errorf("can't support multiple programs: %w", err) - } - } - - err := RawAttachProgram(RawAttachProgramOptions{ - Target: int(cgroup.Fd()), - Program: prog, - Flags: uint32(flags), - Attach: attach, - }) - if err != nil { - return nil, fmt.Errorf("cgroup: %w", err) - } - - return &progAttachCgroup{cgroup, prog, attach, flags}, nil -} - -func (cg *progAttachCgroup) Close() error { - defer cg.cgroup.Close() - defer cg.current.Close() - - err := RawDetachProgram(RawDetachProgramOptions{ - Target: int(cg.cgroup.Fd()), - Program: cg.current, - Attach: cg.attachType, - }) - if err != nil { - return fmt.Errorf("close cgroup: %s", err) - } - return nil -} - -func (cg *progAttachCgroup) Update(prog *ebpf.Program) error { - new, err := prog.Clone() - if err != nil { - return err - } - - args := RawAttachProgramOptions{ - Target: int(cg.cgroup.Fd()), - Program: prog, - Attach: cg.attachType, - Flags: uint32(cg.flags), - } - - if cg.flags&flagAllowMulti > 0 { - // Atomically replacing multiple programs requires at least - // 5.5 (commit 7dd68b3279f17921 "bpf: Support replacing cgroup-bpf - // program in MULTI mode") - args.Flags |= uint32(flagReplace) - args.Replace = cg.current - } - - if err := RawAttachProgram(args); err != nil { - new.Close() - return fmt.Errorf("can't update cgroup: %s", err) - } - - cg.current.Close() - cg.current = new - return nil -} - -func (cg *progAttachCgroup) Pin(string) error { - return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported) -} - -func (cg *progAttachCgroup) Unpin() error { - return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported) -} - -func (cg *progAttachCgroup) Info() (*Info, error) { - return nil, fmt.Errorf("can't get cgroup info: %w", ErrNotSupported) -} - -type linkCgroup struct { - RawLink -} - -var _ Link = (*linkCgroup)(nil) - -func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program) (*linkCgroup, error) { - link, err := AttachRawLink(RawLinkOptions{ - Target: int(cgroup.Fd()), - Program: prog, - Attach: attach, - }) - if err != nil { - return nil, err - } - - return &linkCgroup{*link}, err -} diff --git a/vendor/github.com/cilium/ebpf/link/doc.go b/vendor/github.com/cilium/ebpf/link/doc.go deleted file mode 100644 index 2bde35ed..00000000 --- a/vendor/github.com/cilium/ebpf/link/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package link allows attaching eBPF programs to various kernel hooks. -package link diff --git a/vendor/github.com/cilium/ebpf/link/iter.go b/vendor/github.com/cilium/ebpf/link/iter.go deleted file mode 100644 index d2b32ef3..00000000 --- a/vendor/github.com/cilium/ebpf/link/iter.go +++ /dev/null @@ -1,85 +0,0 @@ -package link - -import ( - "fmt" - "io" - "unsafe" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal/sys" -) - -type IterOptions struct { - // Program must be of type Tracing with attach type - // AttachTraceIter. The kind of iterator to attach to is - // determined at load time via the AttachTo field. - // - // AttachTo requires the kernel to include BTF of itself, - // and it to be compiled with a recent pahole (>= 1.16). - Program *ebpf.Program - - // Map specifies the target map for bpf_map_elem and sockmap iterators. - // It may be nil. - Map *ebpf.Map -} - -// AttachIter attaches a BPF seq_file iterator. -func AttachIter(opts IterOptions) (*Iter, error) { - if err := haveBPFLink(); err != nil { - return nil, err - } - - progFd := opts.Program.FD() - if progFd < 0 { - return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd) - } - - var info bpfIterLinkInfoMap - if opts.Map != nil { - mapFd := opts.Map.FD() - if mapFd < 0 { - return nil, fmt.Errorf("invalid map: %w", sys.ErrClosedFd) - } - info.map_fd = uint32(mapFd) - } - - attr := sys.LinkCreateIterAttr{ - ProgFd: uint32(progFd), - AttachType: sys.AttachType(ebpf.AttachTraceIter), - IterInfo: sys.NewPointer(unsafe.Pointer(&info)), - IterInfoLen: uint32(unsafe.Sizeof(info)), - } - - fd, err := sys.LinkCreateIter(&attr) - if err != nil { - return nil, fmt.Errorf("can't link iterator: %w", err) - } - - return &Iter{RawLink{fd, ""}}, err -} - -// Iter represents an attached bpf_iter. -type Iter struct { - RawLink -} - -// Open creates a new instance of the iterator. -// -// Reading from the returned reader triggers the BPF program. -func (it *Iter) Open() (io.ReadCloser, error) { - attr := &sys.IterCreateAttr{ - LinkFd: it.fd.Uint(), - } - - fd, err := sys.IterCreate(attr) - if err != nil { - return nil, fmt.Errorf("can't create iterator: %w", err) - } - - return fd.File("bpf_iter"), nil -} - -// union bpf_iter_link_info.map -type bpfIterLinkInfoMap struct { - map_fd uint32 -} diff --git a/vendor/github.com/cilium/ebpf/link/kprobe.go b/vendor/github.com/cilium/ebpf/link/kprobe.go deleted file mode 100644 index fdf622a0..00000000 --- a/vendor/github.com/cilium/ebpf/link/kprobe.go +++ /dev/null @@ -1,568 +0,0 @@ -package link - -import ( - "bytes" - "crypto/rand" - "errors" - "fmt" - "os" - "path/filepath" - "runtime" - "strings" - "sync" - "syscall" - "unsafe" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -var ( - kprobeEventsPath = filepath.Join(tracefsPath, "kprobe_events") - - kprobeRetprobeBit = struct { - once sync.Once - value uint64 - err error - }{} -) - -type probeType uint8 - -type probeArgs struct { - symbol, group, path string - offset, refCtrOffset, cookie uint64 - pid int - ret bool -} - -// KprobeOptions defines additional parameters that will be used -// when loading Kprobes. -type KprobeOptions struct { - // Arbitrary value that can be fetched from an eBPF program - // via `bpf_get_attach_cookie()`. - // - // Needs kernel 5.15+. - Cookie uint64 - // Offset of the kprobe relative to the traced symbol. - // Can be used to insert kprobes at arbitrary offsets in kernel functions, - // e.g. in places where functions have been inlined. - Offset uint64 -} - -const ( - kprobeType probeType = iota - uprobeType -) - -func (pt probeType) String() string { - if pt == kprobeType { - return "kprobe" - } - return "uprobe" -} - -func (pt probeType) EventsPath() string { - if pt == kprobeType { - return kprobeEventsPath - } - return uprobeEventsPath -} - -func (pt probeType) PerfEventType(ret bool) perfEventType { - if pt == kprobeType { - if ret { - return kretprobeEvent - } - return kprobeEvent - } - if ret { - return uretprobeEvent - } - return uprobeEvent -} - -func (pt probeType) RetprobeBit() (uint64, error) { - if pt == kprobeType { - return kretprobeBit() - } - return uretprobeBit() -} - -// Kprobe attaches the given eBPF program to a perf event that fires when the -// given kernel symbol starts executing. See /proc/kallsyms for available -// symbols. For example, printk(): -// -// kp, err := Kprobe("printk", prog, nil) -// -// Losing the reference to the resulting Link (kp) will close the Kprobe -// and prevent further execution of prog. The Link must be Closed during -// program shutdown to avoid leaking system resources. -func Kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) { - k, err := kprobe(symbol, prog, opts, false) - if err != nil { - return nil, err - } - - lnk, err := attachPerfEvent(k, prog) - if err != nil { - k.Close() - return nil, err - } - - return lnk, nil -} - -// Kretprobe attaches the given eBPF program to a perf event that fires right -// before the given kernel symbol exits, with the function stack left intact. -// See /proc/kallsyms for available symbols. For example, printk(): -// -// kp, err := Kretprobe("printk", prog, nil) -// -// Losing the reference to the resulting Link (kp) will close the Kretprobe -// and prevent further execution of prog. The Link must be Closed during -// program shutdown to avoid leaking system resources. -func Kretprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) { - k, err := kprobe(symbol, prog, opts, true) - if err != nil { - return nil, err - } - - lnk, err := attachPerfEvent(k, prog) - if err != nil { - k.Close() - return nil, err - } - - return lnk, nil -} - -// isValidKprobeSymbol implements the equivalent of a regex match -// against "^[a-zA-Z_][0-9a-zA-Z_.]*$". -func isValidKprobeSymbol(s string) bool { - if len(s) < 1 { - return false - } - - for i, c := range []byte(s) { - switch { - case c >= 'a' && c <= 'z': - case c >= 'A' && c <= 'Z': - case c == '_': - case i > 0 && c >= '0' && c <= '9': - - // Allow `.` in symbol name. GCC-compiled kernel may change symbol name - // to have a `.isra.$n` suffix, like `udp_send_skb.isra.52`. - // See: https://gcc.gnu.org/gcc-10/changes.html - case i > 0 && c == '.': - - default: - return false - } - } - - return true -} - -// kprobe opens a perf event on the given symbol and attaches prog to it. -// If ret is true, create a kretprobe. -func kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions, ret bool) (*perfEvent, error) { - if symbol == "" { - return nil, fmt.Errorf("symbol name cannot be empty: %w", errInvalidInput) - } - if prog == nil { - return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) - } - if !isValidKprobeSymbol(symbol) { - return nil, fmt.Errorf("symbol '%s' must be a valid symbol in /proc/kallsyms: %w", symbol, errInvalidInput) - } - if prog.Type() != ebpf.Kprobe { - return nil, fmt.Errorf("eBPF program type %s is not a Kprobe: %w", prog.Type(), errInvalidInput) - } - - args := probeArgs{ - pid: perfAllThreads, - symbol: symbol, - ret: ret, - } - - if opts != nil { - args.cookie = opts.Cookie - args.offset = opts.Offset - } - - // Use kprobe PMU if the kernel has it available. - tp, err := pmuKprobe(args) - if errors.Is(err, os.ErrNotExist) { - args.symbol = platformPrefix(symbol) - tp, err = pmuKprobe(args) - } - if err == nil { - return tp, nil - } - if err != nil && !errors.Is(err, ErrNotSupported) { - return nil, fmt.Errorf("creating perf_kprobe PMU: %w", err) - } - - // Use tracefs if kprobe PMU is missing. - args.symbol = symbol - tp, err = tracefsKprobe(args) - if errors.Is(err, os.ErrNotExist) { - args.symbol = platformPrefix(symbol) - tp, err = tracefsKprobe(args) - } - if err != nil { - return nil, fmt.Errorf("creating trace event '%s' in tracefs: %w", symbol, err) - } - - return tp, nil -} - -// pmuKprobe opens a perf event based on the kprobe PMU. -// Returns os.ErrNotExist if the given symbol does not exist in the kernel. -func pmuKprobe(args probeArgs) (*perfEvent, error) { - return pmuProbe(kprobeType, args) -} - -// pmuProbe opens a perf event based on a Performance Monitoring Unit. -// -// Requires at least a 4.17 kernel. -// e12f03d7031a "perf/core: Implement the 'perf_kprobe' PMU" -// 33ea4b24277b "perf/core: Implement the 'perf_uprobe' PMU" -// -// Returns ErrNotSupported if the kernel doesn't support perf_[k,u]probe PMU -func pmuProbe(typ probeType, args probeArgs) (*perfEvent, error) { - // Getting the PMU type will fail if the kernel doesn't support - // the perf_[k,u]probe PMU. - et, err := getPMUEventType(typ) - if err != nil { - return nil, err - } - - var config uint64 - if args.ret { - bit, err := typ.RetprobeBit() - if err != nil { - return nil, err - } - config |= 1 << bit - } - - var ( - attr unix.PerfEventAttr - sp unsafe.Pointer - ) - switch typ { - case kprobeType: - // Create a pointer to a NUL-terminated string for the kernel. - sp, err = unsafeStringPtr(args.symbol) - if err != nil { - return nil, err - } - - attr = unix.PerfEventAttr{ - // The minimum size required for PMU kprobes is PERF_ATTR_SIZE_VER1, - // since it added the config2 (Ext2) field. Use Ext2 as probe_offset. - Size: unix.PERF_ATTR_SIZE_VER1, - Type: uint32(et), // PMU event type read from sysfs - Ext1: uint64(uintptr(sp)), // Kernel symbol to trace - Ext2: args.offset, // Kernel symbol offset - Config: config, // Retprobe flag - } - case uprobeType: - sp, err = unsafeStringPtr(args.path) - if err != nil { - return nil, err - } - - if args.refCtrOffset != 0 { - config |= args.refCtrOffset << uprobeRefCtrOffsetShift - } - - attr = unix.PerfEventAttr{ - // The minimum size required for PMU uprobes is PERF_ATTR_SIZE_VER1, - // since it added the config2 (Ext2) field. The Size field controls the - // size of the internal buffer the kernel allocates for reading the - // perf_event_attr argument from userspace. - Size: unix.PERF_ATTR_SIZE_VER1, - Type: uint32(et), // PMU event type read from sysfs - Ext1: uint64(uintptr(sp)), // Uprobe path - Ext2: args.offset, // Uprobe offset - Config: config, // RefCtrOffset, Retprobe flag - } - } - - rawFd, err := unix.PerfEventOpen(&attr, args.pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC) - - // On some old kernels, kprobe PMU doesn't allow `.` in symbol names and - // return -EINVAL. Return ErrNotSupported to allow falling back to tracefs. - // https://github.com/torvalds/linux/blob/94710cac0ef4/kernel/trace/trace_kprobe.c#L340-L343 - if errors.Is(err, unix.EINVAL) && strings.Contains(args.symbol, ".") { - return nil, fmt.Errorf("symbol '%s+%#x': older kernels don't accept dots: %w", args.symbol, args.offset, ErrNotSupported) - } - // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL - // when trying to create a kretprobe for a missing symbol. Make sure ENOENT - // is returned to the caller. - if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { - return nil, fmt.Errorf("symbol '%s+%#x' not found: %w", args.symbol, args.offset, os.ErrNotExist) - } - // Since commit ab105a4fb894, -EILSEQ is returned when a kprobe sym+offset is resolved - // to an invalid insn boundary. - if errors.Is(err, syscall.EILSEQ) { - return nil, fmt.Errorf("symbol '%s+%#x' not found (bad insn boundary): %w", args.symbol, args.offset, os.ErrNotExist) - } - // Since at least commit cb9a19fe4aa51, ENOTSUPP is returned - // when attempting to set a uprobe on a trap instruction. - if errors.Is(err, unix.ENOTSUPP) { - return nil, fmt.Errorf("failed setting uprobe on offset %#x (possible trap insn): %w", args.offset, err) - } - if err != nil { - return nil, fmt.Errorf("opening perf event: %w", err) - } - - // Ensure the string pointer is not collected before PerfEventOpen returns. - runtime.KeepAlive(sp) - - fd, err := sys.NewFD(rawFd) - if err != nil { - return nil, err - } - - // Kernel has perf_[k,u]probe PMU available, initialize perf event. - return &perfEvent{ - typ: typ.PerfEventType(args.ret), - name: args.symbol, - pmuID: et, - cookie: args.cookie, - fd: fd, - }, nil -} - -// tracefsKprobe creates a Kprobe tracefs entry. -func tracefsKprobe(args probeArgs) (*perfEvent, error) { - return tracefsProbe(kprobeType, args) -} - -// tracefsProbe creates a trace event by writing an entry to /[k,u]probe_events. -// A new trace event group name is generated on every call to support creating -// multiple trace events for the same kernel or userspace symbol. -// Path and offset are only set in the case of uprobe(s) and are used to set -// the executable/library path on the filesystem and the offset where the probe is inserted. -// A perf event is then opened on the newly-created trace event and returned to the caller. -func tracefsProbe(typ probeType, args probeArgs) (_ *perfEvent, err error) { - // Generate a random string for each trace event we attempt to create. - // This value is used as the 'group' token in tracefs to allow creating - // multiple kprobe trace events with the same name. - group, err := randomGroup("ebpf") - if err != nil { - return nil, fmt.Errorf("randomizing group name: %w", err) - } - args.group = group - - // Before attempting to create a trace event through tracefs, - // check if an event with the same group and name already exists. - // Kernels 4.x and earlier don't return os.ErrExist on writing a duplicate - // entry, so we need to rely on reads for detecting uniqueness. - _, err = getTraceEventID(group, args.symbol) - if err == nil { - return nil, fmt.Errorf("trace event already exists: %s/%s", group, args.symbol) - } - if err != nil && !errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("checking trace event %s/%s: %w", group, args.symbol, err) - } - - // Create the [k,u]probe trace event using tracefs. - if err := createTraceFSProbeEvent(typ, args); err != nil { - return nil, fmt.Errorf("creating probe entry on tracefs: %w", err) - } - defer func() { - if err != nil { - // Make sure we clean up the created tracefs event when we return error. - // If a livepatch handler is already active on the symbol, the write to - // tracefs will succeed, a trace event will show up, but creating the - // perf event will fail with EBUSY. - _ = closeTraceFSProbeEvent(typ, args.group, args.symbol) - } - }() - - // Get the newly-created trace event's id. - tid, err := getTraceEventID(group, args.symbol) - if err != nil { - return nil, fmt.Errorf("getting trace event id: %w", err) - } - - // Kprobes are ephemeral tracepoints and share the same perf event type. - fd, err := openTracepointPerfEvent(tid, args.pid) - if err != nil { - return nil, err - } - - return &perfEvent{ - typ: typ.PerfEventType(args.ret), - group: group, - name: args.symbol, - tracefsID: tid, - cookie: args.cookie, - fd: fd, - }, nil -} - -// createTraceFSProbeEvent creates a new ephemeral trace event by writing to -// /[k,u]probe_events. Returns os.ErrNotExist if symbol is not a valid -// kernel symbol, or if it is not traceable with kprobes. Returns os.ErrExist -// if a probe with the same group and symbol already exists. -func createTraceFSProbeEvent(typ probeType, args probeArgs) error { - // Open the kprobe_events file in tracefs. - f, err := os.OpenFile(typ.EventsPath(), os.O_APPEND|os.O_WRONLY, 0666) - if err != nil { - return fmt.Errorf("error opening '%s': %w", typ.EventsPath(), err) - } - defer f.Close() - - var pe, token string - switch typ { - case kprobeType: - // The kprobe_events syntax is as follows (see Documentation/trace/kprobetrace.txt): - // p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe - // r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe - // -:[GRP/]EVENT : Clear a probe - // - // Some examples: - // r:ebpf_1234/r_my_kretprobe nf_conntrack_destroy - // p:ebpf_5678/p_my_kprobe __x64_sys_execve - // - // Leaving the kretprobe's MAXACTIVE set to 0 (or absent) will make the - // kernel default to NR_CPUS. This is desired in most eBPF cases since - // subsampling or rate limiting logic can be more accurately implemented in - // the eBPF program itself. - // See Documentation/kprobes.txt for more details. - token = kprobeToken(args) - pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.ret), args.group, sanitizeSymbol(args.symbol), token) - case uprobeType: - // The uprobe_events syntax is as follows: - // p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a probe - // r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return probe - // -:[GRP/]EVENT : Clear a probe - // - // Some examples: - // r:ebpf_1234/readline /bin/bash:0x12345 - // p:ebpf_5678/main_mySymbol /bin/mybin:0x12345(0x123) - // - // See Documentation/trace/uprobetracer.txt for more details. - token = uprobeToken(args) - pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.ret), args.group, args.symbol, token) - } - _, err = f.WriteString(pe) - // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL - // when trying to create a kretprobe for a missing symbol. Make sure ENOENT - // is returned to the caller. - // EINVAL is also returned on pre-5.2 kernels when the `SYM[+offs]` token - // is resolved to an invalid insn boundary. - if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) { - return fmt.Errorf("token %s: %w", token, os.ErrNotExist) - } - // Since commit ab105a4fb894, -EILSEQ is returned when a kprobe sym+offset is resolved - // to an invalid insn boundary. - if errors.Is(err, syscall.EILSEQ) { - return fmt.Errorf("token %s: bad insn boundary: %w", token, os.ErrNotExist) - } - // ERANGE is returned when the `SYM[+offs]` token is too big and cannot - // be resolved. - if errors.Is(err, syscall.ERANGE) { - return fmt.Errorf("token %s: offset too big: %w", token, os.ErrNotExist) - } - if err != nil { - return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err) - } - - return nil -} - -// closeTraceFSProbeEvent removes the [k,u]probe with the given type, group and symbol -// from /[k,u]probe_events. -func closeTraceFSProbeEvent(typ probeType, group, symbol string) error { - f, err := os.OpenFile(typ.EventsPath(), os.O_APPEND|os.O_WRONLY, 0666) - if err != nil { - return fmt.Errorf("error opening %s: %w", typ.EventsPath(), err) - } - defer f.Close() - - // See [k,u]probe_events syntax above. The probe type does not need to be specified - // for removals. - pe := fmt.Sprintf("-:%s/%s", group, sanitizeSymbol(symbol)) - if _, err = f.WriteString(pe); err != nil { - return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err) - } - - return nil -} - -// randomGroup generates a pseudorandom string for use as a tracefs group name. -// Returns an error when the output string would exceed 63 characters (kernel -// limitation), when rand.Read() fails or when prefix contains characters not -// allowed by isValidTraceID. -func randomGroup(prefix string) (string, error) { - if !isValidTraceID(prefix) { - return "", fmt.Errorf("prefix '%s' must be alphanumeric or underscore: %w", prefix, errInvalidInput) - } - - b := make([]byte, 8) - if _, err := rand.Read(b); err != nil { - return "", fmt.Errorf("reading random bytes: %w", err) - } - - group := fmt.Sprintf("%s_%x", prefix, b) - if len(group) > 63 { - return "", fmt.Errorf("group name '%s' cannot be longer than 63 characters: %w", group, errInvalidInput) - } - - return group, nil -} - -func probePrefix(ret bool) string { - if ret { - return "r" - } - return "p" -} - -// determineRetprobeBit reads a Performance Monitoring Unit's retprobe bit -// from /sys/bus/event_source/devices//format/retprobe. -func determineRetprobeBit(typ probeType) (uint64, error) { - p := filepath.Join("/sys/bus/event_source/devices/", typ.String(), "/format/retprobe") - - data, err := os.ReadFile(p) - if err != nil { - return 0, err - } - - var rp uint64 - n, err := fmt.Sscanf(string(bytes.TrimSpace(data)), "config:%d", &rp) - if err != nil { - return 0, fmt.Errorf("parse retprobe bit: %w", err) - } - if n != 1 { - return 0, fmt.Errorf("parse retprobe bit: expected 1 item, got %d", n) - } - - return rp, nil -} - -func kretprobeBit() (uint64, error) { - kprobeRetprobeBit.once.Do(func() { - kprobeRetprobeBit.value, kprobeRetprobeBit.err = determineRetprobeBit(kprobeType) - }) - return kprobeRetprobeBit.value, kprobeRetprobeBit.err -} - -// kprobeToken creates the SYM[+offs] token for the tracefs api. -func kprobeToken(args probeArgs) string { - po := args.symbol - - if args.offset != 0 { - po += fmt.Sprintf("+%#x", args.offset) - } - - return po -} diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go deleted file mode 100644 index 067d0101..00000000 --- a/vendor/github.com/cilium/ebpf/link/link.go +++ /dev/null @@ -1,313 +0,0 @@ -package link - -import ( - "bytes" - "encoding/binary" - "fmt" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" -) - -var ErrNotSupported = internal.ErrNotSupported - -// Link represents a Program attached to a BPF hook. -type Link interface { - // Replace the current program with a new program. - // - // Passing a nil program is an error. May return an error wrapping ErrNotSupported. - Update(*ebpf.Program) error - - // Persist a link by pinning it into a bpffs. - // - // May return an error wrapping ErrNotSupported. - Pin(string) error - - // Undo a previous call to Pin. - // - // May return an error wrapping ErrNotSupported. - Unpin() error - - // Close frees resources. - // - // The link will be broken unless it has been successfully pinned. - // A link may continue past the lifetime of the process if Close is - // not called. - Close() error - - // Info returns metadata on a link. - // - // May return an error wrapping ErrNotSupported. - Info() (*Info, error) - - // Prevent external users from implementing this interface. - isLink() -} - -// LoadPinnedLink loads a link that was persisted into a bpffs. -func LoadPinnedLink(fileName string, opts *ebpf.LoadPinOptions) (Link, error) { - raw, err := loadPinnedRawLink(fileName, opts) - if err != nil { - return nil, err - } - - return wrapRawLink(raw) -} - -// wrap a RawLink in a more specific type if possible. -// -// The function takes ownership of raw and closes it on error. -func wrapRawLink(raw *RawLink) (Link, error) { - info, err := raw.Info() - if err != nil { - raw.Close() - return nil, err - } - - switch info.Type { - case RawTracepointType: - return &rawTracepoint{*raw}, nil - case TracingType: - return &tracing{*raw}, nil - case CgroupType: - return &linkCgroup{*raw}, nil - case IterType: - return &Iter{*raw}, nil - case NetNsType: - return &NetNsLink{*raw}, nil - default: - return raw, nil - } -} - -// ID uniquely identifies a BPF link. -type ID = sys.LinkID - -// RawLinkOptions control the creation of a raw link. -type RawLinkOptions struct { - // File descriptor to attach to. This differs for each attach type. - Target int - // Program to attach. - Program *ebpf.Program - // Attach must match the attach type of Program. - Attach ebpf.AttachType - // BTF is the BTF of the attachment target. - BTF btf.TypeID - // Flags control the attach behaviour. - Flags uint32 -} - -// Info contains metadata on a link. -type Info struct { - Type Type - ID ID - Program ebpf.ProgramID - extra interface{} -} - -type TracingInfo sys.TracingLinkInfo -type CgroupInfo sys.CgroupLinkInfo -type NetNsInfo sys.NetNsLinkInfo -type XDPInfo sys.XDPLinkInfo - -// Tracing returns tracing type-specific link info. -// -// Returns nil if the type-specific link info isn't available. -func (r Info) Tracing() *TracingInfo { - e, _ := r.extra.(*TracingInfo) - return e -} - -// Cgroup returns cgroup type-specific link info. -// -// Returns nil if the type-specific link info isn't available. -func (r Info) Cgroup() *CgroupInfo { - e, _ := r.extra.(*CgroupInfo) - return e -} - -// NetNs returns netns type-specific link info. -// -// Returns nil if the type-specific link info isn't available. -func (r Info) NetNs() *NetNsInfo { - e, _ := r.extra.(*NetNsInfo) - return e -} - -// ExtraNetNs returns XDP type-specific link info. -// -// Returns nil if the type-specific link info isn't available. -func (r Info) XDP() *XDPInfo { - e, _ := r.extra.(*XDPInfo) - return e -} - -// RawLink is the low-level API to bpf_link. -// -// You should consider using the higher level interfaces in this -// package instead. -type RawLink struct { - fd *sys.FD - pinnedPath string -} - -// AttachRawLink creates a raw link. -func AttachRawLink(opts RawLinkOptions) (*RawLink, error) { - if err := haveBPFLink(); err != nil { - return nil, err - } - - if opts.Target < 0 { - return nil, fmt.Errorf("invalid target: %s", sys.ErrClosedFd) - } - - progFd := opts.Program.FD() - if progFd < 0 { - return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd) - } - - attr := sys.LinkCreateAttr{ - TargetFd: uint32(opts.Target), - ProgFd: uint32(progFd), - AttachType: sys.AttachType(opts.Attach), - TargetBtfId: uint32(opts.BTF), - Flags: opts.Flags, - } - fd, err := sys.LinkCreate(&attr) - if err != nil { - return nil, fmt.Errorf("can't create link: %s", err) - } - - return &RawLink{fd, ""}, nil -} - -func loadPinnedRawLink(fileName string, opts *ebpf.LoadPinOptions) (*RawLink, error) { - fd, err := sys.ObjGet(&sys.ObjGetAttr{ - Pathname: sys.NewStringPointer(fileName), - FileFlags: opts.Marshal(), - }) - if err != nil { - return nil, fmt.Errorf("load pinned link: %w", err) - } - - return &RawLink{fd, fileName}, nil -} - -func (l *RawLink) isLink() {} - -// FD returns the raw file descriptor. -func (l *RawLink) FD() int { - return l.fd.Int() -} - -// Close breaks the link. -// -// Use Pin if you want to make the link persistent. -func (l *RawLink) Close() error { - return l.fd.Close() -} - -// Pin persists a link past the lifetime of the process. -// -// Calling Close on a pinned Link will not break the link -// until the pin is removed. -func (l *RawLink) Pin(fileName string) error { - if err := internal.Pin(l.pinnedPath, fileName, l.fd); err != nil { - return err - } - l.pinnedPath = fileName - return nil -} - -// Unpin implements the Link interface. -func (l *RawLink) Unpin() error { - if err := internal.Unpin(l.pinnedPath); err != nil { - return err - } - l.pinnedPath = "" - return nil -} - -// Update implements the Link interface. -func (l *RawLink) Update(new *ebpf.Program) error { - return l.UpdateArgs(RawLinkUpdateOptions{ - New: new, - }) -} - -// RawLinkUpdateOptions control the behaviour of RawLink.UpdateArgs. -type RawLinkUpdateOptions struct { - New *ebpf.Program - Old *ebpf.Program - Flags uint32 -} - -// UpdateArgs updates a link based on args. -func (l *RawLink) UpdateArgs(opts RawLinkUpdateOptions) error { - newFd := opts.New.FD() - if newFd < 0 { - return fmt.Errorf("invalid program: %s", sys.ErrClosedFd) - } - - var oldFd int - if opts.Old != nil { - oldFd = opts.Old.FD() - if oldFd < 0 { - return fmt.Errorf("invalid replacement program: %s", sys.ErrClosedFd) - } - } - - attr := sys.LinkUpdateAttr{ - LinkFd: l.fd.Uint(), - NewProgFd: uint32(newFd), - OldProgFd: uint32(oldFd), - Flags: opts.Flags, - } - return sys.LinkUpdate(&attr) -} - -// Info returns metadata about the link. -func (l *RawLink) Info() (*Info, error) { - var info sys.LinkInfo - - if err := sys.ObjInfo(l.fd, &info); err != nil { - return nil, fmt.Errorf("link info: %s", err) - } - - var extra interface{} - switch info.Type { - case CgroupType: - extra = &CgroupInfo{} - case IterType: - // not supported - case NetNsType: - extra = &NetNsInfo{} - case RawTracepointType: - // not supported - case TracingType: - extra = &TracingInfo{} - case XDPType: - extra = &XDPInfo{} - case PerfEventType: - // no extra - default: - return nil, fmt.Errorf("unknown link info type: %d", info.Type) - } - - if info.Type != RawTracepointType && info.Type != IterType && info.Type != PerfEventType { - buf := bytes.NewReader(info.Extra[:]) - err := binary.Read(buf, internal.NativeEndian, extra) - if err != nil { - return nil, fmt.Errorf("can not read extra link info: %w", err) - } - } - - return &Info{ - info.Type, - info.Id, - ebpf.ProgramID(info.ProgId), - extra, - }, nil -} diff --git a/vendor/github.com/cilium/ebpf/link/netns.go b/vendor/github.com/cilium/ebpf/link/netns.go deleted file mode 100644 index 344ecced..00000000 --- a/vendor/github.com/cilium/ebpf/link/netns.go +++ /dev/null @@ -1,36 +0,0 @@ -package link - -import ( - "fmt" - - "github.com/cilium/ebpf" -) - -// NetNsLink is a program attached to a network namespace. -type NetNsLink struct { - RawLink -} - -// AttachNetNs attaches a program to a network namespace. -func AttachNetNs(ns int, prog *ebpf.Program) (*NetNsLink, error) { - var attach ebpf.AttachType - switch t := prog.Type(); t { - case ebpf.FlowDissector: - attach = ebpf.AttachFlowDissector - case ebpf.SkLookup: - attach = ebpf.AttachSkLookup - default: - return nil, fmt.Errorf("can't attach %v to network namespace", t) - } - - link, err := AttachRawLink(RawLinkOptions{ - Target: ns, - Program: prog, - Attach: attach, - }) - if err != nil { - return nil, err - } - - return &NetNsLink{*link}, nil -} diff --git a/vendor/github.com/cilium/ebpf/link/perf_event.go b/vendor/github.com/cilium/ebpf/link/perf_event.go deleted file mode 100644 index 0e5bd479..00000000 --- a/vendor/github.com/cilium/ebpf/link/perf_event.go +++ /dev/null @@ -1,394 +0,0 @@ -package link - -import ( - "bytes" - "errors" - "fmt" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" - "unsafe" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// Getting the terminology right is usually the hardest part. For posterity and -// for staying sane during implementation: -// -// - trace event: Representation of a kernel runtime hook. Filesystem entries -// under /events. Can be tracepoints (static), kprobes or uprobes. -// Can be instantiated into perf events (see below). -// - tracepoint: A predetermined hook point in the kernel. Exposed as trace -// events in (sub)directories under /events. Cannot be closed or -// removed, they are static. -// - k(ret)probe: Ephemeral trace events based on entry or exit points of -// exported kernel symbols. kprobe-based (tracefs) trace events can be -// created system-wide by writing to the /kprobe_events file, or -// they can be scoped to the current process by creating PMU perf events. -// - u(ret)probe: Ephemeral trace events based on user provides ELF binaries -// and offsets. uprobe-based (tracefs) trace events can be -// created system-wide by writing to the /uprobe_events file, or -// they can be scoped to the current process by creating PMU perf events. -// - perf event: An object instantiated based on an existing trace event or -// kernel symbol. Referred to by fd in userspace. -// Exactly one eBPF program can be attached to a perf event. Multiple perf -// events can be created from a single trace event. Closing a perf event -// stops any further invocations of the attached eBPF program. - -var ( - tracefsPath = "/sys/kernel/debug/tracing" - - errInvalidInput = errors.New("invalid input") -) - -const ( - perfAllThreads = -1 -) - -type perfEventType uint8 - -const ( - tracepointEvent perfEventType = iota - kprobeEvent - kretprobeEvent - uprobeEvent - uretprobeEvent -) - -// A perfEvent represents a perf event kernel object. Exactly one eBPF program -// can be attached to it. It is created based on a tracefs trace event or a -// Performance Monitoring Unit (PMU). -type perfEvent struct { - // The event type determines the types of programs that can be attached. - typ perfEventType - - // Group and name of the tracepoint/kprobe/uprobe. - group string - name string - - // PMU event ID read from sysfs. Valid IDs are non-zero. - pmuID uint64 - // ID of the trace event read from tracefs. Valid IDs are non-zero. - tracefsID uint64 - - // User provided arbitrary value. - cookie uint64 - - // This is the perf event FD. - fd *sys.FD -} - -func (pe *perfEvent) Close() error { - if err := pe.fd.Close(); err != nil { - return fmt.Errorf("closing perf event fd: %w", err) - } - - switch pe.typ { - case kprobeEvent, kretprobeEvent: - // Clean up kprobe tracefs entry. - if pe.tracefsID != 0 { - return closeTraceFSProbeEvent(kprobeType, pe.group, pe.name) - } - case uprobeEvent, uretprobeEvent: - // Clean up uprobe tracefs entry. - if pe.tracefsID != 0 { - return closeTraceFSProbeEvent(uprobeType, pe.group, pe.name) - } - case tracepointEvent: - // Tracepoint trace events don't hold any extra resources. - return nil - } - - return nil -} - -// perfEventLink represents a bpf perf link. -type perfEventLink struct { - RawLink - pe *perfEvent -} - -func (pl *perfEventLink) isLink() {} - -// Pinning requires the underlying perf event FD to stay open. -// -// | PerfEvent FD | BpfLink FD | Works | -// |--------------|------------|-------| -// | Open | Open | Yes | -// | Closed | Open | No | -// | Open | Closed | No (Pin() -> EINVAL) | -// | Closed | Closed | No (Pin() -> EINVAL) | -// -// There is currently no pretty way to recover the perf event FD -// when loading a pinned link, so leave as not supported for now. -func (pl *perfEventLink) Pin(string) error { - return fmt.Errorf("perf event link pin: %w", ErrNotSupported) -} - -func (pl *perfEventLink) Unpin() error { - return fmt.Errorf("perf event link unpin: %w", ErrNotSupported) -} - -func (pl *perfEventLink) Close() error { - if err := pl.pe.Close(); err != nil { - return fmt.Errorf("perf event link close: %w", err) - } - return pl.fd.Close() -} - -func (pl *perfEventLink) Update(prog *ebpf.Program) error { - return fmt.Errorf("perf event link update: %w", ErrNotSupported) -} - -// perfEventIoctl implements Link and handles the perf event lifecycle -// via ioctl(). -type perfEventIoctl struct { - *perfEvent -} - -func (pi *perfEventIoctl) isLink() {} - -// Since 4.15 (e87c6bc3852b "bpf: permit multiple bpf attachments for a single perf event"), -// calling PERF_EVENT_IOC_SET_BPF appends the given program to a prog_array -// owned by the perf event, which means multiple programs can be attached -// simultaneously. -// -// Before 4.15, calling PERF_EVENT_IOC_SET_BPF more than once on a perf event -// returns EEXIST. -// -// Detaching a program from a perf event is currently not possible, so a -// program replacement mechanism cannot be implemented for perf events. -func (pi *perfEventIoctl) Update(prog *ebpf.Program) error { - return fmt.Errorf("perf event ioctl update: %w", ErrNotSupported) -} - -func (pi *perfEventIoctl) Pin(string) error { - return fmt.Errorf("perf event ioctl pin: %w", ErrNotSupported) -} - -func (pi *perfEventIoctl) Unpin() error { - return fmt.Errorf("perf event ioctl unpin: %w", ErrNotSupported) -} - -func (pi *perfEventIoctl) Info() (*Info, error) { - return nil, fmt.Errorf("perf event ioctl info: %w", ErrNotSupported) -} - -// attach the given eBPF prog to the perf event stored in pe. -// pe must contain a valid perf event fd. -// prog's type must match the program type stored in pe. -func attachPerfEvent(pe *perfEvent, prog *ebpf.Program) (Link, error) { - if prog == nil { - return nil, errors.New("cannot attach a nil program") - } - if prog.FD() < 0 { - return nil, fmt.Errorf("invalid program: %w", sys.ErrClosedFd) - } - - switch pe.typ { - case kprobeEvent, kretprobeEvent, uprobeEvent, uretprobeEvent: - if t := prog.Type(); t != ebpf.Kprobe { - return nil, fmt.Errorf("invalid program type (expected %s): %s", ebpf.Kprobe, t) - } - case tracepointEvent: - if t := prog.Type(); t != ebpf.TracePoint { - return nil, fmt.Errorf("invalid program type (expected %s): %s", ebpf.TracePoint, t) - } - default: - return nil, fmt.Errorf("unknown perf event type: %d", pe.typ) - } - - if err := haveBPFLinkPerfEvent(); err == nil { - return attachPerfEventLink(pe, prog) - } - return attachPerfEventIoctl(pe, prog) -} - -func attachPerfEventIoctl(pe *perfEvent, prog *ebpf.Program) (*perfEventIoctl, error) { - if pe.cookie != 0 { - return nil, fmt.Errorf("cookies are not supported: %w", ErrNotSupported) - } - - // Assign the eBPF program to the perf event. - err := unix.IoctlSetInt(pe.fd.Int(), unix.PERF_EVENT_IOC_SET_BPF, prog.FD()) - if err != nil { - return nil, fmt.Errorf("setting perf event bpf program: %w", err) - } - - // PERF_EVENT_IOC_ENABLE and _DISABLE ignore their given values. - if err := unix.IoctlSetInt(pe.fd.Int(), unix.PERF_EVENT_IOC_ENABLE, 0); err != nil { - return nil, fmt.Errorf("enable perf event: %s", err) - } - - pi := &perfEventIoctl{pe} - - // Close the perf event when its reference is lost to avoid leaking system resources. - runtime.SetFinalizer(pi, (*perfEventIoctl).Close) - return pi, nil -} - -// Use the bpf api to attach the perf event (BPF_LINK_TYPE_PERF_EVENT, 5.15+). -// -// https://github.com/torvalds/linux/commit/b89fbfbb854c9afc3047e8273cc3a694650b802e -func attachPerfEventLink(pe *perfEvent, prog *ebpf.Program) (*perfEventLink, error) { - fd, err := sys.LinkCreatePerfEvent(&sys.LinkCreatePerfEventAttr{ - ProgFd: uint32(prog.FD()), - TargetFd: pe.fd.Uint(), - AttachType: sys.BPF_PERF_EVENT, - BpfCookie: pe.cookie, - }) - if err != nil { - return nil, fmt.Errorf("cannot create bpf perf link: %v", err) - } - - pl := &perfEventLink{RawLink{fd: fd}, pe} - - // Close the perf event when its reference is lost to avoid leaking system resources. - runtime.SetFinalizer(pl, (*perfEventLink).Close) - return pl, nil -} - -// unsafeStringPtr returns an unsafe.Pointer to a NUL-terminated copy of str. -func unsafeStringPtr(str string) (unsafe.Pointer, error) { - p, err := unix.BytePtrFromString(str) - if err != nil { - return nil, err - } - return unsafe.Pointer(p), nil -} - -// getTraceEventID reads a trace event's ID from tracefs given its group and name. -// The kernel requires group and name to be alphanumeric or underscore. -// -// name automatically has its invalid symbols converted to underscores so the caller -// can pass a raw symbol name, e.g. a kernel symbol containing dots. -func getTraceEventID(group, name string) (uint64, error) { - name = sanitizeSymbol(name) - tid, err := uint64FromFile(tracefsPath, "events", group, name, "id") - if errors.Is(err, os.ErrNotExist) { - return 0, fmt.Errorf("trace event %s/%s: %w", group, name, os.ErrNotExist) - } - if err != nil { - return 0, fmt.Errorf("reading trace event ID of %s/%s: %w", group, name, err) - } - - return tid, nil -} - -// getPMUEventType reads a Performance Monitoring Unit's type (numeric identifier) -// from /sys/bus/event_source/devices//type. -// -// Returns ErrNotSupported if the pmu type is not supported. -func getPMUEventType(typ probeType) (uint64, error) { - et, err := uint64FromFile("/sys/bus/event_source/devices", typ.String(), "type") - if errors.Is(err, os.ErrNotExist) { - return 0, fmt.Errorf("pmu type %s: %w", typ, ErrNotSupported) - } - if err != nil { - return 0, fmt.Errorf("reading pmu type %s: %w", typ, err) - } - - return et, nil -} - -// openTracepointPerfEvent opens a tracepoint-type perf event. System-wide -// [k,u]probes created by writing to /[k,u]probe_events are tracepoints -// behind the scenes, and can be attached to using these perf events. -func openTracepointPerfEvent(tid uint64, pid int) (*sys.FD, error) { - attr := unix.PerfEventAttr{ - Type: unix.PERF_TYPE_TRACEPOINT, - Config: tid, - Sample_type: unix.PERF_SAMPLE_RAW, - Sample: 1, - Wakeup: 1, - } - - fd, err := unix.PerfEventOpen(&attr, pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC) - if err != nil { - return nil, fmt.Errorf("opening tracepoint perf event: %w", err) - } - - return sys.NewFD(fd) -} - -// uint64FromFile reads a uint64 from a file. All elements of path are sanitized -// and joined onto base. Returns error if base no longer prefixes the path after -// joining all components. -func uint64FromFile(base string, path ...string) (uint64, error) { - l := filepath.Join(path...) - p := filepath.Join(base, l) - if !strings.HasPrefix(p, base) { - return 0, fmt.Errorf("path '%s' attempts to escape base path '%s': %w", l, base, errInvalidInput) - } - - data, err := os.ReadFile(p) - if err != nil { - return 0, fmt.Errorf("reading file %s: %w", p, err) - } - - et := bytes.TrimSpace(data) - return strconv.ParseUint(string(et), 10, 64) -} - -// Probe BPF perf link. -// -// https://elixir.bootlin.com/linux/v5.16.8/source/kernel/bpf/syscall.c#L4307 -// https://github.com/torvalds/linux/commit/b89fbfbb854c9afc3047e8273cc3a694650b802e -var haveBPFLinkPerfEvent = internal.FeatureTest("bpf_link_perf_event", "5.15", func() error { - prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ - Name: "probe_bpf_perf_link", - Type: ebpf.Kprobe, - Instructions: asm.Instructions{ - asm.Mov.Imm(asm.R0, 0), - asm.Return(), - }, - License: "MIT", - }) - if err != nil { - return err - } - defer prog.Close() - - _, err = sys.LinkCreatePerfEvent(&sys.LinkCreatePerfEventAttr{ - ProgFd: uint32(prog.FD()), - AttachType: sys.BPF_PERF_EVENT, - }) - if errors.Is(err, unix.EINVAL) { - return internal.ErrNotSupported - } - if errors.Is(err, unix.EBADF) { - return nil - } - return err -}) - -// isValidTraceID implements the equivalent of a regex match -// against "^[a-zA-Z_][0-9a-zA-Z_]*$". -// -// Trace event groups, names and kernel symbols must adhere to this set -// of characters. Non-empty, first character must not be a number, all -// characters must be alphanumeric or underscore. -func isValidTraceID(s string) bool { - if len(s) < 1 { - return false - } - for i, c := range []byte(s) { - switch { - case c >= 'a' && c <= 'z': - case c >= 'A' && c <= 'Z': - case c == '_': - case i > 0 && c >= '0' && c <= '9': - - default: - return false - } - } - - return true -} diff --git a/vendor/github.com/cilium/ebpf/link/platform.go b/vendor/github.com/cilium/ebpf/link/platform.go deleted file mode 100644 index eb6f7b7a..00000000 --- a/vendor/github.com/cilium/ebpf/link/platform.go +++ /dev/null @@ -1,25 +0,0 @@ -package link - -import ( - "fmt" - "runtime" -) - -func platformPrefix(symbol string) string { - - prefix := runtime.GOARCH - - // per https://github.com/golang/go/blob/master/src/go/build/syslist.go - switch prefix { - case "386": - prefix = "ia32" - case "amd64", "amd64p32": - prefix = "x64" - case "arm64", "arm64be": - prefix = "arm64" - default: - return symbol - } - - return fmt.Sprintf("__%s_%s", prefix, symbol) -} diff --git a/vendor/github.com/cilium/ebpf/link/program.go b/vendor/github.com/cilium/ebpf/link/program.go deleted file mode 100644 index ea318173..00000000 --- a/vendor/github.com/cilium/ebpf/link/program.go +++ /dev/null @@ -1,76 +0,0 @@ -package link - -import ( - "fmt" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal/sys" -) - -type RawAttachProgramOptions struct { - // File descriptor to attach to. This differs for each attach type. - Target int - // Program to attach. - Program *ebpf.Program - // Program to replace (cgroups). - Replace *ebpf.Program - // Attach must match the attach type of Program (and Replace). - Attach ebpf.AttachType - // Flags control the attach behaviour. This differs for each attach type. - Flags uint32 -} - -// RawAttachProgram is a low level wrapper around BPF_PROG_ATTACH. -// -// You should use one of the higher level abstractions available in this -// package if possible. -func RawAttachProgram(opts RawAttachProgramOptions) error { - if err := haveProgAttach(); err != nil { - return err - } - - var replaceFd uint32 - if opts.Replace != nil { - replaceFd = uint32(opts.Replace.FD()) - } - - attr := sys.ProgAttachAttr{ - TargetFd: uint32(opts.Target), - AttachBpfFd: uint32(opts.Program.FD()), - ReplaceBpfFd: replaceFd, - AttachType: uint32(opts.Attach), - AttachFlags: uint32(opts.Flags), - } - - if err := sys.ProgAttach(&attr); err != nil { - return fmt.Errorf("can't attach program: %w", err) - } - return nil -} - -type RawDetachProgramOptions struct { - Target int - Program *ebpf.Program - Attach ebpf.AttachType -} - -// RawDetachProgram is a low level wrapper around BPF_PROG_DETACH. -// -// You should use one of the higher level abstractions available in this -// package if possible. -func RawDetachProgram(opts RawDetachProgramOptions) error { - if err := haveProgAttach(); err != nil { - return err - } - - attr := sys.ProgDetachAttr{ - TargetFd: uint32(opts.Target), - AttachBpfFd: uint32(opts.Program.FD()), - AttachType: uint32(opts.Attach), - } - if err := sys.ProgDetach(&attr); err != nil { - return fmt.Errorf("can't detach program: %w", err) - } - - return nil -} diff --git a/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go b/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go deleted file mode 100644 index 925e621c..00000000 --- a/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go +++ /dev/null @@ -1,87 +0,0 @@ -package link - -import ( - "errors" - "fmt" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal/sys" -) - -type RawTracepointOptions struct { - // Tracepoint name. - Name string - // Program must be of type RawTracepoint* - Program *ebpf.Program -} - -// AttachRawTracepoint links a BPF program to a raw_tracepoint. -// -// Requires at least Linux 4.17. -func AttachRawTracepoint(opts RawTracepointOptions) (Link, error) { - if t := opts.Program.Type(); t != ebpf.RawTracepoint && t != ebpf.RawTracepointWritable { - return nil, fmt.Errorf("invalid program type %s, expected RawTracepoint(Writable)", t) - } - if opts.Program.FD() < 0 { - return nil, fmt.Errorf("invalid program: %w", sys.ErrClosedFd) - } - - fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{ - Name: sys.NewStringPointer(opts.Name), - ProgFd: uint32(opts.Program.FD()), - }) - if err != nil { - return nil, err - } - - err = haveBPFLink() - if errors.Is(err, ErrNotSupported) { - // Prior to commit 70ed506c3bbc ("bpf: Introduce pinnable bpf_link abstraction") - // raw_tracepoints are just a plain fd. - return &simpleRawTracepoint{fd}, nil - } - - if err != nil { - return nil, err - } - - return &rawTracepoint{RawLink{fd: fd}}, nil -} - -type simpleRawTracepoint struct { - fd *sys.FD -} - -var _ Link = (*simpleRawTracepoint)(nil) - -func (frt *simpleRawTracepoint) isLink() {} - -func (frt *simpleRawTracepoint) Close() error { - return frt.fd.Close() -} - -func (frt *simpleRawTracepoint) Update(_ *ebpf.Program) error { - return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported) -} - -func (frt *simpleRawTracepoint) Pin(string) error { - return fmt.Errorf("pin raw_tracepoint: %w", ErrNotSupported) -} - -func (frt *simpleRawTracepoint) Unpin() error { - return fmt.Errorf("unpin raw_tracepoint: %w", ErrNotSupported) -} - -func (frt *simpleRawTracepoint) Info() (*Info, error) { - return nil, fmt.Errorf("can't get raw_tracepoint info: %w", ErrNotSupported) -} - -type rawTracepoint struct { - RawLink -} - -var _ Link = (*rawTracepoint)(nil) - -func (rt *rawTracepoint) Update(_ *ebpf.Program) error { - return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported) -} diff --git a/vendor/github.com/cilium/ebpf/link/socket_filter.go b/vendor/github.com/cilium/ebpf/link/socket_filter.go deleted file mode 100644 index 94f3958c..00000000 --- a/vendor/github.com/cilium/ebpf/link/socket_filter.go +++ /dev/null @@ -1,40 +0,0 @@ -package link - -import ( - "syscall" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal/unix" -) - -// AttachSocketFilter attaches a SocketFilter BPF program to a socket. -func AttachSocketFilter(conn syscall.Conn, program *ebpf.Program) error { - rawConn, err := conn.SyscallConn() - if err != nil { - return err - } - var ssoErr error - err = rawConn.Control(func(fd uintptr) { - ssoErr = syscall.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_ATTACH_BPF, program.FD()) - }) - if ssoErr != nil { - return ssoErr - } - return err -} - -// DetachSocketFilter detaches a SocketFilter BPF program from a socket. -func DetachSocketFilter(conn syscall.Conn) error { - rawConn, err := conn.SyscallConn() - if err != nil { - return err - } - var ssoErr error - err = rawConn.Control(func(fd uintptr) { - ssoErr = syscall.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_DETACH_BPF, 0) - }) - if ssoErr != nil { - return ssoErr - } - return err -} diff --git a/vendor/github.com/cilium/ebpf/link/syscalls.go b/vendor/github.com/cilium/ebpf/link/syscalls.go deleted file mode 100644 index a661395b..00000000 --- a/vendor/github.com/cilium/ebpf/link/syscalls.go +++ /dev/null @@ -1,103 +0,0 @@ -package link - -import ( - "errors" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// Type is the kind of link. -type Type = sys.LinkType - -// Valid link types. -const ( - UnspecifiedType = sys.BPF_LINK_TYPE_UNSPEC - RawTracepointType = sys.BPF_LINK_TYPE_RAW_TRACEPOINT - TracingType = sys.BPF_LINK_TYPE_TRACING - CgroupType = sys.BPF_LINK_TYPE_CGROUP - IterType = sys.BPF_LINK_TYPE_ITER - NetNsType = sys.BPF_LINK_TYPE_NETNS - XDPType = sys.BPF_LINK_TYPE_XDP - PerfEventType = sys.BPF_LINK_TYPE_PERF_EVENT -) - -var haveProgAttach = internal.FeatureTest("BPF_PROG_ATTACH", "4.10", func() error { - prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ - Type: ebpf.CGroupSKB, - License: "MIT", - Instructions: asm.Instructions{ - asm.Mov.Imm(asm.R0, 0), - asm.Return(), - }, - }) - if err != nil { - return internal.ErrNotSupported - } - - // BPF_PROG_ATTACH was introduced at the same time as CGgroupSKB, - // so being able to load the program is enough to infer that we - // have the syscall. - prog.Close() - return nil -}) - -var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replacement", "5.5", func() error { - if err := haveProgAttach(); err != nil { - return err - } - - prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ - Type: ebpf.CGroupSKB, - AttachType: ebpf.AttachCGroupInetIngress, - License: "MIT", - Instructions: asm.Instructions{ - asm.Mov.Imm(asm.R0, 0), - asm.Return(), - }, - }) - if err != nil { - return internal.ErrNotSupported - } - defer prog.Close() - - // We know that we have BPF_PROG_ATTACH since we can load CGroupSKB programs. - // If passing BPF_F_REPLACE gives us EINVAL we know that the feature isn't - // present. - attr := sys.ProgAttachAttr{ - // We rely on this being checked after attachFlags. - TargetFd: ^uint32(0), - AttachBpfFd: uint32(prog.FD()), - AttachType: uint32(ebpf.AttachCGroupInetIngress), - AttachFlags: uint32(flagReplace), - } - - err = sys.ProgAttach(&attr) - if errors.Is(err, unix.EINVAL) { - return internal.ErrNotSupported - } - if errors.Is(err, unix.EBADF) { - return nil - } - return err -}) - -var haveBPFLink = internal.FeatureTest("bpf_link", "5.7", func() error { - attr := sys.LinkCreateAttr{ - // This is a hopefully invalid file descriptor, which triggers EBADF. - TargetFd: ^uint32(0), - ProgFd: ^uint32(0), - AttachType: sys.AttachType(ebpf.AttachCGroupInetIngress), - } - _, err := sys.LinkCreate(&attr) - if errors.Is(err, unix.EINVAL) { - return internal.ErrNotSupported - } - if errors.Is(err, unix.EBADF) { - return nil - } - return err -}) diff --git a/vendor/github.com/cilium/ebpf/link/tracepoint.go b/vendor/github.com/cilium/ebpf/link/tracepoint.go deleted file mode 100644 index a59ef9d1..00000000 --- a/vendor/github.com/cilium/ebpf/link/tracepoint.go +++ /dev/null @@ -1,77 +0,0 @@ -package link - -import ( - "fmt" - - "github.com/cilium/ebpf" -) - -// TracepointOptions defines additional parameters that will be used -// when loading Tracepoints. -type TracepointOptions struct { - // Arbitrary value that can be fetched from an eBPF program - // via `bpf_get_attach_cookie()`. - // - // Needs kernel 5.15+. - Cookie uint64 -} - -// Tracepoint attaches the given eBPF program to the tracepoint with the given -// group and name. See /sys/kernel/debug/tracing/events to find available -// tracepoints. The top-level directory is the group, the event's subdirectory -// is the name. Example: -// -// tp, err := Tracepoint("syscalls", "sys_enter_fork", prog, nil) -// -// Losing the reference to the resulting Link (tp) will close the Tracepoint -// and prevent further execution of prog. The Link must be Closed during -// program shutdown to avoid leaking system resources. -// -// Note that attaching eBPF programs to syscalls (sys_enter_*/sys_exit_*) is -// only possible as of kernel 4.14 (commit cf5f5ce). -func Tracepoint(group, name string, prog *ebpf.Program, opts *TracepointOptions) (Link, error) { - if group == "" || name == "" { - return nil, fmt.Errorf("group and name cannot be empty: %w", errInvalidInput) - } - if prog == nil { - return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) - } - if !isValidTraceID(group) || !isValidTraceID(name) { - return nil, fmt.Errorf("group and name '%s/%s' must be alphanumeric or underscore: %w", group, name, errInvalidInput) - } - if prog.Type() != ebpf.TracePoint { - return nil, fmt.Errorf("eBPF program type %s is not a Tracepoint: %w", prog.Type(), errInvalidInput) - } - - tid, err := getTraceEventID(group, name) - if err != nil { - return nil, err - } - - fd, err := openTracepointPerfEvent(tid, perfAllThreads) - if err != nil { - return nil, err - } - - var cookie uint64 - if opts != nil { - cookie = opts.Cookie - } - - pe := &perfEvent{ - typ: tracepointEvent, - group: group, - name: name, - tracefsID: tid, - cookie: cookie, - fd: fd, - } - - lnk, err := attachPerfEvent(pe, prog) - if err != nil { - pe.Close() - return nil, err - } - - return lnk, nil -} diff --git a/vendor/github.com/cilium/ebpf/link/tracing.go b/vendor/github.com/cilium/ebpf/link/tracing.go deleted file mode 100644 index e47e61a3..00000000 --- a/vendor/github.com/cilium/ebpf/link/tracing.go +++ /dev/null @@ -1,141 +0,0 @@ -package link - -import ( - "fmt" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal/sys" -) - -type tracing struct { - RawLink -} - -func (f *tracing) Update(new *ebpf.Program) error { - return fmt.Errorf("tracing update: %w", ErrNotSupported) -} - -// AttachFreplace attaches the given eBPF program to the function it replaces. -// -// The program and name can either be provided at link time, or can be provided -// at program load time. If they were provided at load time, they should be nil -// and empty respectively here, as they will be ignored by the kernel. -// Examples: -// -// AttachFreplace(dispatcher, "function", replacement) -// AttachFreplace(nil, "", replacement) -func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (Link, error) { - if (name == "") != (targetProg == nil) { - return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput) - } - if prog == nil { - return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) - } - if prog.Type() != ebpf.Extension { - return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput) - } - - var ( - target int - typeID btf.TypeID - ) - if targetProg != nil { - btfHandle, err := targetProg.Handle() - if err != nil { - return nil, err - } - defer btfHandle.Close() - - spec, err := btfHandle.Spec(nil) - if err != nil { - return nil, err - } - - var function *btf.Func - if err := spec.TypeByName(name, &function); err != nil { - return nil, err - } - - target = targetProg.FD() - typeID, err = spec.TypeID(function) - if err != nil { - return nil, err - } - } - - link, err := AttachRawLink(RawLinkOptions{ - Target: target, - Program: prog, - Attach: ebpf.AttachNone, - BTF: typeID, - }) - if err != nil { - return nil, err - } - - return &tracing{*link}, nil -} - -type TracingOptions struct { - // Program must be of type Tracing with attach type - // AttachTraceFEntry/AttachTraceFExit/AttachModifyReturn or - // AttachTraceRawTp. - Program *ebpf.Program -} - -type LSMOptions struct { - // Program must be of type LSM with attach type - // AttachLSMMac. - Program *ebpf.Program -} - -// attachBTFID links all BPF program types (Tracing/LSM) that they attach to a btf_id. -func attachBTFID(program *ebpf.Program) (Link, error) { - if program.FD() < 0 { - return nil, fmt.Errorf("invalid program %w", sys.ErrClosedFd) - } - - fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{ - ProgFd: uint32(program.FD()), - }) - if err != nil { - return nil, err - } - - raw := RawLink{fd: fd} - info, err := raw.Info() - if err != nil { - raw.Close() - return nil, err - } - - if info.Type == RawTracepointType { - // Sadness upon sadness: a Tracing program with AttachRawTp returns - // a raw_tracepoint link. Other types return a tracing link. - return &rawTracepoint{raw}, nil - } - - return &tracing{RawLink: RawLink{fd: fd}}, nil -} - -// AttachTracing links a tracing (fentry/fexit/fmod_ret) BPF program or -// a BTF-powered raw tracepoint (tp_btf) BPF Program to a BPF hook defined -// in kernel modules. -func AttachTracing(opts TracingOptions) (Link, error) { - if t := opts.Program.Type(); t != ebpf.Tracing { - return nil, fmt.Errorf("invalid program type %s, expected Tracing", t) - } - - return attachBTFID(opts.Program) -} - -// AttachLSM links a Linux security module (LSM) BPF Program to a BPF -// hook defined in kernel modules. -func AttachLSM(opts LSMOptions) (Link, error) { - if t := opts.Program.Type(); t != ebpf.LSM { - return nil, fmt.Errorf("invalid program type %s, expected LSM", t) - } - - return attachBTFID(opts.Program) -} diff --git a/vendor/github.com/cilium/ebpf/link/uprobe.go b/vendor/github.com/cilium/ebpf/link/uprobe.go deleted file mode 100644 index edf925b5..00000000 --- a/vendor/github.com/cilium/ebpf/link/uprobe.go +++ /dev/null @@ -1,373 +0,0 @@ -package link - -import ( - "debug/elf" - "errors" - "fmt" - "os" - "path/filepath" - "strings" - "sync" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/internal" -) - -var ( - uprobeEventsPath = filepath.Join(tracefsPath, "uprobe_events") - - uprobeRetprobeBit = struct { - once sync.Once - value uint64 - err error - }{} - - uprobeRefCtrOffsetPMUPath = "/sys/bus/event_source/devices/uprobe/format/ref_ctr_offset" - // elixir.bootlin.com/linux/v5.15-rc7/source/kernel/events/core.c#L9799 - uprobeRefCtrOffsetShift = 32 - haveRefCtrOffsetPMU = internal.FeatureTest("RefCtrOffsetPMU", "4.20", func() error { - _, err := os.Stat(uprobeRefCtrOffsetPMUPath) - if err != nil { - return internal.ErrNotSupported - } - return nil - }) - - // ErrNoSymbol indicates that the given symbol was not found - // in the ELF symbols table. - ErrNoSymbol = errors.New("not found") -) - -// Executable defines an executable program on the filesystem. -type Executable struct { - // Path of the executable on the filesystem. - path string - // Parsed ELF and dynamic symbols' addresses. - addresses map[string]uint64 -} - -// UprobeOptions defines additional parameters that will be used -// when loading Uprobes. -type UprobeOptions struct { - // Symbol address. Must be provided in case of external symbols (shared libs). - // If set, overrides the address eventually parsed from the executable. - Address uint64 - // The offset relative to given symbol. Useful when tracing an arbitrary point - // inside the frame of given symbol. - // - // Note: this field changed from being an absolute offset to being relative - // to Address. - Offset uint64 - // Only set the uprobe on the given process ID. Useful when tracing - // shared library calls or programs that have many running instances. - PID int - // Automatically manage SDT reference counts (semaphores). - // - // If this field is set, the Kernel will increment/decrement the - // semaphore located in the process memory at the provided address on - // probe attach/detach. - // - // See also: - // sourceware.org/systemtap/wiki/UserSpaceProbeImplementation (Semaphore Handling) - // github.com/torvalds/linux/commit/1cc33161a83d - // github.com/torvalds/linux/commit/a6ca88b241d5 - RefCtrOffset uint64 - // Arbitrary value that can be fetched from an eBPF program - // via `bpf_get_attach_cookie()`. - // - // Needs kernel 5.15+. - Cookie uint64 -} - -// To open a new Executable, use: -// -// OpenExecutable("/bin/bash") -// -// The returned value can then be used to open Uprobe(s). -func OpenExecutable(path string) (*Executable, error) { - if path == "" { - return nil, fmt.Errorf("path cannot be empty") - } - - f, err := os.Open(path) - if err != nil { - return nil, fmt.Errorf("open file '%s': %w", path, err) - } - defer f.Close() - - se, err := internal.NewSafeELFFile(f) - if err != nil { - return nil, fmt.Errorf("parse ELF file: %w", err) - } - - if se.Type != elf.ET_EXEC && se.Type != elf.ET_DYN { - // ELF is not an executable or a shared object. - return nil, errors.New("the given file is not an executable or a shared object") - } - - ex := Executable{ - path: path, - addresses: make(map[string]uint64), - } - - if err := ex.load(se); err != nil { - return nil, err - } - - return &ex, nil -} - -func (ex *Executable) load(f *internal.SafeELFFile) error { - syms, err := f.Symbols() - if err != nil && !errors.Is(err, elf.ErrNoSymbols) { - return err - } - - dynsyms, err := f.DynamicSymbols() - if err != nil && !errors.Is(err, elf.ErrNoSymbols) { - return err - } - - syms = append(syms, dynsyms...) - - for _, s := range syms { - if elf.ST_TYPE(s.Info) != elf.STT_FUNC { - // Symbol not associated with a function or other executable code. - continue - } - - address := s.Value - - // Loop over ELF segments. - for _, prog := range f.Progs { - // Skip uninteresting segments. - if prog.Type != elf.PT_LOAD || (prog.Flags&elf.PF_X) == 0 { - continue - } - - if prog.Vaddr <= s.Value && s.Value < (prog.Vaddr+prog.Memsz) { - // If the symbol value is contained in the segment, calculate - // the symbol offset. - // - // fn symbol offset = fn symbol VA - .text VA + .text offset - // - // stackoverflow.com/a/40249502 - address = s.Value - prog.Vaddr + prog.Off - break - } - } - - ex.addresses[s.Name] = address - } - - return nil -} - -// address calculates the address of a symbol in the executable. -// -// opts must not be nil. -func (ex *Executable) address(symbol string, opts *UprobeOptions) (uint64, error) { - if opts.Address > 0 { - return opts.Address + opts.Offset, nil - } - - address, ok := ex.addresses[symbol] - if !ok { - return 0, fmt.Errorf("symbol %s: %w", symbol, ErrNoSymbol) - } - - // Symbols with location 0 from section undef are shared library calls and - // are relocated before the binary is executed. Dynamic linking is not - // implemented by the library, so mark this as unsupported for now. - // - // Since only offset values are stored and not elf.Symbol, if the value is 0, - // assume it's an external symbol. - if address == 0 { - return 0, fmt.Errorf("cannot resolve %s library call '%s': %w "+ - "(consider providing UprobeOptions.Address)", ex.path, symbol, ErrNotSupported) - } - - return address + opts.Offset, nil -} - -// Uprobe attaches the given eBPF program to a perf event that fires when the -// given symbol starts executing in the given Executable. -// For example, /bin/bash::main(): -// -// ex, _ = OpenExecutable("/bin/bash") -// ex.Uprobe("main", prog, nil) -// -// When using symbols which belongs to shared libraries, -// an offset must be provided via options: -// -// up, err := ex.Uprobe("main", prog, &UprobeOptions{Offset: 0x123}) -// -// Note: Setting the Offset field in the options supersedes the symbol's offset. -// -// Losing the reference to the resulting Link (up) will close the Uprobe -// and prevent further execution of prog. The Link must be Closed during -// program shutdown to avoid leaking system resources. -// -// Functions provided by shared libraries can currently not be traced and -// will result in an ErrNotSupported. -func (ex *Executable) Uprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions) (Link, error) { - u, err := ex.uprobe(symbol, prog, opts, false) - if err != nil { - return nil, err - } - - lnk, err := attachPerfEvent(u, prog) - if err != nil { - u.Close() - return nil, err - } - - return lnk, nil -} - -// Uretprobe attaches the given eBPF program to a perf event that fires right -// before the given symbol exits. For example, /bin/bash::main(): -// -// ex, _ = OpenExecutable("/bin/bash") -// ex.Uretprobe("main", prog, nil) -// -// When using symbols which belongs to shared libraries, -// an offset must be provided via options: -// -// up, err := ex.Uretprobe("main", prog, &UprobeOptions{Offset: 0x123}) -// -// Note: Setting the Offset field in the options supersedes the symbol's offset. -// -// Losing the reference to the resulting Link (up) will close the Uprobe -// and prevent further execution of prog. The Link must be Closed during -// program shutdown to avoid leaking system resources. -// -// Functions provided by shared libraries can currently not be traced and -// will result in an ErrNotSupported. -func (ex *Executable) Uretprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions) (Link, error) { - u, err := ex.uprobe(symbol, prog, opts, true) - if err != nil { - return nil, err - } - - lnk, err := attachPerfEvent(u, prog) - if err != nil { - u.Close() - return nil, err - } - - return lnk, nil -} - -// uprobe opens a perf event for the given binary/symbol and attaches prog to it. -// If ret is true, create a uretprobe. -func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions, ret bool) (*perfEvent, error) { - if prog == nil { - return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput) - } - if prog.Type() != ebpf.Kprobe { - return nil, fmt.Errorf("eBPF program type %s is not Kprobe: %w", prog.Type(), errInvalidInput) - } - if opts == nil { - opts = &UprobeOptions{} - } - - offset, err := ex.address(symbol, opts) - if err != nil { - return nil, err - } - - pid := opts.PID - if pid == 0 { - pid = perfAllThreads - } - - if opts.RefCtrOffset != 0 { - if err := haveRefCtrOffsetPMU(); err != nil { - return nil, fmt.Errorf("uprobe ref_ctr_offset: %w", err) - } - } - - args := probeArgs{ - symbol: symbol, - path: ex.path, - offset: offset, - pid: pid, - refCtrOffset: opts.RefCtrOffset, - ret: ret, - cookie: opts.Cookie, - } - - // Use uprobe PMU if the kernel has it available. - tp, err := pmuUprobe(args) - if err == nil { - return tp, nil - } - if err != nil && !errors.Is(err, ErrNotSupported) { - return nil, fmt.Errorf("creating perf_uprobe PMU: %w", err) - } - - // Use tracefs if uprobe PMU is missing. - args.symbol = sanitizeSymbol(symbol) - tp, err = tracefsUprobe(args) - if err != nil { - return nil, fmt.Errorf("creating trace event '%s:%s' in tracefs: %w", ex.path, symbol, err) - } - - return tp, nil -} - -// pmuUprobe opens a perf event based on the uprobe PMU. -func pmuUprobe(args probeArgs) (*perfEvent, error) { - return pmuProbe(uprobeType, args) -} - -// tracefsUprobe creates a Uprobe tracefs entry. -func tracefsUprobe(args probeArgs) (*perfEvent, error) { - return tracefsProbe(uprobeType, args) -} - -// sanitizeSymbol replaces every invalid character for the tracefs api with an underscore. -// It is equivalent to calling regexp.MustCompile("[^a-zA-Z0-9]+").ReplaceAllString("_"). -func sanitizeSymbol(s string) string { - var b strings.Builder - b.Grow(len(s)) - var skip bool - for _, c := range []byte(s) { - switch { - case c >= 'a' && c <= 'z', - c >= 'A' && c <= 'Z', - c >= '0' && c <= '9': - skip = false - b.WriteByte(c) - - default: - if !skip { - b.WriteByte('_') - skip = true - } - } - } - - return b.String() -} - -// uprobeToken creates the PATH:OFFSET(REF_CTR_OFFSET) token for the tracefs api. -func uprobeToken(args probeArgs) string { - po := fmt.Sprintf("%s:%#x", args.path, args.offset) - - if args.refCtrOffset != 0 { - // This is not documented in Documentation/trace/uprobetracer.txt. - // elixir.bootlin.com/linux/v5.15-rc7/source/kernel/trace/trace.c#L5564 - po += fmt.Sprintf("(%#x)", args.refCtrOffset) - } - - return po -} - -func uretprobeBit() (uint64, error) { - uprobeRetprobeBit.once.Do(func() { - uprobeRetprobeBit.value, uprobeRetprobeBit.err = determineRetprobeBit(uprobeType) - }) - return uprobeRetprobeBit.value, uprobeRetprobeBit.err -} diff --git a/vendor/github.com/cilium/ebpf/link/xdp.go b/vendor/github.com/cilium/ebpf/link/xdp.go deleted file mode 100644 index aa8dd3a4..00000000 --- a/vendor/github.com/cilium/ebpf/link/xdp.go +++ /dev/null @@ -1,54 +0,0 @@ -package link - -import ( - "fmt" - - "github.com/cilium/ebpf" -) - -// XDPAttachFlags represents how XDP program will be attached to interface. -type XDPAttachFlags uint32 - -const ( - // XDPGenericMode (SKB) links XDP BPF program for drivers which do - // not yet support native XDP. - XDPGenericMode XDPAttachFlags = 1 << (iota + 1) - // XDPDriverMode links XDP BPF program into the driver’s receive path. - XDPDriverMode - // XDPOffloadMode offloads the entire XDP BPF program into hardware. - XDPOffloadMode -) - -type XDPOptions struct { - // Program must be an XDP BPF program. - Program *ebpf.Program - - // Interface is the interface index to attach program to. - Interface int - - // Flags is one of XDPAttachFlags (optional). - // - // Only one XDP mode should be set, without flag defaults - // to driver/generic mode (best effort). - Flags XDPAttachFlags -} - -// AttachXDP links an XDP BPF program to an XDP hook. -func AttachXDP(opts XDPOptions) (Link, error) { - if t := opts.Program.Type(); t != ebpf.XDP { - return nil, fmt.Errorf("invalid program type %s, expected XDP", t) - } - - if opts.Interface < 1 { - return nil, fmt.Errorf("invalid interface index: %d", opts.Interface) - } - - rawLink, err := AttachRawLink(RawLinkOptions{ - Program: opts.Program, - Attach: ebpf.AttachXDP, - Target: opts.Interface, - Flags: uint32(opts.Flags), - }) - - return rawLink, err -} diff --git a/vendor/github.com/cilium/ebpf/linker.go b/vendor/github.com/cilium/ebpf/linker.go deleted file mode 100644 index e6276b18..00000000 --- a/vendor/github.com/cilium/ebpf/linker.go +++ /dev/null @@ -1,238 +0,0 @@ -package ebpf - -import ( - "errors" - "fmt" - "sync" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/btf" -) - -// splitSymbols splits insns into subsections delimited by Symbol Instructions. -// insns cannot be empty and must start with a Symbol Instruction. -// -// The resulting map is indexed by Symbol name. -func splitSymbols(insns asm.Instructions) (map[string]asm.Instructions, error) { - if len(insns) == 0 { - return nil, errors.New("insns is empty") - } - - if insns[0].Symbol() == "" { - return nil, errors.New("insns must start with a Symbol") - } - - var name string - progs := make(map[string]asm.Instructions) - for _, ins := range insns { - if sym := ins.Symbol(); sym != "" { - if progs[sym] != nil { - return nil, fmt.Errorf("insns contains duplicate Symbol %s", sym) - } - name = sym - } - - progs[name] = append(progs[name], ins) - } - - return progs, nil -} - -// The linker is responsible for resolving bpf-to-bpf calls between programs -// within an ELF. Each BPF program must be a self-contained binary blob, -// so when an instruction in one ELF program section wants to jump to -// a function in another, the linker needs to pull in the bytecode -// (and BTF info) of the target function and concatenate the instruction -// streams. -// -// Later on in the pipeline, all call sites are fixed up with relative jumps -// within this newly-created instruction stream to then finally hand off to -// the kernel with BPF_PROG_LOAD. -// -// Each function is denoted by an ELF symbol and the compiler takes care of -// register setup before each jump instruction. - -// hasFunctionReferences returns true if insns contains one or more bpf2bpf -// function references. -func hasFunctionReferences(insns asm.Instructions) bool { - for _, i := range insns { - if i.IsFunctionReference() { - return true - } - } - return false -} - -// applyRelocations collects and applies any CO-RE relocations in insns. -// -// Passing a nil target will relocate against the running kernel. insns are -// modified in place. -func applyRelocations(insns asm.Instructions, local, target *btf.Spec) error { - var relos []*btf.CORERelocation - var reloInsns []*asm.Instruction - iter := insns.Iterate() - for iter.Next() { - if relo := btf.CORERelocationMetadata(iter.Ins); relo != nil { - relos = append(relos, relo) - reloInsns = append(reloInsns, iter.Ins) - } - } - - if len(relos) == 0 { - return nil - } - - target, err := maybeLoadKernelBTF(target) - if err != nil { - return err - } - - fixups, err := btf.CORERelocate(local, target, relos) - if err != nil { - return err - } - - for i, fixup := range fixups { - if err := fixup.Apply(reloInsns[i]); err != nil { - return fmt.Errorf("apply fixup %s: %w", &fixup, err) - } - } - - return nil -} - -// flattenPrograms resolves bpf-to-bpf calls for a set of programs. -// -// Links all programs in names by modifying their ProgramSpec in progs. -func flattenPrograms(progs map[string]*ProgramSpec, names []string) { - // Pre-calculate all function references. - refs := make(map[*ProgramSpec][]string) - for _, prog := range progs { - refs[prog] = prog.Instructions.FunctionReferences() - } - - // Create a flattened instruction stream, but don't modify progs yet to - // avoid linking multiple times. - flattened := make([]asm.Instructions, 0, len(names)) - for _, name := range names { - flattened = append(flattened, flattenInstructions(name, progs, refs)) - } - - // Finally, assign the flattened instructions. - for i, name := range names { - progs[name].Instructions = flattened[i] - } -} - -// flattenInstructions resolves bpf-to-bpf calls for a single program. -// -// Flattens the instructions of prog by concatenating the instructions of all -// direct and indirect dependencies. -// -// progs contains all referenceable programs, while refs contain the direct -// dependencies of each program. -func flattenInstructions(name string, progs map[string]*ProgramSpec, refs map[*ProgramSpec][]string) asm.Instructions { - prog := progs[name] - - insns := make(asm.Instructions, len(prog.Instructions)) - copy(insns, prog.Instructions) - - // Add all direct references of prog to the list of to be linked programs. - pending := make([]string, len(refs[prog])) - copy(pending, refs[prog]) - - // All references for which we've appended instructions. - linked := make(map[string]bool) - - // Iterate all pending references. We can't use a range since pending is - // modified in the body below. - for len(pending) > 0 { - var ref string - ref, pending = pending[0], pending[1:] - - if linked[ref] { - // We've already linked this ref, don't append instructions again. - continue - } - - progRef := progs[ref] - if progRef == nil { - // We don't have instructions that go with this reference. This - // happens when calling extern functions. - continue - } - - insns = append(insns, progRef.Instructions...) - linked[ref] = true - - // Make sure we link indirect references. - pending = append(pending, refs[progRef]...) - } - - return insns -} - -// fixupAndValidate is called by the ELF reader right before marshaling the -// instruction stream. It performs last-minute adjustments to the program and -// runs some sanity checks before sending it off to the kernel. -func fixupAndValidate(insns asm.Instructions) error { - iter := insns.Iterate() - for iter.Next() { - ins := iter.Ins - - // Map load was tagged with a Reference, but does not contain a Map pointer. - if ins.IsLoadFromMap() && ins.Reference() != "" && ins.Map() == nil { - return fmt.Errorf("instruction %d: map %s: %w", iter.Index, ins.Reference(), asm.ErrUnsatisfiedMapReference) - } - - fixupProbeReadKernel(ins) - } - - return nil -} - -// fixupProbeReadKernel replaces calls to bpf_probe_read_{kernel,user}(_str) -// with bpf_probe_read(_str) on kernels that don't support it yet. -func fixupProbeReadKernel(ins *asm.Instruction) { - if !ins.IsBuiltinCall() { - return - } - - // Kernel supports bpf_probe_read_kernel, nothing to do. - if haveProbeReadKernel() == nil { - return - } - - switch asm.BuiltinFunc(ins.Constant) { - case asm.FnProbeReadKernel, asm.FnProbeReadUser: - ins.Constant = int64(asm.FnProbeRead) - case asm.FnProbeReadKernelStr, asm.FnProbeReadUserStr: - ins.Constant = int64(asm.FnProbeReadStr) - } -} - -var kernelBTF struct { - sync.Mutex - spec *btf.Spec -} - -// maybeLoadKernelBTF loads the current kernel's BTF if spec is nil, otherwise -// it returns spec unchanged. -// -// The kernel BTF is cached for the lifetime of the process. -func maybeLoadKernelBTF(spec *btf.Spec) (*btf.Spec, error) { - if spec != nil { - return spec, nil - } - - kernelBTF.Lock() - defer kernelBTF.Unlock() - - if kernelBTF.spec != nil { - return kernelBTF.spec, nil - } - - var err error - kernelBTF.spec, err = btf.LoadKernelSpec() - return kernelBTF.spec, err -} diff --git a/vendor/github.com/cilium/ebpf/map.go b/vendor/github.com/cilium/ebpf/map.go deleted file mode 100644 index e4a6c87e..00000000 --- a/vendor/github.com/cilium/ebpf/map.go +++ /dev/null @@ -1,1424 +0,0 @@ -package ebpf - -import ( - "bytes" - "errors" - "fmt" - "io" - "math/rand" - "path/filepath" - "reflect" - "time" - "unsafe" - - "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// Errors returned by Map and MapIterator methods. -var ( - ErrKeyNotExist = errors.New("key does not exist") - ErrKeyExist = errors.New("key already exists") - ErrIterationAborted = errors.New("iteration aborted") - ErrMapIncompatible = errors.New("map spec is incompatible with existing map") - errMapNoBTFValue = errors.New("map spec does not contain a BTF Value") -) - -// MapOptions control loading a map into the kernel. -type MapOptions struct { - // The base path to pin maps in if requested via PinByName. - // Existing maps will be re-used if they are compatible, otherwise an - // error is returned. - PinPath string - LoadPinOptions LoadPinOptions -} - -// MapID represents the unique ID of an eBPF map -type MapID uint32 - -// MapSpec defines a Map. -type MapSpec struct { - // Name is passed to the kernel as a debug aid. Must only contain - // alpha numeric and '_' characters. - Name string - Type MapType - KeySize uint32 - ValueSize uint32 - MaxEntries uint32 - - // Flags is passed to the kernel and specifies additional map - // creation attributes. - Flags uint32 - - // Automatically pin and load a map from MapOptions.PinPath. - // Generates an error if an existing pinned map is incompatible with the MapSpec. - Pinning PinType - - // Specify numa node during map creation - // (effective only if unix.BPF_F_NUMA_NODE flag is set, - // which can be imported from golang.org/x/sys/unix) - NumaNode uint32 - - // The initial contents of the map. May be nil. - Contents []MapKV - - // Whether to freeze a map after setting its initial contents. - Freeze bool - - // InnerMap is used as a template for ArrayOfMaps and HashOfMaps - InnerMap *MapSpec - - // Extra trailing bytes found in the ELF map definition when using structs - // larger than libbpf's bpf_map_def. nil if no trailing bytes were present. - // Must be nil or empty before instantiating the MapSpec into a Map. - Extra *bytes.Reader - - // The key and value type of this map. May be nil. - Key, Value btf.Type - - // The BTF associated with this map. - BTF *btf.Spec -} - -func (ms *MapSpec) String() string { - return fmt.Sprintf("%s(keySize=%d, valueSize=%d, maxEntries=%d, flags=%d)", ms.Type, ms.KeySize, ms.ValueSize, ms.MaxEntries, ms.Flags) -} - -// Copy returns a copy of the spec. -// -// MapSpec.Contents is a shallow copy. -func (ms *MapSpec) Copy() *MapSpec { - if ms == nil { - return nil - } - - cpy := *ms - - cpy.Contents = make([]MapKV, len(ms.Contents)) - copy(cpy.Contents, ms.Contents) - - cpy.InnerMap = ms.InnerMap.Copy() - - return &cpy -} - -// hasBTF returns true if the MapSpec has a valid BTF spec and if its -// map type supports associated BTF metadata in the kernel. -func (ms *MapSpec) hasBTF() bool { - return ms.BTF != nil && ms.Type.hasBTF() -} - -func (ms *MapSpec) clampPerfEventArraySize() error { - if ms.Type != PerfEventArray { - return nil - } - - n, err := internal.PossibleCPUs() - if err != nil { - return fmt.Errorf("perf event array: %w", err) - } - - if n := uint32(n); ms.MaxEntries > n { - ms.MaxEntries = n - } - - return nil -} - -// dataSection returns the contents and BTF Datasec descriptor of the spec. -func (ms *MapSpec) dataSection() ([]byte, *btf.Datasec, error) { - - if ms.Value == nil { - return nil, nil, errMapNoBTFValue - } - - ds, ok := ms.Value.(*btf.Datasec) - if !ok { - return nil, nil, fmt.Errorf("map value BTF is a %T, not a *btf.Datasec", ms.Value) - } - - if n := len(ms.Contents); n != 1 { - return nil, nil, fmt.Errorf("expected one key, found %d", n) - } - - kv := ms.Contents[0] - value, ok := kv.Value.([]byte) - if !ok { - return nil, nil, fmt.Errorf("value at first map key is %T, not []byte", kv.Value) - } - - return value, ds, nil -} - -// MapKV is used to initialize the contents of a Map. -type MapKV struct { - Key interface{} - Value interface{} -} - -func (ms *MapSpec) checkCompatibility(m *Map) error { - switch { - case m.typ != ms.Type: - return fmt.Errorf("expected type %v, got %v: %w", ms.Type, m.typ, ErrMapIncompatible) - - case m.keySize != ms.KeySize: - return fmt.Errorf("expected key size %v, got %v: %w", ms.KeySize, m.keySize, ErrMapIncompatible) - - case m.valueSize != ms.ValueSize: - return fmt.Errorf("expected value size %v, got %v: %w", ms.ValueSize, m.valueSize, ErrMapIncompatible) - - case !(ms.Type == PerfEventArray && ms.MaxEntries == 0) && - m.maxEntries != ms.MaxEntries: - return fmt.Errorf("expected max entries %v, got %v: %w", ms.MaxEntries, m.maxEntries, ErrMapIncompatible) - - case m.flags != ms.Flags: - return fmt.Errorf("expected flags %v, got %v: %w", ms.Flags, m.flags, ErrMapIncompatible) - } - return nil -} - -// Map represents a Map file descriptor. -// -// It is not safe to close a map which is used by other goroutines. -// -// Methods which take interface{} arguments by default encode -// them using binary.Read/Write in the machine's native endianness. -// -// Implement encoding.BinaryMarshaler or encoding.BinaryUnmarshaler -// if you require custom encoding. -type Map struct { - name string - fd *sys.FD - typ MapType - keySize uint32 - valueSize uint32 - maxEntries uint32 - flags uint32 - pinnedPath string - // Per CPU maps return values larger than the size in the spec - fullValueSize int -} - -// NewMapFromFD creates a map from a raw fd. -// -// You should not use fd after calling this function. -func NewMapFromFD(fd int) (*Map, error) { - f, err := sys.NewFD(fd) - if err != nil { - return nil, err - } - - return newMapFromFD(f) -} - -func newMapFromFD(fd *sys.FD) (*Map, error) { - info, err := newMapInfoFromFd(fd) - if err != nil { - fd.Close() - return nil, fmt.Errorf("get map info: %w", err) - } - - return newMap(fd, info.Name, info.Type, info.KeySize, info.ValueSize, info.MaxEntries, info.Flags) -} - -// NewMap creates a new Map. -// -// It's equivalent to calling NewMapWithOptions with default options. -func NewMap(spec *MapSpec) (*Map, error) { - return NewMapWithOptions(spec, MapOptions{}) -} - -// NewMapWithOptions creates a new Map. -// -// Creating a map for the first time will perform feature detection -// by creating small, temporary maps. -// -// The caller is responsible for ensuring the process' rlimit is set -// sufficiently high for locking memory during map creation. This can be done -// by calling rlimit.RemoveMemlock() prior to calling NewMapWithOptions. -// -// May return an error wrapping ErrMapIncompatible. -func NewMapWithOptions(spec *MapSpec, opts MapOptions) (*Map, error) { - handles := newHandleCache() - defer handles.close() - - m, err := newMapWithOptions(spec, opts, handles) - if err != nil { - return nil, fmt.Errorf("creating map: %w", err) - } - - if err := m.finalize(spec); err != nil { - m.Close() - return nil, fmt.Errorf("populating map: %w", err) - } - - return m, nil -} - -func newMapWithOptions(spec *MapSpec, opts MapOptions, handles *handleCache) (_ *Map, err error) { - closeOnError := func(c io.Closer) { - if err != nil { - c.Close() - } - } - - switch spec.Pinning { - case PinByName: - if spec.Name == "" { - return nil, fmt.Errorf("pin by name: missing Name") - } - - if opts.PinPath == "" { - return nil, fmt.Errorf("pin by name: missing MapOptions.PinPath") - } - - path := filepath.Join(opts.PinPath, spec.Name) - m, err := LoadPinnedMap(path, &opts.LoadPinOptions) - if errors.Is(err, unix.ENOENT) { - break - } - if err != nil { - return nil, fmt.Errorf("load pinned map: %w", err) - } - defer closeOnError(m) - - if err := spec.checkCompatibility(m); err != nil { - return nil, fmt.Errorf("use pinned map %s: %w", spec.Name, err) - } - - return m, nil - - case PinNone: - // Nothing to do here - - default: - return nil, fmt.Errorf("pin type %d: %w", int(spec.Pinning), ErrNotSupported) - } - - var innerFd *sys.FD - if spec.Type == ArrayOfMaps || spec.Type == HashOfMaps { - if spec.InnerMap == nil { - return nil, fmt.Errorf("%s requires InnerMap", spec.Type) - } - - if spec.InnerMap.Pinning != PinNone { - return nil, errors.New("inner maps cannot be pinned") - } - - template, err := spec.InnerMap.createMap(nil, opts, handles) - if err != nil { - return nil, fmt.Errorf("inner map: %w", err) - } - defer template.Close() - - // Intentionally skip populating and freezing (finalizing) - // the inner map template since it will be removed shortly. - - innerFd = template.fd - } - - m, err := spec.createMap(innerFd, opts, handles) - if err != nil { - return nil, err - } - defer closeOnError(m) - - if spec.Pinning == PinByName { - path := filepath.Join(opts.PinPath, spec.Name) - if err := m.Pin(path); err != nil { - return nil, fmt.Errorf("pin map: %w", err) - } - } - - return m, nil -} - -// createMap validates the spec's properties and creates the map in the kernel -// using the given opts. It does not populate or freeze the map. -func (spec *MapSpec) createMap(inner *sys.FD, opts MapOptions, handles *handleCache) (_ *Map, err error) { - closeOnError := func(closer io.Closer) { - if err != nil { - closer.Close() - } - } - - spec = spec.Copy() - - // Kernels 4.13 through 5.4 used a struct bpf_map_def that contained - // additional 'inner_map_idx' and later 'numa_node' fields. - // In order to support loading these definitions, tolerate the presence of - // extra bytes, but require them to be zeroes. - if spec.Extra != nil { - if _, err := io.Copy(internal.DiscardZeroes{}, spec.Extra); err != nil { - return nil, errors.New("extra contains unhandled non-zero bytes, drain before creating map") - } - } - - switch spec.Type { - case ArrayOfMaps, HashOfMaps: - if err := haveNestedMaps(); err != nil { - return nil, err - } - - if spec.ValueSize != 0 && spec.ValueSize != 4 { - return nil, errors.New("ValueSize must be zero or four for map of map") - } - spec.ValueSize = 4 - - case PerfEventArray: - if spec.KeySize != 0 && spec.KeySize != 4 { - return nil, errors.New("KeySize must be zero or four for perf event array") - } - spec.KeySize = 4 - - if spec.ValueSize != 0 && spec.ValueSize != 4 { - return nil, errors.New("ValueSize must be zero or four for perf event array") - } - spec.ValueSize = 4 - - if spec.MaxEntries == 0 { - n, err := internal.PossibleCPUs() - if err != nil { - return nil, fmt.Errorf("perf event array: %w", err) - } - spec.MaxEntries = uint32(n) - } - } - - if spec.Flags&(unix.BPF_F_RDONLY_PROG|unix.BPF_F_WRONLY_PROG) > 0 || spec.Freeze { - if err := haveMapMutabilityModifiers(); err != nil { - return nil, fmt.Errorf("map create: %w", err) - } - } - if spec.Flags&unix.BPF_F_MMAPABLE > 0 { - if err := haveMmapableMaps(); err != nil { - return nil, fmt.Errorf("map create: %w", err) - } - } - if spec.Flags&unix.BPF_F_INNER_MAP > 0 { - if err := haveInnerMaps(); err != nil { - return nil, fmt.Errorf("map create: %w", err) - } - } - if spec.Flags&unix.BPF_F_NO_PREALLOC > 0 { - if err := haveNoPreallocMaps(); err != nil { - return nil, fmt.Errorf("map create: %w", err) - } - } - - attr := sys.MapCreateAttr{ - MapType: sys.MapType(spec.Type), - KeySize: spec.KeySize, - ValueSize: spec.ValueSize, - MaxEntries: spec.MaxEntries, - MapFlags: spec.Flags, - NumaNode: spec.NumaNode, - } - - if inner != nil { - attr.InnerMapFd = inner.Uint() - } - - if haveObjName() == nil { - attr.MapName = sys.NewObjName(spec.Name) - } - - if spec.hasBTF() { - handle, err := handles.btfHandle(spec.BTF) - if err != nil && !errors.Is(err, btf.ErrNotSupported) { - return nil, fmt.Errorf("load BTF: %w", err) - } - - if handle != nil { - keyTypeID, err := spec.BTF.TypeID(spec.Key) - if err != nil { - return nil, err - } - - valueTypeID, err := spec.BTF.TypeID(spec.Value) - if err != nil { - return nil, err - } - - attr.BtfFd = uint32(handle.FD()) - attr.BtfKeyTypeId = uint32(keyTypeID) - attr.BtfValueTypeId = uint32(valueTypeID) - } - } - - fd, err := sys.MapCreate(&attr) - if err != nil { - if errors.Is(err, unix.EPERM) { - return nil, fmt.Errorf("map create: %w (MEMLOCK may be too low, consider rlimit.RemoveMemlock)", err) - } - if !spec.hasBTF() { - return nil, fmt.Errorf("map create without BTF: %w", err) - } - if errors.Is(err, unix.EINVAL) && attr.MaxEntries == 0 { - return nil, fmt.Errorf("map create: %w (MaxEntries may be incorrectly set to zero)", err) - } - return nil, fmt.Errorf("map create: %w", err) - } - defer closeOnError(fd) - - m, err := newMap(fd, spec.Name, spec.Type, spec.KeySize, spec.ValueSize, spec.MaxEntries, spec.Flags) - if err != nil { - return nil, fmt.Errorf("map create: %w", err) - } - - return m, nil -} - -// newMap allocates and returns a new Map structure. -// Sets the fullValueSize on per-CPU maps. -func newMap(fd *sys.FD, name string, typ MapType, keySize, valueSize, maxEntries, flags uint32) (*Map, error) { - m := &Map{ - name, - fd, - typ, - keySize, - valueSize, - maxEntries, - flags, - "", - int(valueSize), - } - - if !typ.hasPerCPUValue() { - return m, nil - } - - possibleCPUs, err := internal.PossibleCPUs() - if err != nil { - return nil, err - } - - m.fullValueSize = internal.Align(int(valueSize), 8) * possibleCPUs - return m, nil -} - -func (m *Map) String() string { - if m.name != "" { - return fmt.Sprintf("%s(%s)#%v", m.typ, m.name, m.fd) - } - return fmt.Sprintf("%s#%v", m.typ, m.fd) -} - -// Type returns the underlying type of the map. -func (m *Map) Type() MapType { - return m.typ -} - -// KeySize returns the size of the map key in bytes. -func (m *Map) KeySize() uint32 { - return m.keySize -} - -// ValueSize returns the size of the map value in bytes. -func (m *Map) ValueSize() uint32 { - return m.valueSize -} - -// MaxEntries returns the maximum number of elements the map can hold. -func (m *Map) MaxEntries() uint32 { - return m.maxEntries -} - -// Flags returns the flags of the map. -func (m *Map) Flags() uint32 { - return m.flags -} - -// Info returns metadata about the map. -func (m *Map) Info() (*MapInfo, error) { - return newMapInfoFromFd(m.fd) -} - -// MapLookupFlags controls the behaviour of the map lookup calls. -type MapLookupFlags uint64 - -// LookupLock look up the value of a spin-locked map. -const LookupLock MapLookupFlags = 4 - -// Lookup retrieves a value from a Map. -// -// Calls Close() on valueOut if it is of type **Map or **Program, -// and *valueOut is not nil. -// -// Returns an error if the key doesn't exist, see ErrKeyNotExist. -func (m *Map) Lookup(key, valueOut interface{}) error { - valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) - if err := m.lookup(key, valuePtr, 0); err != nil { - return err - } - - return m.unmarshalValue(valueOut, valueBytes) -} - -// LookupWithFlags retrieves a value from a Map with flags. -// -// Passing LookupLock flag will look up the value of a spin-locked -// map without returning the lock. This must be specified if the -// elements contain a spinlock. -// -// Calls Close() on valueOut if it is of type **Map or **Program, -// and *valueOut is not nil. -// -// Returns an error if the key doesn't exist, see ErrKeyNotExist. -func (m *Map) LookupWithFlags(key, valueOut interface{}, flags MapLookupFlags) error { - valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) - if err := m.lookup(key, valuePtr, flags); err != nil { - return err - } - - return m.unmarshalValue(valueOut, valueBytes) -} - -// LookupAndDelete retrieves and deletes a value from a Map. -// -// Returns ErrKeyNotExist if the key doesn't exist. -func (m *Map) LookupAndDelete(key, valueOut interface{}) error { - return m.lookupAndDelete(key, valueOut, 0) -} - -// LookupAndDeleteWithFlags retrieves and deletes a value from a Map. -// -// Passing LookupLock flag will look up and delete the value of a spin-locked -// map without returning the lock. This must be specified if the elements -// contain a spinlock. -// -// Returns ErrKeyNotExist if the key doesn't exist. -func (m *Map) LookupAndDeleteWithFlags(key, valueOut interface{}, flags MapLookupFlags) error { - return m.lookupAndDelete(key, valueOut, flags) -} - -// LookupBytes gets a value from Map. -// -// Returns a nil value if a key doesn't exist. -func (m *Map) LookupBytes(key interface{}) ([]byte, error) { - valueBytes := make([]byte, m.fullValueSize) - valuePtr := sys.NewSlicePointer(valueBytes) - - err := m.lookup(key, valuePtr, 0) - if errors.Is(err, ErrKeyNotExist) { - return nil, nil - } - - return valueBytes, err -} - -func (m *Map) lookup(key interface{}, valueOut sys.Pointer, flags MapLookupFlags) error { - keyPtr, err := m.marshalKey(key) - if err != nil { - return fmt.Errorf("can't marshal key: %w", err) - } - - attr := sys.MapLookupElemAttr{ - MapFd: m.fd.Uint(), - Key: keyPtr, - Value: valueOut, - Flags: uint64(flags), - } - - if err = sys.MapLookupElem(&attr); err != nil { - return fmt.Errorf("lookup: %w", wrapMapError(err)) - } - return nil -} - -func (m *Map) lookupAndDelete(key, valueOut interface{}, flags MapLookupFlags) error { - valuePtr, valueBytes := makeBuffer(valueOut, m.fullValueSize) - - keyPtr, err := m.marshalKey(key) - if err != nil { - return fmt.Errorf("can't marshal key: %w", err) - } - - attr := sys.MapLookupAndDeleteElemAttr{ - MapFd: m.fd.Uint(), - Key: keyPtr, - Value: valuePtr, - Flags: uint64(flags), - } - - if err := sys.MapLookupAndDeleteElem(&attr); err != nil { - return fmt.Errorf("lookup and delete: %w", wrapMapError(err)) - } - - return m.unmarshalValue(valueOut, valueBytes) -} - -// MapUpdateFlags controls the behaviour of the Map.Update call. -// -// The exact semantics depend on the specific MapType. -type MapUpdateFlags uint64 - -const ( - // UpdateAny creates a new element or update an existing one. - UpdateAny MapUpdateFlags = iota - // UpdateNoExist creates a new element. - UpdateNoExist MapUpdateFlags = 1 << (iota - 1) - // UpdateExist updates an existing element. - UpdateExist - // UpdateLock updates elements under bpf_spin_lock. - UpdateLock -) - -// Put replaces or creates a value in map. -// -// It is equivalent to calling Update with UpdateAny. -func (m *Map) Put(key, value interface{}) error { - return m.Update(key, value, UpdateAny) -} - -// Update changes the value of a key. -func (m *Map) Update(key, value interface{}, flags MapUpdateFlags) error { - keyPtr, err := m.marshalKey(key) - if err != nil { - return fmt.Errorf("can't marshal key: %w", err) - } - - valuePtr, err := m.marshalValue(value) - if err != nil { - return fmt.Errorf("can't marshal value: %w", err) - } - - attr := sys.MapUpdateElemAttr{ - MapFd: m.fd.Uint(), - Key: keyPtr, - Value: valuePtr, - Flags: uint64(flags), - } - - if err = sys.MapUpdateElem(&attr); err != nil { - return fmt.Errorf("update: %w", wrapMapError(err)) - } - - return nil -} - -// Delete removes a value. -// -// Returns ErrKeyNotExist if the key does not exist. -func (m *Map) Delete(key interface{}) error { - keyPtr, err := m.marshalKey(key) - if err != nil { - return fmt.Errorf("can't marshal key: %w", err) - } - - attr := sys.MapDeleteElemAttr{ - MapFd: m.fd.Uint(), - Key: keyPtr, - } - - if err = sys.MapDeleteElem(&attr); err != nil { - return fmt.Errorf("delete: %w", wrapMapError(err)) - } - return nil -} - -// NextKey finds the key following an initial key. -// -// See NextKeyBytes for details. -// -// Returns ErrKeyNotExist if there is no next key. -func (m *Map) NextKey(key, nextKeyOut interface{}) error { - nextKeyPtr, nextKeyBytes := makeBuffer(nextKeyOut, int(m.keySize)) - - if err := m.nextKey(key, nextKeyPtr); err != nil { - return err - } - - if err := m.unmarshalKey(nextKeyOut, nextKeyBytes); err != nil { - return fmt.Errorf("can't unmarshal next key: %w", err) - } - return nil -} - -// NextKeyBytes returns the key following an initial key as a byte slice. -// -// Passing nil will return the first key. -// -// Use Iterate if you want to traverse all entries in the map. -// -// Returns nil if there are no more keys. -func (m *Map) NextKeyBytes(key interface{}) ([]byte, error) { - nextKey := make([]byte, m.keySize) - nextKeyPtr := sys.NewSlicePointer(nextKey) - - err := m.nextKey(key, nextKeyPtr) - if errors.Is(err, ErrKeyNotExist) { - return nil, nil - } - - return nextKey, err -} - -func (m *Map) nextKey(key interface{}, nextKeyOut sys.Pointer) error { - var ( - keyPtr sys.Pointer - err error - ) - - if key != nil { - keyPtr, err = m.marshalKey(key) - if err != nil { - return fmt.Errorf("can't marshal key: %w", err) - } - } - - attr := sys.MapGetNextKeyAttr{ - MapFd: m.fd.Uint(), - Key: keyPtr, - NextKey: nextKeyOut, - } - - if err = sys.MapGetNextKey(&attr); err != nil { - // Kernels 4.4.131 and earlier return EFAULT instead of a pointer to the - // first map element when a nil key pointer is specified. - if key == nil && errors.Is(err, unix.EFAULT) { - var guessKey []byte - guessKey, err = m.guessNonExistentKey() - if err != nil { - return err - } - - // Retry the syscall with a valid non-existing key. - attr.Key = sys.NewSlicePointer(guessKey) - if err = sys.MapGetNextKey(&attr); err == nil { - return nil - } - } - - return fmt.Errorf("next key: %w", wrapMapError(err)) - } - - return nil -} - -// guessNonExistentKey attempts to perform a map lookup that returns ENOENT. -// This is necessary on kernels before 4.4.132, since those don't support -// iterating maps from the start by providing an invalid key pointer. -func (m *Map) guessNonExistentKey() ([]byte, error) { - // Provide an invalid value pointer to prevent a copy on the kernel side. - valuePtr := sys.NewPointer(unsafe.Pointer(^uintptr(0))) - randKey := make([]byte, int(m.keySize)) - - for i := 0; i < 4; i++ { - switch i { - // For hash maps, the 0 key is less likely to be occupied. They're often - // used for storing data related to pointers, and their access pattern is - // generally scattered across the keyspace. - case 0: - // An all-0xff key is guaranteed to be out of bounds of any array, since - // those have a fixed key size of 4 bytes. The only corner case being - // arrays with 2^32 max entries, but those are prohibitively expensive - // in many environments. - case 1: - for r := range randKey { - randKey[r] = 0xff - } - // Inspired by BCC, 0x55 is an alternating binary pattern (0101), so - // is unlikely to be taken. - case 2: - for r := range randKey { - randKey[r] = 0x55 - } - // Last ditch effort, generate a random key. - case 3: - rand.New(rand.NewSource(time.Now().UnixNano())).Read(randKey) - } - - err := m.lookup(randKey, valuePtr, 0) - if errors.Is(err, ErrKeyNotExist) { - return randKey, nil - } - } - - return nil, errors.New("couldn't find non-existing key") -} - -// BatchLookup looks up many elements in a map at once. -// -// "keysOut" and "valuesOut" must be of type slice, a pointer -// to a slice or buffer will not work. -// "prevKey" is the key to start the batch lookup from, it will -// *not* be included in the results. Use nil to start at the first key. -// -// ErrKeyNotExist is returned when the batch lookup has reached -// the end of all possible results, even when partial results -// are returned. It should be used to evaluate when lookup is "done". -func (m *Map) BatchLookup(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { - return m.batchLookup(sys.BPF_MAP_LOOKUP_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) -} - -// BatchLookupAndDelete looks up many elements in a map at once, -// -// It then deletes all those elements. -// "keysOut" and "valuesOut" must be of type slice, a pointer -// to a slice or buffer will not work. -// "prevKey" is the key to start the batch lookup from, it will -// *not* be included in the results. Use nil to start at the first key. -// -// ErrKeyNotExist is returned when the batch lookup has reached -// the end of all possible results, even when partial results -// are returned. It should be used to evaluate when lookup is "done". -func (m *Map) BatchLookupAndDelete(prevKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { - return m.batchLookup(sys.BPF_MAP_LOOKUP_AND_DELETE_BATCH, prevKey, nextKeyOut, keysOut, valuesOut, opts) -} - -func (m *Map) batchLookup(cmd sys.Cmd, startKey, nextKeyOut, keysOut, valuesOut interface{}, opts *BatchOptions) (int, error) { - if err := haveBatchAPI(); err != nil { - return 0, err - } - if m.typ.hasPerCPUValue() { - return 0, ErrNotSupported - } - keysValue := reflect.ValueOf(keysOut) - if keysValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("keys must be a slice") - } - valuesValue := reflect.ValueOf(valuesOut) - if valuesValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("valuesOut must be a slice") - } - count := keysValue.Len() - if count != valuesValue.Len() { - return 0, fmt.Errorf("keysOut and valuesOut must be the same length") - } - keyBuf := make([]byte, count*int(m.keySize)) - keyPtr := sys.NewSlicePointer(keyBuf) - valueBuf := make([]byte, count*int(m.fullValueSize)) - valuePtr := sys.NewSlicePointer(valueBuf) - nextPtr, nextBuf := makeBuffer(nextKeyOut, int(m.keySize)) - - attr := sys.MapLookupBatchAttr{ - MapFd: m.fd.Uint(), - Keys: keyPtr, - Values: valuePtr, - Count: uint32(count), - OutBatch: nextPtr, - } - - if opts != nil { - attr.ElemFlags = opts.ElemFlags - attr.Flags = opts.Flags - } - - var err error - if startKey != nil { - attr.InBatch, err = marshalPtr(startKey, int(m.keySize)) - if err != nil { - return 0, err - } - } - - _, sysErr := sys.BPF(cmd, unsafe.Pointer(&attr), unsafe.Sizeof(attr)) - sysErr = wrapMapError(sysErr) - if sysErr != nil && !errors.Is(sysErr, unix.ENOENT) { - return 0, sysErr - } - - err = m.unmarshalKey(nextKeyOut, nextBuf) - if err != nil { - return 0, err - } - err = unmarshalBytes(keysOut, keyBuf) - if err != nil { - return 0, err - } - err = unmarshalBytes(valuesOut, valueBuf) - if err != nil { - return 0, err - } - - return int(attr.Count), sysErr -} - -// BatchUpdate updates the map with multiple keys and values -// simultaneously. -// "keys" and "values" must be of type slice, a pointer -// to a slice or buffer will not work. -func (m *Map) BatchUpdate(keys, values interface{}, opts *BatchOptions) (int, error) { - if err := haveBatchAPI(); err != nil { - return 0, err - } - if m.typ.hasPerCPUValue() { - return 0, ErrNotSupported - } - keysValue := reflect.ValueOf(keys) - if keysValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("keys must be a slice") - } - valuesValue := reflect.ValueOf(values) - if valuesValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("values must be a slice") - } - var ( - count = keysValue.Len() - valuePtr sys.Pointer - err error - ) - if count != valuesValue.Len() { - return 0, fmt.Errorf("keys and values must be the same length") - } - keyPtr, err := marshalPtr(keys, count*int(m.keySize)) - if err != nil { - return 0, err - } - valuePtr, err = marshalPtr(values, count*int(m.valueSize)) - if err != nil { - return 0, err - } - - attr := sys.MapUpdateBatchAttr{ - MapFd: m.fd.Uint(), - Keys: keyPtr, - Values: valuePtr, - Count: uint32(count), - } - if opts != nil { - attr.ElemFlags = opts.ElemFlags - attr.Flags = opts.Flags - } - - err = sys.MapUpdateBatch(&attr) - if err != nil { - return int(attr.Count), fmt.Errorf("batch update: %w", wrapMapError(err)) - } - - return int(attr.Count), nil -} - -// BatchDelete batch deletes entries in the map by keys. -// "keys" must be of type slice, a pointer to a slice or buffer will not work. -func (m *Map) BatchDelete(keys interface{}, opts *BatchOptions) (int, error) { - if err := haveBatchAPI(); err != nil { - return 0, err - } - if m.typ.hasPerCPUValue() { - return 0, ErrNotSupported - } - keysValue := reflect.ValueOf(keys) - if keysValue.Kind() != reflect.Slice { - return 0, fmt.Errorf("keys must be a slice") - } - count := keysValue.Len() - keyPtr, err := marshalPtr(keys, count*int(m.keySize)) - if err != nil { - return 0, fmt.Errorf("cannot marshal keys: %v", err) - } - - attr := sys.MapDeleteBatchAttr{ - MapFd: m.fd.Uint(), - Keys: keyPtr, - Count: uint32(count), - } - - if opts != nil { - attr.ElemFlags = opts.ElemFlags - attr.Flags = opts.Flags - } - - if err = sys.MapDeleteBatch(&attr); err != nil { - return int(attr.Count), fmt.Errorf("batch delete: %w", wrapMapError(err)) - } - - return int(attr.Count), nil -} - -// Iterate traverses a map. -// -// It's safe to create multiple iterators at the same time. -// -// It's not possible to guarantee that all keys in a map will be -// returned if there are concurrent modifications to the map. -func (m *Map) Iterate() *MapIterator { - return newMapIterator(m) -} - -// Close the Map's underlying file descriptor, which could unload the -// Map from the kernel if it is not pinned or in use by a loaded Program. -func (m *Map) Close() error { - if m == nil { - // This makes it easier to clean up when iterating maps - // of maps / programs. - return nil - } - - return m.fd.Close() -} - -// FD gets the file descriptor of the Map. -// -// Calling this function is invalid after Close has been called. -func (m *Map) FD() int { - return m.fd.Int() -} - -// Clone creates a duplicate of the Map. -// -// Closing the duplicate does not affect the original, and vice versa. -// Changes made to the map are reflected by both instances however. -// If the original map was pinned, the cloned map will not be pinned by default. -// -// Cloning a nil Map returns nil. -func (m *Map) Clone() (*Map, error) { - if m == nil { - return nil, nil - } - - dup, err := m.fd.Dup() - if err != nil { - return nil, fmt.Errorf("can't clone map: %w", err) - } - - return &Map{ - m.name, - dup, - m.typ, - m.keySize, - m.valueSize, - m.maxEntries, - m.flags, - "", - m.fullValueSize, - }, nil -} - -// Pin persists the map on the BPF virtual file system past the lifetime of -// the process that created it . -// -// Calling Pin on a previously pinned map will overwrite the path, except when -// the new path already exists. Re-pinning across filesystems is not supported. -// You can Clone a map to pin it to a different path. -// -// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs -func (m *Map) Pin(fileName string) error { - if err := internal.Pin(m.pinnedPath, fileName, m.fd); err != nil { - return err - } - m.pinnedPath = fileName - return nil -} - -// Unpin removes the persisted state for the map from the BPF virtual filesystem. -// -// Failed calls to Unpin will not alter the state returned by IsPinned. -// -// Unpinning an unpinned Map returns nil. -func (m *Map) Unpin() error { - if err := internal.Unpin(m.pinnedPath); err != nil { - return err - } - m.pinnedPath = "" - return nil -} - -// IsPinned returns true if the map has a non-empty pinned path. -func (m *Map) IsPinned() bool { - return m.pinnedPath != "" -} - -// Freeze prevents a map to be modified from user space. -// -// It makes no changes to kernel-side restrictions. -func (m *Map) Freeze() error { - if err := haveMapMutabilityModifiers(); err != nil { - return fmt.Errorf("can't freeze map: %w", err) - } - - attr := sys.MapFreezeAttr{ - MapFd: m.fd.Uint(), - } - - if err := sys.MapFreeze(&attr); err != nil { - return fmt.Errorf("can't freeze map: %w", err) - } - return nil -} - -// finalize populates the Map according to the Contents specified -// in spec and freezes the Map if requested by spec. -func (m *Map) finalize(spec *MapSpec) error { - for _, kv := range spec.Contents { - if err := m.Put(kv.Key, kv.Value); err != nil { - return fmt.Errorf("putting value: key %v: %w", kv.Key, err) - } - } - - if spec.Freeze { - if err := m.Freeze(); err != nil { - return fmt.Errorf("freezing map: %w", err) - } - } - - return nil -} - -func (m *Map) marshalKey(data interface{}) (sys.Pointer, error) { - if data == nil { - if m.keySize == 0 { - // Queues have a key length of zero, so passing nil here is valid. - return sys.NewPointer(nil), nil - } - return sys.Pointer{}, errors.New("can't use nil as key of map") - } - - return marshalPtr(data, int(m.keySize)) -} - -func (m *Map) unmarshalKey(data interface{}, buf []byte) error { - if buf == nil { - // This is from a makeBuffer call, nothing do do here. - return nil - } - - return unmarshalBytes(data, buf) -} - -func (m *Map) marshalValue(data interface{}) (sys.Pointer, error) { - if m.typ.hasPerCPUValue() { - return marshalPerCPUValue(data, int(m.valueSize)) - } - - var ( - buf []byte - err error - ) - - switch value := data.(type) { - case *Map: - if !m.typ.canStoreMap() { - return sys.Pointer{}, fmt.Errorf("can't store map in %s", m.typ) - } - buf, err = marshalMap(value, int(m.valueSize)) - - case *Program: - if !m.typ.canStoreProgram() { - return sys.Pointer{}, fmt.Errorf("can't store program in %s", m.typ) - } - buf, err = marshalProgram(value, int(m.valueSize)) - - default: - return marshalPtr(data, int(m.valueSize)) - } - - if err != nil { - return sys.Pointer{}, err - } - - return sys.NewSlicePointer(buf), nil -} - -func (m *Map) unmarshalValue(value interface{}, buf []byte) error { - if buf == nil { - // This is from a makeBuffer call, nothing do do here. - return nil - } - - if m.typ.hasPerCPUValue() { - return unmarshalPerCPUValue(value, int(m.valueSize), buf) - } - - switch value := value.(type) { - case **Map: - if !m.typ.canStoreMap() { - return fmt.Errorf("can't read a map from %s", m.typ) - } - - other, err := unmarshalMap(buf) - if err != nil { - return err - } - - // The caller might close the map externally, so ignore errors. - _ = (*value).Close() - - *value = other - return nil - - case *Map: - if !m.typ.canStoreMap() { - return fmt.Errorf("can't read a map from %s", m.typ) - } - return errors.New("require pointer to *Map") - - case **Program: - if !m.typ.canStoreProgram() { - return fmt.Errorf("can't read a program from %s", m.typ) - } - - other, err := unmarshalProgram(buf) - if err != nil { - return err - } - - // The caller might close the program externally, so ignore errors. - _ = (*value).Close() - - *value = other - return nil - - case *Program: - if !m.typ.canStoreProgram() { - return fmt.Errorf("can't read a program from %s", m.typ) - } - return errors.New("require pointer to *Program") - } - - return unmarshalBytes(value, buf) -} - -// LoadPinnedMap loads a Map from a BPF file. -func LoadPinnedMap(fileName string, opts *LoadPinOptions) (*Map, error) { - fd, err := sys.ObjGet(&sys.ObjGetAttr{ - Pathname: sys.NewStringPointer(fileName), - FileFlags: opts.Marshal(), - }) - if err != nil { - return nil, err - } - - m, err := newMapFromFD(fd) - if err == nil { - m.pinnedPath = fileName - } - - return m, err -} - -// unmarshalMap creates a map from a map ID encoded in host endianness. -func unmarshalMap(buf []byte) (*Map, error) { - if len(buf) != 4 { - return nil, errors.New("map id requires 4 byte value") - } - - id := internal.NativeEndian.Uint32(buf) - return NewMapFromID(MapID(id)) -} - -// marshalMap marshals the fd of a map into a buffer in host endianness. -func marshalMap(m *Map, length int) ([]byte, error) { - if length != 4 { - return nil, fmt.Errorf("can't marshal map to %d bytes", length) - } - - buf := make([]byte, 4) - internal.NativeEndian.PutUint32(buf, m.fd.Uint()) - return buf, nil -} - -// MapIterator iterates a Map. -// -// See Map.Iterate. -type MapIterator struct { - target *Map - prevKey interface{} - prevBytes []byte - count, maxEntries uint32 - done bool - err error -} - -func newMapIterator(target *Map) *MapIterator { - return &MapIterator{ - target: target, - maxEntries: target.maxEntries, - prevBytes: make([]byte, target.keySize), - } -} - -// Next decodes the next key and value. -// -// Iterating a hash map from which keys are being deleted is not -// safe. You may see the same key multiple times. Iteration may -// also abort with an error, see IsIterationAborted. -// -// Returns false if there are no more entries. You must check -// the result of Err afterwards. -// -// See Map.Get for further caveats around valueOut. -func (mi *MapIterator) Next(keyOut, valueOut interface{}) bool { - if mi.err != nil || mi.done { - return false - } - - // For array-like maps NextKeyBytes returns nil only on after maxEntries - // iterations. - for mi.count <= mi.maxEntries { - var nextBytes []byte - nextBytes, mi.err = mi.target.NextKeyBytes(mi.prevKey) - if mi.err != nil { - return false - } - - if nextBytes == nil { - mi.done = true - return false - } - - // The user can get access to nextBytes since unmarshalBytes - // does not copy when unmarshaling into a []byte. - // Make a copy to prevent accidental corruption of - // iterator state. - copy(mi.prevBytes, nextBytes) - mi.prevKey = mi.prevBytes - - mi.count++ - mi.err = mi.target.Lookup(nextBytes, valueOut) - if errors.Is(mi.err, ErrKeyNotExist) { - // Even though the key should be valid, we couldn't look up - // its value. If we're iterating a hash map this is probably - // because a concurrent delete removed the value before we - // could get it. This means that the next call to NextKeyBytes - // is very likely to restart iteration. - // If we're iterating one of the fd maps like - // ProgramArray it means that a given slot doesn't have - // a valid fd associated. It's OK to continue to the next slot. - continue - } - if mi.err != nil { - return false - } - - mi.err = mi.target.unmarshalKey(keyOut, nextBytes) - return mi.err == nil - } - - mi.err = fmt.Errorf("%w", ErrIterationAborted) - return false -} - -// Err returns any encountered error. -// -// The method must be called after Next returns nil. -// -// Returns ErrIterationAborted if it wasn't possible to do a full iteration. -func (mi *MapIterator) Err() error { - return mi.err -} - -// MapGetNextID returns the ID of the next eBPF map. -// -// Returns ErrNotExist, if there is no next eBPF map. -func MapGetNextID(startID MapID) (MapID, error) { - attr := &sys.MapGetNextIdAttr{Id: uint32(startID)} - return MapID(attr.NextId), sys.MapGetNextId(attr) -} - -// NewMapFromID returns the map for a given id. -// -// Returns ErrNotExist, if there is no eBPF map with the given id. -func NewMapFromID(id MapID) (*Map, error) { - fd, err := sys.MapGetFdById(&sys.MapGetFdByIdAttr{ - Id: uint32(id), - }) - if err != nil { - return nil, err - } - - return newMapFromFD(fd) -} diff --git a/vendor/github.com/cilium/ebpf/marshalers.go b/vendor/github.com/cilium/ebpf/marshalers.go deleted file mode 100644 index 544d17f3..00000000 --- a/vendor/github.com/cilium/ebpf/marshalers.go +++ /dev/null @@ -1,247 +0,0 @@ -package ebpf - -import ( - "bytes" - "encoding" - "encoding/binary" - "errors" - "fmt" - "reflect" - "runtime" - "sync" - "unsafe" - - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" -) - -// marshalPtr converts an arbitrary value into a pointer suitable -// to be passed to the kernel. -// -// As an optimization, it returns the original value if it is an -// unsafe.Pointer. -func marshalPtr(data interface{}, length int) (sys.Pointer, error) { - if ptr, ok := data.(unsafe.Pointer); ok { - return sys.NewPointer(ptr), nil - } - - buf, err := marshalBytes(data, length) - if err != nil { - return sys.Pointer{}, err - } - - return sys.NewSlicePointer(buf), nil -} - -// marshalBytes converts an arbitrary value into a byte buffer. -// -// Prefer using Map.marshalKey and Map.marshalValue if possible, since -// those have special cases that allow more types to be encoded. -// -// Returns an error if the given value isn't representable in exactly -// length bytes. -func marshalBytes(data interface{}, length int) (buf []byte, err error) { - if data == nil { - return nil, errors.New("can't marshal a nil value") - } - - switch value := data.(type) { - case encoding.BinaryMarshaler: - buf, err = value.MarshalBinary() - case string: - buf = []byte(value) - case []byte: - buf = value - case unsafe.Pointer: - err = errors.New("can't marshal from unsafe.Pointer") - case Map, *Map, Program, *Program: - err = fmt.Errorf("can't marshal %T", value) - default: - var wr bytes.Buffer - err = binary.Write(&wr, internal.NativeEndian, value) - if err != nil { - err = fmt.Errorf("encoding %T: %v", value, err) - } - buf = wr.Bytes() - } - if err != nil { - return nil, err - } - - if len(buf) != length { - return nil, fmt.Errorf("%T doesn't marshal to %d bytes", data, length) - } - return buf, nil -} - -func makeBuffer(dst interface{}, length int) (sys.Pointer, []byte) { - if ptr, ok := dst.(unsafe.Pointer); ok { - return sys.NewPointer(ptr), nil - } - - buf := make([]byte, length) - return sys.NewSlicePointer(buf), buf -} - -var bytesReaderPool = sync.Pool{ - New: func() interface{} { - return new(bytes.Reader) - }, -} - -// unmarshalBytes converts a byte buffer into an arbitrary value. -// -// Prefer using Map.unmarshalKey and Map.unmarshalValue if possible, since -// those have special cases that allow more types to be encoded. -// -// The common int32 and int64 types are directly handled to avoid -// unnecessary heap allocations as happening in the default case. -func unmarshalBytes(data interface{}, buf []byte) error { - switch value := data.(type) { - case unsafe.Pointer: - dst := unsafe.Slice((*byte)(value), len(buf)) - copy(dst, buf) - runtime.KeepAlive(value) - return nil - case Map, *Map, Program, *Program: - return fmt.Errorf("can't unmarshal into %T", value) - case encoding.BinaryUnmarshaler: - return value.UnmarshalBinary(buf) - case *string: - *value = string(buf) - return nil - case *[]byte: - *value = buf - return nil - case *int32: - if len(buf) < 4 { - return errors.New("int32 requires 4 bytes") - } - *value = int32(internal.NativeEndian.Uint32(buf)) - return nil - case *uint32: - if len(buf) < 4 { - return errors.New("uint32 requires 4 bytes") - } - *value = internal.NativeEndian.Uint32(buf) - return nil - case *int64: - if len(buf) < 8 { - return errors.New("int64 requires 8 bytes") - } - *value = int64(internal.NativeEndian.Uint64(buf)) - return nil - case *uint64: - if len(buf) < 8 { - return errors.New("uint64 requires 8 bytes") - } - *value = internal.NativeEndian.Uint64(buf) - return nil - case string: - return errors.New("require pointer to string") - case []byte: - return errors.New("require pointer to []byte") - default: - rd := bytesReaderPool.Get().(*bytes.Reader) - rd.Reset(buf) - defer bytesReaderPool.Put(rd) - if err := binary.Read(rd, internal.NativeEndian, value); err != nil { - return fmt.Errorf("decoding %T: %v", value, err) - } - return nil - } -} - -// marshalPerCPUValue encodes a slice containing one value per -// possible CPU into a buffer of bytes. -// -// Values are initialized to zero if the slice has less elements than CPUs. -// -// slice must have a type like []elementType. -func marshalPerCPUValue(slice interface{}, elemLength int) (sys.Pointer, error) { - sliceType := reflect.TypeOf(slice) - if sliceType.Kind() != reflect.Slice { - return sys.Pointer{}, errors.New("per-CPU value requires slice") - } - - possibleCPUs, err := internal.PossibleCPUs() - if err != nil { - return sys.Pointer{}, err - } - - sliceValue := reflect.ValueOf(slice) - sliceLen := sliceValue.Len() - if sliceLen > possibleCPUs { - return sys.Pointer{}, fmt.Errorf("per-CPU value exceeds number of CPUs") - } - - alignedElemLength := internal.Align(elemLength, 8) - buf := make([]byte, alignedElemLength*possibleCPUs) - - for i := 0; i < sliceLen; i++ { - elem := sliceValue.Index(i).Interface() - elemBytes, err := marshalBytes(elem, elemLength) - if err != nil { - return sys.Pointer{}, err - } - - offset := i * alignedElemLength - copy(buf[offset:offset+elemLength], elemBytes) - } - - return sys.NewSlicePointer(buf), nil -} - -// unmarshalPerCPUValue decodes a buffer into a slice containing one value per -// possible CPU. -// -// valueOut must have a type like *[]elementType -func unmarshalPerCPUValue(slicePtr interface{}, elemLength int, buf []byte) error { - slicePtrType := reflect.TypeOf(slicePtr) - if slicePtrType.Kind() != reflect.Ptr || slicePtrType.Elem().Kind() != reflect.Slice { - return fmt.Errorf("per-cpu value requires pointer to slice") - } - - possibleCPUs, err := internal.PossibleCPUs() - if err != nil { - return err - } - - sliceType := slicePtrType.Elem() - slice := reflect.MakeSlice(sliceType, possibleCPUs, possibleCPUs) - - sliceElemType := sliceType.Elem() - sliceElemIsPointer := sliceElemType.Kind() == reflect.Ptr - if sliceElemIsPointer { - sliceElemType = sliceElemType.Elem() - } - - step := len(buf) / possibleCPUs - if step < elemLength { - return fmt.Errorf("per-cpu element length is larger than available data") - } - for i := 0; i < possibleCPUs; i++ { - var elem interface{} - if sliceElemIsPointer { - newElem := reflect.New(sliceElemType) - slice.Index(i).Set(newElem) - elem = newElem.Interface() - } else { - elem = slice.Index(i).Addr().Interface() - } - - // Make a copy, since unmarshal can hold on to itemBytes - elemBytes := make([]byte, elemLength) - copy(elemBytes, buf[:elemLength]) - - err := unmarshalBytes(elem, elemBytes) - if err != nil { - return fmt.Errorf("cpu %d: %w", i, err) - } - - buf = buf[step:] - } - - reflect.ValueOf(slicePtr).Elem().Set(slice) - return nil -} diff --git a/vendor/github.com/cilium/ebpf/prog.go b/vendor/github.com/cilium/ebpf/prog.go deleted file mode 100644 index 675edc71..00000000 --- a/vendor/github.com/cilium/ebpf/prog.go +++ /dev/null @@ -1,875 +0,0 @@ -package ebpf - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "math" - "path/filepath" - "runtime" - "strings" - "time" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/btf" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// ErrNotSupported is returned whenever the kernel doesn't support a feature. -var ErrNotSupported = internal.ErrNotSupported - -// ProgramID represents the unique ID of an eBPF program. -type ProgramID uint32 - -const ( - // Number of bytes to pad the output buffer for BPF_PROG_TEST_RUN. - // This is currently the maximum of spare space allocated for SKB - // and XDP programs, and equal to XDP_PACKET_HEADROOM + NET_IP_ALIGN. - outputPad = 256 + 2 -) - -// DefaultVerifierLogSize is the default number of bytes allocated for the -// verifier log. -const DefaultVerifierLogSize = 64 * 1024 - -// ProgramOptions control loading a program into the kernel. -type ProgramOptions struct { - // Controls the detail emitted by the kernel verifier. Set to non-zero - // to enable logging. - LogLevel uint32 - // Controls the output buffer size for the verifier. Defaults to - // DefaultVerifierLogSize. - LogSize int - // Type information used for CO-RE relocations and when attaching to - // kernel functions. - // - // This is useful in environments where the kernel BTF is not available - // (containers) or where it is in a non-standard location. Defaults to - // use the kernel BTF from a well-known location if nil. - KernelTypes *btf.Spec -} - -// ProgramSpec defines a Program. -type ProgramSpec struct { - // Name is passed to the kernel as a debug aid. Must only contain - // alpha numeric and '_' characters. - Name string - - // Type determines at which hook in the kernel a program will run. - Type ProgramType - - // AttachType of the program, needed to differentiate allowed context - // accesses in some newer program types like CGroupSockAddr. - // - // Available on kernels 4.17 and later. - AttachType AttachType - - // Name of a kernel data structure or function to attach to. Its - // interpretation depends on Type and AttachType. - AttachTo string - - // The program to attach to. Must be provided manually. - AttachTarget *Program - - // The name of the ELF section this program orininated from. - SectionName string - - Instructions asm.Instructions - - // Flags is passed to the kernel and specifies additional program - // load attributes. - Flags uint32 - - // License of the program. Some helpers are only available if - // the license is deemed compatible with the GPL. - // - // See https://www.kernel.org/doc/html/latest/process/license-rules.html#id1 - License string - - // Version used by Kprobe programs. - // - // Deprecated on kernels 5.0 and later. Leave empty to let the library - // detect this value automatically. - KernelVersion uint32 - - // The BTF associated with this program. Changing Instructions - // will most likely invalidate the contained data, and may - // result in errors when attempting to load it into the kernel. - BTF *btf.Spec - - // The byte order this program was compiled for, may be nil. - ByteOrder binary.ByteOrder -} - -// Copy returns a copy of the spec. -func (ps *ProgramSpec) Copy() *ProgramSpec { - if ps == nil { - return nil - } - - cpy := *ps - cpy.Instructions = make(asm.Instructions, len(ps.Instructions)) - copy(cpy.Instructions, ps.Instructions) - return &cpy -} - -// Tag calculates the kernel tag for a series of instructions. -// -// Use asm.Instructions.Tag if you need to calculate for non-native endianness. -func (ps *ProgramSpec) Tag() (string, error) { - return ps.Instructions.Tag(internal.NativeEndian) -} - -type VerifierError = internal.VerifierError - -// Program represents BPF program loaded into the kernel. -// -// It is not safe to close a Program which is used by other goroutines. -type Program struct { - // Contains the output of the kernel verifier if enabled, - // otherwise it is empty. - VerifierLog string - - fd *sys.FD - name string - pinnedPath string - typ ProgramType -} - -// NewProgram creates a new Program. -// -// See NewProgramWithOptions for details. -func NewProgram(spec *ProgramSpec) (*Program, error) { - return NewProgramWithOptions(spec, ProgramOptions{}) -} - -// NewProgramWithOptions creates a new Program. -// -// Loading a program for the first time will perform -// feature detection by loading small, temporary programs. -// -// Returns an error wrapping VerifierError if the program or its BTF is rejected -// by the kernel. -func NewProgramWithOptions(spec *ProgramSpec, opts ProgramOptions) (*Program, error) { - if spec == nil { - return nil, errors.New("can't load a program from a nil spec") - } - - handles := newHandleCache() - defer handles.close() - - prog, err := newProgramWithOptions(spec, opts, handles) - if errors.Is(err, asm.ErrUnsatisfiedMapReference) { - return nil, fmt.Errorf("cannot load program without loading its whole collection: %w", err) - } - return prog, err -} - -func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *handleCache) (*Program, error) { - if len(spec.Instructions) == 0 { - return nil, errors.New("instructions cannot be empty") - } - - if spec.Type == UnspecifiedProgram { - return nil, errors.New("can't load program of unspecified type") - } - - if spec.ByteOrder != nil && spec.ByteOrder != internal.NativeEndian { - return nil, fmt.Errorf("can't load %s program on %s", spec.ByteOrder, internal.NativeEndian) - } - - // Kernels before 5.0 (6c4fc209fcf9 "bpf: remove useless version check for prog load") - // require the version field to be set to the value of the KERNEL_VERSION - // macro for kprobe-type programs. - // Overwrite Kprobe program version if set to zero or the magic version constant. - kv := spec.KernelVersion - if spec.Type == Kprobe && (kv == 0 || kv == internal.MagicKernelVersion) { - v, err := internal.KernelVersion() - if err != nil { - return nil, fmt.Errorf("detecting kernel version: %w", err) - } - kv = v.Kernel() - } - - attr := &sys.ProgLoadAttr{ - ProgType: sys.ProgType(spec.Type), - ProgFlags: spec.Flags, - ExpectedAttachType: sys.AttachType(spec.AttachType), - License: sys.NewStringPointer(spec.License), - KernVersion: kv, - } - - if haveObjName() == nil { - attr.ProgName = sys.NewObjName(spec.Name) - } - - kernelTypes := opts.KernelTypes - - insns := make(asm.Instructions, len(spec.Instructions)) - copy(insns, spec.Instructions) - - var btfDisabled bool - if spec.BTF != nil { - if err := applyRelocations(insns, spec.BTF, kernelTypes); err != nil { - return nil, fmt.Errorf("apply CO-RE relocations: %w", err) - } - - handle, err := handles.btfHandle(spec.BTF) - btfDisabled = errors.Is(err, btf.ErrNotSupported) - if err != nil && !btfDisabled { - return nil, fmt.Errorf("load BTF: %w", err) - } - - if handle != nil { - attr.ProgBtfFd = uint32(handle.FD()) - - fib, lib, err := btf.MarshalExtInfos(insns, spec.BTF.TypeID) - if err != nil { - return nil, err - } - - attr.FuncInfoRecSize = btf.FuncInfoSize - attr.FuncInfoCnt = uint32(len(fib)) / btf.FuncInfoSize - attr.FuncInfo = sys.NewSlicePointer(fib) - - attr.LineInfoRecSize = btf.LineInfoSize - attr.LineInfoCnt = uint32(len(lib)) / btf.LineInfoSize - attr.LineInfo = sys.NewSlicePointer(lib) - } - } - - if err := fixupAndValidate(insns); err != nil { - return nil, err - } - - buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) - err := insns.Marshal(buf, internal.NativeEndian) - if err != nil { - return nil, err - } - - bytecode := buf.Bytes() - attr.Insns = sys.NewSlicePointer(bytecode) - attr.InsnCnt = uint32(len(bytecode) / asm.InstructionSize) - - if spec.AttachTarget != nil { - targetID, err := findTargetInProgram(spec.AttachTarget, spec.AttachTo, spec.Type, spec.AttachType) - if err != nil { - return nil, fmt.Errorf("attach %s/%s: %w", spec.Type, spec.AttachType, err) - } - - attr.AttachBtfId = uint32(targetID) - attr.AttachProgFd = uint32(spec.AttachTarget.FD()) - defer runtime.KeepAlive(spec.AttachTarget) - } else if spec.AttachTo != "" { - targetID, err := findTargetInKernel(kernelTypes, spec.AttachTo, spec.Type, spec.AttachType) - if err != nil && !errors.Is(err, errUnrecognizedAttachType) { - // We ignore errUnrecognizedAttachType since AttachTo may be non-empty - // for programs that don't attach anywhere. - return nil, fmt.Errorf("attach %s/%s: %w", spec.Type, spec.AttachType, err) - } - - attr.AttachBtfId = uint32(targetID) - } - - logSize := DefaultVerifierLogSize - if opts.LogSize > 0 { - logSize = opts.LogSize - } - - var logBuf []byte - if opts.LogLevel > 0 { - logBuf = make([]byte, logSize) - attr.LogLevel = opts.LogLevel - attr.LogSize = uint32(len(logBuf)) - attr.LogBuf = sys.NewSlicePointer(logBuf) - } - - fd, err := sys.ProgLoad(attr) - if err == nil { - return &Program{unix.ByteSliceToString(logBuf), fd, spec.Name, "", spec.Type}, nil - } - - if opts.LogLevel == 0 && opts.LogSize >= 0 { - // Re-run with the verifier enabled to get better error messages. - logBuf = make([]byte, logSize) - attr.LogLevel = 1 - attr.LogSize = uint32(len(logBuf)) - attr.LogBuf = sys.NewSlicePointer(logBuf) - _, _ = sys.ProgLoad(attr) - } - - switch { - case errors.Is(err, unix.EPERM): - if len(logBuf) > 0 && logBuf[0] == 0 { - // EPERM due to RLIMIT_MEMLOCK happens before the verifier, so we can - // check that the log is empty to reduce false positives. - return nil, fmt.Errorf("load program: %w (MEMLOCK may be too low, consider rlimit.RemoveMemlock)", err) - } - - fallthrough - - case errors.Is(err, unix.EINVAL): - if hasFunctionReferences(spec.Instructions) { - if err := haveBPFToBPFCalls(); err != nil { - return nil, fmt.Errorf("load program: %w", err) - } - } - } - - err = internal.ErrorWithLog(err, logBuf) - if btfDisabled { - return nil, fmt.Errorf("load program: %w (BTF disabled)", err) - } - return nil, fmt.Errorf("load program: %w", err) -} - -// NewProgramFromFD creates a program from a raw fd. -// -// You should not use fd after calling this function. -// -// Requires at least Linux 4.10. -func NewProgramFromFD(fd int) (*Program, error) { - f, err := sys.NewFD(fd) - if err != nil { - return nil, err - } - - return newProgramFromFD(f) -} - -// NewProgramFromID returns the program for a given id. -// -// Returns ErrNotExist, if there is no eBPF program with the given id. -func NewProgramFromID(id ProgramID) (*Program, error) { - fd, err := sys.ProgGetFdById(&sys.ProgGetFdByIdAttr{ - Id: uint32(id), - }) - if err != nil { - return nil, fmt.Errorf("get program by id: %w", err) - } - - return newProgramFromFD(fd) -} - -func newProgramFromFD(fd *sys.FD) (*Program, error) { - info, err := newProgramInfoFromFd(fd) - if err != nil { - fd.Close() - return nil, fmt.Errorf("discover program type: %w", err) - } - - return &Program{"", fd, "", "", info.Type}, nil -} - -func (p *Program) String() string { - if p.name != "" { - return fmt.Sprintf("%s(%s)#%v", p.typ, p.name, p.fd) - } - return fmt.Sprintf("%s(%v)", p.typ, p.fd) -} - -// Type returns the underlying type of the program. -func (p *Program) Type() ProgramType { - return p.typ -} - -// Info returns metadata about the program. -// -// Requires at least 4.10. -func (p *Program) Info() (*ProgramInfo, error) { - return newProgramInfoFromFd(p.fd) -} - -// Handle returns a reference to the program's type information in the kernel. -// -// Returns ErrNotSupported if the kernel has no BTF support, or if there is no -// BTF associated with the program. -func (p *Program) Handle() (*btf.Handle, error) { - info, err := p.Info() - if err != nil { - return nil, err - } - - id, ok := info.BTFID() - if !ok { - return nil, fmt.Errorf("program %s: retrieve BTF ID: %w", p, ErrNotSupported) - } - - return btf.NewHandleFromID(id) -} - -// FD gets the file descriptor of the Program. -// -// It is invalid to call this function after Close has been called. -func (p *Program) FD() int { - return p.fd.Int() -} - -// Clone creates a duplicate of the Program. -// -// Closing the duplicate does not affect the original, and vice versa. -// -// Cloning a nil Program returns nil. -func (p *Program) Clone() (*Program, error) { - if p == nil { - return nil, nil - } - - dup, err := p.fd.Dup() - if err != nil { - return nil, fmt.Errorf("can't clone program: %w", err) - } - - return &Program{p.VerifierLog, dup, p.name, "", p.typ}, nil -} - -// Pin persists the Program on the BPF virtual file system past the lifetime of -// the process that created it -// -// Calling Pin on a previously pinned program will overwrite the path, except when -// the new path already exists. Re-pinning across filesystems is not supported. -// -// This requires bpffs to be mounted above fileName. See https://docs.cilium.io/en/k8s-doc/admin/#admin-mount-bpffs -func (p *Program) Pin(fileName string) error { - if err := internal.Pin(p.pinnedPath, fileName, p.fd); err != nil { - return err - } - p.pinnedPath = fileName - return nil -} - -// Unpin removes the persisted state for the Program from the BPF virtual filesystem. -// -// Failed calls to Unpin will not alter the state returned by IsPinned. -// -// Unpinning an unpinned Program returns nil. -func (p *Program) Unpin() error { - if err := internal.Unpin(p.pinnedPath); err != nil { - return err - } - p.pinnedPath = "" - return nil -} - -// IsPinned returns true if the Program has a non-empty pinned path. -func (p *Program) IsPinned() bool { - return p.pinnedPath != "" -} - -// Close the Program's underlying file descriptor, which could unload -// the program from the kernel if it is not pinned or attached to a -// kernel hook. -func (p *Program) Close() error { - if p == nil { - return nil - } - - return p.fd.Close() -} - -// Various options for Run'ing a Program -type RunOptions struct { - // Program's data input. Required field. - Data []byte - // Program's data after Program has run. Caller must allocate. Optional field. - DataOut []byte - // Program's context input. Optional field. - Context interface{} - // Program's context after Program has run. Must be a pointer or slice. Optional field. - ContextOut interface{} - // Number of times to run Program. Optional field. Defaults to 1. - Repeat uint32 - // Optional flags. - Flags uint32 - // CPU to run Program on. Optional field. - // Note not all program types support this field. - CPU uint32 - // Called whenever the syscall is interrupted, and should be set to testing.B.ResetTimer - // or similar. Typically used during benchmarking. Optional field. - Reset func() -} - -// Test runs the Program in the kernel with the given input and returns the -// value returned by the eBPF program. outLen may be zero. -// -// Note: the kernel expects at least 14 bytes input for an ethernet header for -// XDP and SKB programs. -// -// This function requires at least Linux 4.12. -func (p *Program) Test(in []byte) (uint32, []byte, error) { - // Older kernels ignore the dataSizeOut argument when copying to user space. - // Combined with things like bpf_xdp_adjust_head() we don't really know what the final - // size will be. Hence we allocate an output buffer which we hope will always be large - // enough, and panic if the kernel wrote past the end of the allocation. - // See https://patchwork.ozlabs.org/cover/1006822/ - var out []byte - if len(in) > 0 { - out = make([]byte, len(in)+outputPad) - } - - opts := RunOptions{ - Data: in, - DataOut: out, - Repeat: 1, - } - - ret, _, err := p.testRun(&opts) - if err != nil { - return ret, nil, fmt.Errorf("can't test program: %w", err) - } - return ret, opts.DataOut, nil -} - -// Run runs the Program in kernel with given RunOptions. -// -// Note: the same restrictions from Test apply. -func (p *Program) Run(opts *RunOptions) (uint32, error) { - ret, _, err := p.testRun(opts) - if err != nil { - return ret, fmt.Errorf("can't test program: %w", err) - } - return ret, nil -} - -// Benchmark runs the Program with the given input for a number of times -// and returns the time taken per iteration. -// -// Returns the result of the last execution of the program and the time per -// run or an error. reset is called whenever the benchmark syscall is -// interrupted, and should be set to testing.B.ResetTimer or similar. -// -// Note: profiling a call to this function will skew it's results, see -// https://github.com/cilium/ebpf/issues/24 -// -// This function requires at least Linux 4.12. -func (p *Program) Benchmark(in []byte, repeat int, reset func()) (uint32, time.Duration, error) { - if uint(repeat) > math.MaxUint32 { - return 0, 0, fmt.Errorf("repeat is too high") - } - - opts := RunOptions{ - Data: in, - Repeat: uint32(repeat), - Reset: reset, - } - - ret, total, err := p.testRun(&opts) - if err != nil { - return ret, total, fmt.Errorf("can't benchmark program: %w", err) - } - return ret, total, nil -} - -var haveProgTestRun = internal.FeatureTest("BPF_PROG_TEST_RUN", "4.12", func() error { - prog, err := NewProgram(&ProgramSpec{ - // SocketFilter does not require privileges on newer kernels. - Type: SocketFilter, - Instructions: asm.Instructions{ - asm.LoadImm(asm.R0, 0, asm.DWord), - asm.Return(), - }, - License: "MIT", - }) - if err != nil { - // This may be because we lack sufficient permissions, etc. - return err - } - defer prog.Close() - - // Programs require at least 14 bytes input - in := make([]byte, 14) - attr := sys.ProgRunAttr{ - ProgFd: uint32(prog.FD()), - DataSizeIn: uint32(len(in)), - DataIn: sys.NewSlicePointer(in), - } - - err = sys.ProgRun(&attr) - switch { - case errors.Is(err, unix.EINVAL): - // Check for EINVAL specifically, rather than err != nil since we - // otherwise misdetect due to insufficient permissions. - return internal.ErrNotSupported - - case errors.Is(err, unix.EINTR): - // We know that PROG_TEST_RUN is supported if we get EINTR. - return nil - - case errors.Is(err, unix.ENOTSUPP): - // The first PROG_TEST_RUN patches shipped in 4.12 didn't include - // a test runner for SocketFilter. ENOTSUPP means PROG_TEST_RUN is - // supported, but not for the program type used in the probe. - return nil - } - - return err -}) - -func (p *Program) testRun(opts *RunOptions) (uint32, time.Duration, error) { - if uint(len(opts.Data)) > math.MaxUint32 { - return 0, 0, fmt.Errorf("input is too long") - } - - if err := haveProgTestRun(); err != nil { - return 0, 0, err - } - - var ctxBytes []byte - if opts.Context != nil { - ctx := new(bytes.Buffer) - if err := binary.Write(ctx, internal.NativeEndian, opts.Context); err != nil { - return 0, 0, fmt.Errorf("cannot serialize context: %v", err) - } - ctxBytes = ctx.Bytes() - } - - var ctxOut []byte - if opts.ContextOut != nil { - ctxOut = make([]byte, binary.Size(opts.ContextOut)) - } - - attr := sys.ProgRunAttr{ - ProgFd: p.fd.Uint(), - DataSizeIn: uint32(len(opts.Data)), - DataSizeOut: uint32(len(opts.DataOut)), - DataIn: sys.NewSlicePointer(opts.Data), - DataOut: sys.NewSlicePointer(opts.DataOut), - Repeat: uint32(opts.Repeat), - CtxSizeIn: uint32(len(ctxBytes)), - CtxSizeOut: uint32(len(ctxOut)), - CtxIn: sys.NewSlicePointer(ctxBytes), - CtxOut: sys.NewSlicePointer(ctxOut), - Flags: opts.Flags, - Cpu: opts.CPU, - } - - for { - err := sys.ProgRun(&attr) - if err == nil { - break - } - - if errors.Is(err, unix.EINTR) { - if opts.Reset != nil { - opts.Reset() - } - continue - } - - if errors.Is(err, unix.ENOTSUPP) { - return 0, 0, fmt.Errorf("kernel doesn't support testing program type %s: %w", p.Type(), ErrNotSupported) - } - - return 0, 0, fmt.Errorf("can't run test: %w", err) - } - - if opts.DataOut != nil { - if int(attr.DataSizeOut) > cap(opts.DataOut) { - // Houston, we have a problem. The program created more data than we allocated, - // and the kernel wrote past the end of our buffer. - panic("kernel wrote past end of output buffer") - } - opts.DataOut = opts.DataOut[:int(attr.DataSizeOut)] - } - - if len(ctxOut) != 0 { - b := bytes.NewReader(ctxOut) - if err := binary.Read(b, internal.NativeEndian, opts.ContextOut); err != nil { - return 0, 0, fmt.Errorf("failed to decode ContextOut: %v", err) - } - } - - total := time.Duration(attr.Duration) * time.Nanosecond - return attr.Retval, total, nil -} - -func unmarshalProgram(buf []byte) (*Program, error) { - if len(buf) != 4 { - return nil, errors.New("program id requires 4 byte value") - } - - // Looking up an entry in a nested map or prog array returns an id, - // not an fd. - id := internal.NativeEndian.Uint32(buf) - return NewProgramFromID(ProgramID(id)) -} - -func marshalProgram(p *Program, length int) ([]byte, error) { - if length != 4 { - return nil, fmt.Errorf("can't marshal program to %d bytes", length) - } - - buf := make([]byte, 4) - internal.NativeEndian.PutUint32(buf, p.fd.Uint()) - return buf, nil -} - -// LoadPinnedProgram loads a Program from a BPF file. -// -// Requires at least Linux 4.11. -func LoadPinnedProgram(fileName string, opts *LoadPinOptions) (*Program, error) { - fd, err := sys.ObjGet(&sys.ObjGetAttr{ - Pathname: sys.NewStringPointer(fileName), - FileFlags: opts.Marshal(), - }) - if err != nil { - return nil, err - } - - info, err := newProgramInfoFromFd(fd) - if err != nil { - _ = fd.Close() - return nil, fmt.Errorf("info for %s: %w", fileName, err) - } - - return &Program{"", fd, filepath.Base(fileName), fileName, info.Type}, nil -} - -// SanitizeName replaces all invalid characters in name with replacement. -// Passing a negative value for replacement will delete characters instead -// of replacing them. Use this to automatically generate valid names for maps -// and programs at runtime. -// -// The set of allowed characters depends on the running kernel version. -// Dots are only allowed as of kernel 5.2. -func SanitizeName(name string, replacement rune) string { - return strings.Map(func(char rune) rune { - if invalidBPFObjNameChar(char) { - return replacement - } - return char - }, name) -} - -// ProgramGetNextID returns the ID of the next eBPF program. -// -// Returns ErrNotExist, if there is no next eBPF program. -func ProgramGetNextID(startID ProgramID) (ProgramID, error) { - attr := &sys.ProgGetNextIdAttr{Id: uint32(startID)} - return ProgramID(attr.NextId), sys.ProgGetNextId(attr) -} - -// BindMap binds map to the program and is only released once program is released. -// -// This may be used in cases where metadata should be associated with the program -// which otherwise does not contain any references to the map. -func (p *Program) BindMap(m *Map) error { - attr := &sys.ProgBindMapAttr{ - ProgFd: uint32(p.FD()), - MapFd: uint32(m.FD()), - } - - return sys.ProgBindMap(attr) -} - -var errUnrecognizedAttachType = errors.New("unrecognized attach type") - -// find an attach target type in the kernel. -// -// spec may be nil and defaults to the canonical kernel BTF. name together with -// progType and attachType determine which type we need to attach to. -// -// Returns errUnrecognizedAttachType. -func findTargetInKernel(spec *btf.Spec, name string, progType ProgramType, attachType AttachType) (btf.TypeID, error) { - type match struct { - p ProgramType - a AttachType - } - - var ( - typeName, featureName string - isBTFTypeFunc = true - ) - - switch (match{progType, attachType}) { - case match{LSM, AttachLSMMac}: - typeName = "bpf_lsm_" + name - featureName = name + " LSM hook" - case match{Tracing, AttachTraceIter}: - typeName = "bpf_iter_" + name - featureName = name + " iterator" - case match{Tracing, AttachTraceFEntry}: - typeName = name - featureName = fmt.Sprintf("fentry %s", name) - case match{Tracing, AttachTraceFExit}: - typeName = name - featureName = fmt.Sprintf("fexit %s", name) - case match{Tracing, AttachModifyReturn}: - typeName = name - featureName = fmt.Sprintf("fmod_ret %s", name) - case match{Tracing, AttachTraceRawTp}: - typeName = fmt.Sprintf("btf_trace_%s", name) - featureName = fmt.Sprintf("raw_tp %s", name) - isBTFTypeFunc = false - default: - return 0, errUnrecognizedAttachType - } - - spec, err := maybeLoadKernelBTF(spec) - if err != nil { - return 0, fmt.Errorf("load kernel spec: %w", err) - } - - var target btf.Type - if isBTFTypeFunc { - var targetFunc *btf.Func - err = spec.TypeByName(typeName, &targetFunc) - target = targetFunc - } else { - var targetTypedef *btf.Typedef - err = spec.TypeByName(typeName, &targetTypedef) - target = targetTypedef - } - - if err != nil { - if errors.Is(err, btf.ErrNotFound) { - return 0, &internal.UnsupportedFeatureError{ - Name: featureName, - } - } - return 0, fmt.Errorf("find target for %s: %w", featureName, err) - } - - return spec.TypeID(target) -} - -// find an attach target type in a program. -// -// Returns errUnrecognizedAttachType. -func findTargetInProgram(prog *Program, name string, progType ProgramType, attachType AttachType) (btf.TypeID, error) { - type match struct { - p ProgramType - a AttachType - } - - var typeName string - switch (match{progType, attachType}) { - case match{Extension, AttachNone}: - typeName = name - default: - return 0, errUnrecognizedAttachType - } - - btfHandle, err := prog.Handle() - if err != nil { - return 0, fmt.Errorf("load target BTF: %w", err) - } - defer btfHandle.Close() - - spec, err := btfHandle.Spec(nil) - if err != nil { - return 0, err - } - - var targetFunc *btf.Func - err = spec.TypeByName(typeName, &targetFunc) - if err != nil { - return 0, fmt.Errorf("find target %s: %w", typeName, err) - } - - return spec.TypeID(targetFunc) -} diff --git a/vendor/github.com/cilium/ebpf/run-tests.sh b/vendor/github.com/cilium/ebpf/run-tests.sh deleted file mode 100644 index c21cca9e..00000000 --- a/vendor/github.com/cilium/ebpf/run-tests.sh +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env bash -# Test the current package under a different kernel. -# Requires virtme and qemu to be installed. -# Examples: -# Run all tests on a 5.4 kernel -# $ ./run-tests.sh 5.4 -# Run a subset of tests: -# $ ./run-tests.sh 5.4 ./link - -set -euo pipefail - -script="$(realpath "$0")" -readonly script - -# This script is a bit like a Matryoshka doll since it keeps re-executing itself -# in various different contexts: -# -# 1. invoked by the user like run-tests.sh 5.4 -# 2. invoked by go test like run-tests.sh --exec-vm -# 3. invoked by init in the vm like run-tests.sh --exec-test -# -# This allows us to use all available CPU on the host machine to compile our -# code, and then only use the VM to execute the test. This is because the VM -# is usually slower at compiling than the host. -if [[ "${1:-}" = "--exec-vm" ]]; then - shift - - input="$1" - shift - - # Use sudo if /dev/kvm isn't accessible by the current user. - sudo="" - if [[ ! -r /dev/kvm || ! -w /dev/kvm ]]; then - sudo="sudo" - fi - readonly sudo - - testdir="$(dirname "$1")" - output="$(mktemp -d)" - printf -v cmd "%q " "$@" - - if [[ "$(stat -c '%t:%T' -L /proc/$$/fd/0)" == "1:3" ]]; then - # stdin is /dev/null, which doesn't play well with qemu. Use a fifo as a - # blocking substitute. - mkfifo "${output}/fake-stdin" - # Open for reading and writing to avoid blocking. - exec 0<> "${output}/fake-stdin" - rm "${output}/fake-stdin" - fi - - for ((i = 0; i < 3; i++)); do - if ! $sudo virtme-run --kimg "${input}/bzImage" --memory 768M --pwd \ - --rwdir="${testdir}=${testdir}" \ - --rodir=/run/input="${input}" \ - --rwdir=/run/output="${output}" \ - --script-sh "PATH=\"$PATH\" CI_MAX_KERNEL_VERSION="${CI_MAX_KERNEL_VERSION:-}" \"$script\" --exec-test $cmd" \ - --kopt possible_cpus=2; then # need at least two CPUs for some tests - exit 23 - fi - - if [[ -e "${output}/status" ]]; then - break - fi - - if [[ -v CI ]]; then - echo "Retrying test run due to qemu crash" - continue - fi - - exit 42 - done - - rc=$(<"${output}/status") - $sudo rm -r "$output" - exit $rc -elif [[ "${1:-}" = "--exec-test" ]]; then - shift - - mount -t bpf bpf /sys/fs/bpf - mount -t tracefs tracefs /sys/kernel/debug/tracing - - if [[ -d "/run/input/bpf" ]]; then - export KERNEL_SELFTESTS="/run/input/bpf" - fi - - if [[ -f "/run/input/bpf/bpf_testmod/bpf_testmod.ko" ]]; then - insmod "/run/input/bpf/bpf_testmod/bpf_testmod.ko" - fi - - dmesg --clear - rc=0 - "$@" || rc=$? - dmesg - echo $rc > "/run/output/status" - exit $rc # this return code is "swallowed" by qemu -fi - -readonly kernel_version="${1:-}" -if [[ -z "${kernel_version}" ]]; then - echo "Expecting kernel version as first argument" - exit 1 -fi -shift - -readonly kernel="linux-${kernel_version}.bz" -readonly selftests="linux-${kernel_version}-selftests-bpf.tgz" -readonly input="$(mktemp -d)" -readonly tmp_dir="${TMPDIR:-/tmp}" -readonly branch="${BRANCH:-master}" - -fetch() { - echo Fetching "${1}" - pushd "${tmp_dir}" > /dev/null - curl -s -L -O --fail --etag-compare "${1}.etag" --etag-save "${1}.etag" "https://github.com/cilium/ci-kernels/raw/${branch}/${1}" - local ret=$? - popd > /dev/null - return $ret -} - -fetch "${kernel}" -cp "${tmp_dir}/${kernel}" "${input}/bzImage" - -if fetch "${selftests}"; then - echo "Decompressing selftests" - mkdir "${input}/bpf" - tar --strip-components=4 -xf "${tmp_dir}/${selftests}" -C "${input}/bpf" -else - echo "No selftests found, disabling" -fi - -args=(-short -coverpkg=./... -coverprofile=coverage.out -count 1 ./...) -if (( $# > 0 )); then - args=("$@") -fi - -export GOFLAGS=-mod=readonly -export CGO_ENABLED=0 -# LINUX_VERSION_CODE test compares this to discovered value. -export KERNEL_VERSION="${kernel_version}" - -echo Testing on "${kernel_version}" -go test -exec "$script --exec-vm $input" "${args[@]}" -echo "Test successful on ${kernel_version}" - -rm -r "${input}" diff --git a/vendor/github.com/cilium/ebpf/syscalls.go b/vendor/github.com/cilium/ebpf/syscalls.go deleted file mode 100644 index e5c270a5..00000000 --- a/vendor/github.com/cilium/ebpf/syscalls.go +++ /dev/null @@ -1,264 +0,0 @@ -package ebpf - -import ( - "bytes" - "errors" - "fmt" - - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/internal" - "github.com/cilium/ebpf/internal/sys" - "github.com/cilium/ebpf/internal/unix" -) - -// invalidBPFObjNameChar returns true if char may not appear in -// a BPF object name. -func invalidBPFObjNameChar(char rune) bool { - dotAllowed := objNameAllowsDot() == nil - - switch { - case char >= 'A' && char <= 'Z': - return false - case char >= 'a' && char <= 'z': - return false - case char >= '0' && char <= '9': - return false - case dotAllowed && char == '.': - return false - case char == '_': - return false - default: - return true - } -} - -func progLoad(insns asm.Instructions, typ ProgramType, license string) (*sys.FD, error) { - buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) - if err := insns.Marshal(buf, internal.NativeEndian); err != nil { - return nil, err - } - bytecode := buf.Bytes() - - return sys.ProgLoad(&sys.ProgLoadAttr{ - ProgType: sys.ProgType(typ), - License: sys.NewStringPointer(license), - Insns: sys.NewSlicePointer(bytecode), - InsnCnt: uint32(len(bytecode) / asm.InstructionSize), - }) -} - -var haveNestedMaps = internal.FeatureTest("nested maps", "4.12", func() error { - _, err := sys.MapCreate(&sys.MapCreateAttr{ - MapType: sys.MapType(ArrayOfMaps), - KeySize: 4, - ValueSize: 4, - MaxEntries: 1, - // Invalid file descriptor. - InnerMapFd: ^uint32(0), - }) - if errors.Is(err, unix.EINVAL) { - return internal.ErrNotSupported - } - if errors.Is(err, unix.EBADF) { - return nil - } - return err -}) - -var haveMapMutabilityModifiers = internal.FeatureTest("read- and write-only maps", "5.2", func() error { - // This checks BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG. Since - // BPF_MAP_FREEZE appeared in 5.2 as well we don't do a separate check. - m, err := sys.MapCreate(&sys.MapCreateAttr{ - MapType: sys.MapType(Array), - KeySize: 4, - ValueSize: 4, - MaxEntries: 1, - MapFlags: unix.BPF_F_RDONLY_PROG, - }) - if err != nil { - return internal.ErrNotSupported - } - _ = m.Close() - return nil -}) - -var haveMmapableMaps = internal.FeatureTest("mmapable maps", "5.5", func() error { - // This checks BPF_F_MMAPABLE, which appeared in 5.5 for array maps. - m, err := sys.MapCreate(&sys.MapCreateAttr{ - MapType: sys.MapType(Array), - KeySize: 4, - ValueSize: 4, - MaxEntries: 1, - MapFlags: unix.BPF_F_MMAPABLE, - }) - if err != nil { - return internal.ErrNotSupported - } - _ = m.Close() - return nil -}) - -var haveInnerMaps = internal.FeatureTest("inner maps", "5.10", func() error { - // This checks BPF_F_INNER_MAP, which appeared in 5.10. - m, err := sys.MapCreate(&sys.MapCreateAttr{ - MapType: sys.MapType(Array), - KeySize: 4, - ValueSize: 4, - MaxEntries: 1, - MapFlags: unix.BPF_F_INNER_MAP, - }) - if err != nil { - return internal.ErrNotSupported - } - _ = m.Close() - return nil -}) - -var haveNoPreallocMaps = internal.FeatureTest("prealloc maps", "4.6", func() error { - // This checks BPF_F_NO_PREALLOC, which appeared in 4.6. - m, err := sys.MapCreate(&sys.MapCreateAttr{ - MapType: sys.MapType(Hash), - KeySize: 4, - ValueSize: 4, - MaxEntries: 1, - MapFlags: unix.BPF_F_NO_PREALLOC, - }) - if err != nil { - return internal.ErrNotSupported - } - _ = m.Close() - return nil -}) - -func wrapMapError(err error) error { - if err == nil { - return nil - } - - if errors.Is(err, unix.ENOENT) { - return sys.Error(ErrKeyNotExist, unix.ENOENT) - } - - if errors.Is(err, unix.EEXIST) { - return sys.Error(ErrKeyExist, unix.EEXIST) - } - - if errors.Is(err, unix.ENOTSUPP) { - return sys.Error(ErrNotSupported, unix.ENOTSUPP) - } - - if errors.Is(err, unix.E2BIG) { - return fmt.Errorf("key too big for map: %w", err) - } - - return err -} - -var haveObjName = internal.FeatureTest("object names", "4.15", func() error { - attr := sys.MapCreateAttr{ - MapType: sys.MapType(Array), - KeySize: 4, - ValueSize: 4, - MaxEntries: 1, - MapName: sys.NewObjName("feature_test"), - } - - fd, err := sys.MapCreate(&attr) - if err != nil { - return internal.ErrNotSupported - } - - _ = fd.Close() - return nil -}) - -var objNameAllowsDot = internal.FeatureTest("dot in object names", "5.2", func() error { - if err := haveObjName(); err != nil { - return err - } - - attr := sys.MapCreateAttr{ - MapType: sys.MapType(Array), - KeySize: 4, - ValueSize: 4, - MaxEntries: 1, - MapName: sys.NewObjName(".test"), - } - - fd, err := sys.MapCreate(&attr) - if err != nil { - return internal.ErrNotSupported - } - - _ = fd.Close() - return nil -}) - -var haveBatchAPI = internal.FeatureTest("map batch api", "5.6", func() error { - var maxEntries uint32 = 2 - attr := sys.MapCreateAttr{ - MapType: sys.MapType(Hash), - KeySize: 4, - ValueSize: 4, - MaxEntries: maxEntries, - } - - fd, err := sys.MapCreate(&attr) - if err != nil { - return internal.ErrNotSupported - } - defer fd.Close() - - keys := []uint32{1, 2} - values := []uint32{3, 4} - kp, _ := marshalPtr(keys, 8) - vp, _ := marshalPtr(values, 8) - - err = sys.MapUpdateBatch(&sys.MapUpdateBatchAttr{ - MapFd: fd.Uint(), - Keys: kp, - Values: vp, - Count: maxEntries, - }) - if err != nil { - return internal.ErrNotSupported - } - return nil -}) - -var haveProbeReadKernel = internal.FeatureTest("bpf_probe_read_kernel", "5.5", func() error { - insns := asm.Instructions{ - asm.Mov.Reg(asm.R1, asm.R10), - asm.Add.Imm(asm.R1, -8), - asm.Mov.Imm(asm.R2, 8), - asm.Mov.Imm(asm.R3, 0), - asm.FnProbeReadKernel.Call(), - asm.Return(), - } - - fd, err := progLoad(insns, Kprobe, "GPL") - if err != nil { - return internal.ErrNotSupported - } - _ = fd.Close() - return nil -}) - -var haveBPFToBPFCalls = internal.FeatureTest("bpf2bpf calls", "4.16", func() error { - insns := asm.Instructions{ - asm.Call.Label("prog2").WithSymbol("prog1"), - asm.Return(), - asm.Mov.Imm(asm.R0, 0).WithSymbol("prog2"), - asm.Return(), - } - - fd, err := progLoad(insns, SocketFilter, "MIT") - if errors.Is(err, unix.EINVAL) { - return internal.ErrNotSupported - } - if err != nil { - return err - } - _ = fd.Close() - return nil -}) diff --git a/vendor/github.com/cilium/ebpf/types.go b/vendor/github.com/cilium/ebpf/types.go deleted file mode 100644 index a27b4424..00000000 --- a/vendor/github.com/cilium/ebpf/types.go +++ /dev/null @@ -1,284 +0,0 @@ -package ebpf - -import ( - "github.com/cilium/ebpf/internal/unix" -) - -//go:generate stringer -output types_string.go -type=MapType,ProgramType,PinType - -// MapType indicates the type map structure -// that will be initialized in the kernel. -type MapType uint32 - -// Max returns the latest supported MapType. -func (MapType) Max() MapType { - return maxMapType - 1 -} - -// All the various map types that can be created -const ( - UnspecifiedMap MapType = iota - // Hash is a hash map - Hash - // Array is an array map - Array - // ProgramArray - A program array map is a special kind of array map whose map - // values contain only file descriptors referring to other eBPF - // programs. Thus, both the key_size and value_size must be - // exactly four bytes. This map is used in conjunction with the - // TailCall helper. - ProgramArray - // PerfEventArray - A perf event array is used in conjunction with PerfEventRead - // and PerfEventOutput calls, to read the raw bpf_perf_data from the registers. - PerfEventArray - // PerCPUHash - This data structure is useful for people who have high performance - // network needs and can reconcile adds at the end of some cycle, so that - // hashes can be lock free without the use of XAdd, which can be costly. - PerCPUHash - // PerCPUArray - This data structure is useful for people who have high performance - // network needs and can reconcile adds at the end of some cycle, so that - // hashes can be lock free without the use of XAdd, which can be costly. - // Each CPU gets a copy of this hash, the contents of all of which can be reconciled - // later. - PerCPUArray - // StackTrace - This holds whole user and kernel stack traces, it can be retrieved with - // GetStackID - StackTrace - // CGroupArray - This is a very niche structure used to help SKBInCGroup determine - // if an skb is from a socket belonging to a specific cgroup - CGroupArray - // LRUHash - This allows you to create a small hash structure that will purge the - // least recently used items rather than thow an error when you run out of memory - LRUHash - // LRUCPUHash - This is NOT like PerCPUHash, this structure is shared among the CPUs, - // it has more to do with including the CPU id with the LRU calculation so that if a - // particular CPU is using a value over-and-over again, then it will be saved, but if - // a value is being retrieved a lot but sparsely across CPUs it is not as important, basically - // giving weight to CPU locality over overall usage. - LRUCPUHash - // LPMTrie - This is an implementation of Longest-Prefix-Match Trie structure. It is useful, - // for storing things like IP addresses which can be bit masked allowing for keys of differing - // values to refer to the same reference based on their masks. See wikipedia for more details. - LPMTrie - // ArrayOfMaps - Each item in the array is another map. The inner map mustn't be a map of maps - // itself. - ArrayOfMaps - // HashOfMaps - Each item in the hash map is another map. The inner map mustn't be a map of maps - // itself. - HashOfMaps - // DevMap - Specialized map to store references to network devices. - DevMap - // SockMap - Specialized map to store references to sockets. - SockMap - // CPUMap - Specialized map to store references to CPUs. - CPUMap - // XSKMap - Specialized map for XDP programs to store references to open sockets. - XSKMap - // SockHash - Specialized hash to store references to sockets. - SockHash - // CGroupStorage - Special map for CGroups. - CGroupStorage - // ReusePortSockArray - Specialized map to store references to sockets that can be reused. - ReusePortSockArray - // PerCPUCGroupStorage - Special per CPU map for CGroups. - PerCPUCGroupStorage - // Queue - FIFO storage for BPF programs. - Queue - // Stack - LIFO storage for BPF programs. - Stack - // SkStorage - Specialized map for local storage at SK for BPF programs. - SkStorage - // DevMapHash - Hash-based indexing scheme for references to network devices. - DevMapHash - // StructOpsMap - This map holds a kernel struct with its function pointer implemented in a BPF - // program. - StructOpsMap - // RingBuf - Similar to PerfEventArray, but shared across all CPUs. - RingBuf - // InodeStorage - Specialized local storage map for inodes. - InodeStorage - // TaskStorage - Specialized local storage map for task_struct. - TaskStorage - // maxMapType - Bound enum of MapTypes, has to be last in enum. - maxMapType -) - -// hasPerCPUValue returns true if the Map stores a value per CPU. -func (mt MapType) hasPerCPUValue() bool { - return mt == PerCPUHash || mt == PerCPUArray || mt == LRUCPUHash || mt == PerCPUCGroupStorage -} - -// canStoreMap returns true if the map type accepts a map fd -// for update and returns a map id for lookup. -func (mt MapType) canStoreMap() bool { - return mt == ArrayOfMaps || mt == HashOfMaps -} - -// canStoreProgram returns true if the map type accepts a program fd -// for update and returns a program id for lookup. -func (mt MapType) canStoreProgram() bool { - return mt == ProgramArray -} - -// hasBTF returns true if the map type supports BTF key/value metadata. -func (mt MapType) hasBTF() bool { - switch mt { - case PerfEventArray, CGroupArray, StackTrace, ArrayOfMaps, HashOfMaps, DevMap, - DevMapHash, CPUMap, XSKMap, SockMap, SockHash, Queue, Stack, RingBuf: - return false - default: - return true - } -} - -// ProgramType of the eBPF program -type ProgramType uint32 - -// Max return the latest supported ProgramType. -func (ProgramType) Max() ProgramType { - return maxProgramType - 1 -} - -// eBPF program types -const ( - UnspecifiedProgram ProgramType = iota - SocketFilter - Kprobe - SchedCLS - SchedACT - TracePoint - XDP - PerfEvent - CGroupSKB - CGroupSock - LWTIn - LWTOut - LWTXmit - SockOps - SkSKB - CGroupDevice - SkMsg - RawTracepoint - CGroupSockAddr - LWTSeg6Local - LircMode2 - SkReuseport - FlowDissector - CGroupSysctl - RawTracepointWritable - CGroupSockopt - Tracing - StructOps - Extension - LSM - SkLookup - Syscall - maxProgramType -) - -// AttachType of the eBPF program, needed to differentiate allowed context accesses in -// some newer program types like CGroupSockAddr. Should be set to AttachNone if not required. -// Will cause invalid argument (EINVAL) at program load time if set incorrectly. -type AttachType uint32 - -//go:generate stringer -type AttachType -trimprefix Attach - -// AttachNone is an alias for AttachCGroupInetIngress for readability reasons. -const AttachNone AttachType = 0 - -const ( - AttachCGroupInetIngress AttachType = iota - AttachCGroupInetEgress - AttachCGroupInetSockCreate - AttachCGroupSockOps - AttachSkSKBStreamParser - AttachSkSKBStreamVerdict - AttachCGroupDevice - AttachSkMsgVerdict - AttachCGroupInet4Bind - AttachCGroupInet6Bind - AttachCGroupInet4Connect - AttachCGroupInet6Connect - AttachCGroupInet4PostBind - AttachCGroupInet6PostBind - AttachCGroupUDP4Sendmsg - AttachCGroupUDP6Sendmsg - AttachLircMode2 - AttachFlowDissector - AttachCGroupSysctl - AttachCGroupUDP4Recvmsg - AttachCGroupUDP6Recvmsg - AttachCGroupGetsockopt - AttachCGroupSetsockopt - AttachTraceRawTp - AttachTraceFEntry - AttachTraceFExit - AttachModifyReturn - AttachLSMMac - AttachTraceIter - AttachCgroupInet4GetPeername - AttachCgroupInet6GetPeername - AttachCgroupInet4GetSockname - AttachCgroupInet6GetSockname - AttachXDPDevMap - AttachCgroupInetSockRelease - AttachXDPCPUMap - AttachSkLookup - AttachXDP - AttachSkSKBVerdict - AttachSkReuseportSelect - AttachSkReuseportSelectOrMigrate - AttachPerfEvent -) - -// AttachFlags of the eBPF program used in BPF_PROG_ATTACH command -type AttachFlags uint32 - -// PinType determines whether a map is pinned into a BPFFS. -type PinType int - -// Valid pin types. -// -// Mirrors enum libbpf_pin_type. -const ( - PinNone PinType = iota - // Pin an object by using its name as the filename. - PinByName -) - -// LoadPinOptions control how a pinned object is loaded. -type LoadPinOptions struct { - // Request a read-only or write-only object. The default is a read-write - // object. Only one of the flags may be set. - ReadOnly bool - WriteOnly bool - - // Raw flags for the syscall. Other fields of this struct take precedence. - Flags uint32 -} - -// Marshal returns a value suitable for BPF_OBJ_GET syscall file_flags parameter. -func (lpo *LoadPinOptions) Marshal() uint32 { - if lpo == nil { - return 0 - } - - flags := lpo.Flags - if lpo.ReadOnly { - flags |= unix.BPF_F_RDONLY - } - if lpo.WriteOnly { - flags |= unix.BPF_F_WRONLY - } - return flags -} - -// BatchOptions batch map operations options -// -// Mirrors libbpf struct bpf_map_batch_opts -// Currently BPF_F_FLAG is the only supported -// flag (for ElemFlags). -type BatchOptions struct { - ElemFlags uint64 - Flags uint64 -} diff --git a/vendor/github.com/cilium/ebpf/types_string.go b/vendor/github.com/cilium/ebpf/types_string.go deleted file mode 100644 index e80b948b..00000000 --- a/vendor/github.com/cilium/ebpf/types_string.go +++ /dev/null @@ -1,120 +0,0 @@ -// Code generated by "stringer -output types_string.go -type=MapType,ProgramType,PinType"; DO NOT EDIT. - -package ebpf - -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[UnspecifiedMap-0] - _ = x[Hash-1] - _ = x[Array-2] - _ = x[ProgramArray-3] - _ = x[PerfEventArray-4] - _ = x[PerCPUHash-5] - _ = x[PerCPUArray-6] - _ = x[StackTrace-7] - _ = x[CGroupArray-8] - _ = x[LRUHash-9] - _ = x[LRUCPUHash-10] - _ = x[LPMTrie-11] - _ = x[ArrayOfMaps-12] - _ = x[HashOfMaps-13] - _ = x[DevMap-14] - _ = x[SockMap-15] - _ = x[CPUMap-16] - _ = x[XSKMap-17] - _ = x[SockHash-18] - _ = x[CGroupStorage-19] - _ = x[ReusePortSockArray-20] - _ = x[PerCPUCGroupStorage-21] - _ = x[Queue-22] - _ = x[Stack-23] - _ = x[SkStorage-24] - _ = x[DevMapHash-25] - _ = x[StructOpsMap-26] - _ = x[RingBuf-27] - _ = x[InodeStorage-28] - _ = x[TaskStorage-29] - _ = x[maxMapType-30] -} - -const _MapType_name = "UnspecifiedMapHashArrayProgramArrayPerfEventArrayPerCPUHashPerCPUArrayStackTraceCGroupArrayLRUHashLRUCPUHashLPMTrieArrayOfMapsHashOfMapsDevMapSockMapCPUMapXSKMapSockHashCGroupStorageReusePortSockArrayPerCPUCGroupStorageQueueStackSkStorageDevMapHashStructOpsMapRingBufInodeStorageTaskStoragemaxMapType" - -var _MapType_index = [...]uint16{0, 14, 18, 23, 35, 49, 59, 70, 80, 91, 98, 108, 115, 126, 136, 142, 149, 155, 161, 169, 182, 200, 219, 224, 229, 238, 248, 260, 267, 279, 290, 300} - -func (i MapType) String() string { - if i >= MapType(len(_MapType_index)-1) { - return "MapType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _MapType_name[_MapType_index[i]:_MapType_index[i+1]] -} -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[UnspecifiedProgram-0] - _ = x[SocketFilter-1] - _ = x[Kprobe-2] - _ = x[SchedCLS-3] - _ = x[SchedACT-4] - _ = x[TracePoint-5] - _ = x[XDP-6] - _ = x[PerfEvent-7] - _ = x[CGroupSKB-8] - _ = x[CGroupSock-9] - _ = x[LWTIn-10] - _ = x[LWTOut-11] - _ = x[LWTXmit-12] - _ = x[SockOps-13] - _ = x[SkSKB-14] - _ = x[CGroupDevice-15] - _ = x[SkMsg-16] - _ = x[RawTracepoint-17] - _ = x[CGroupSockAddr-18] - _ = x[LWTSeg6Local-19] - _ = x[LircMode2-20] - _ = x[SkReuseport-21] - _ = x[FlowDissector-22] - _ = x[CGroupSysctl-23] - _ = x[RawTracepointWritable-24] - _ = x[CGroupSockopt-25] - _ = x[Tracing-26] - _ = x[StructOps-27] - _ = x[Extension-28] - _ = x[LSM-29] - _ = x[SkLookup-30] - _ = x[Syscall-31] - _ = x[maxProgramType-32] -} - -const _ProgramType_name = "UnspecifiedProgramSocketFilterKprobeSchedCLSSchedACTTracePointXDPPerfEventCGroupSKBCGroupSockLWTInLWTOutLWTXmitSockOpsSkSKBCGroupDeviceSkMsgRawTracepointCGroupSockAddrLWTSeg6LocalLircMode2SkReuseportFlowDissectorCGroupSysctlRawTracepointWritableCGroupSockoptTracingStructOpsExtensionLSMSkLookupSyscallmaxProgramType" - -var _ProgramType_index = [...]uint16{0, 18, 30, 36, 44, 52, 62, 65, 74, 83, 93, 98, 104, 111, 118, 123, 135, 140, 153, 167, 179, 188, 199, 212, 224, 245, 258, 265, 274, 283, 286, 294, 301, 315} - -func (i ProgramType) String() string { - if i >= ProgramType(len(_ProgramType_index)-1) { - return "ProgramType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _ProgramType_name[_ProgramType_index[i]:_ProgramType_index[i+1]] -} -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[PinNone-0] - _ = x[PinByName-1] -} - -const _PinType_name = "PinNonePinByName" - -var _PinType_index = [...]uint8{0, 7, 16} - -func (i PinType) String() string { - if i < 0 || i >= PinType(len(_PinType_index)-1) { - return "PinType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _PinType_name[_PinType_index[i]:_PinType_index[i+1]] -} diff --git a/vendor/github.com/coreos/go-systemd/v22/LICENSE b/vendor/github.com/coreos/go-systemd/v22/LICENSE deleted file mode 100644 index 37ec93a1..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/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-systemd/v22/NOTICE b/vendor/github.com/coreos/go-systemd/v22/NOTICE deleted file mode 100644 index 23a0ada2..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/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-systemd/v22/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go deleted file mode 100644 index cff5af1a..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go +++ /dev/null @@ -1,261 +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. - -// Integration with the systemd D-Bus API. See http://www.freedesktop.org/wiki/Software/systemd/dbus/ -package dbus - -import ( - "context" - "encoding/hex" - "fmt" - "os" - "strconv" - "strings" - "sync" - - "github.com/godbus/dbus/v5" -) - -const ( - alpha = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ` - num = `0123456789` - alphanum = alpha + num - signalBuffer = 100 -) - -// needsEscape checks whether a byte in a potential dbus ObjectPath needs to be escaped -func needsEscape(i int, b byte) bool { - // Escape everything that is not a-z-A-Z-0-9 - // Also escape 0-9 if it's the first character - return strings.IndexByte(alphanum, b) == -1 || - (i == 0 && strings.IndexByte(num, b) != -1) -} - -// PathBusEscape sanitizes a constituent string of a dbus ObjectPath using the -// rules that systemd uses for serializing special characters. -func PathBusEscape(path string) string { - // Special case the empty string - if len(path) == 0 { - return "_" - } - n := []byte{} - for i := 0; i < len(path); i++ { - c := path[i] - if needsEscape(i, c) { - e := fmt.Sprintf("_%x", c) - n = append(n, []byte(e)...) - } else { - n = append(n, c) - } - } - return string(n) -} - -// pathBusUnescape is the inverse of PathBusEscape. -func pathBusUnescape(path string) string { - if path == "_" { - return "" - } - n := []byte{} - for i := 0; i < len(path); i++ { - c := path[i] - if c == '_' && i+2 < len(path) { - res, err := hex.DecodeString(path[i+1 : i+3]) - if err == nil { - n = append(n, res...) - } - i += 2 - } else { - n = append(n, c) - } - } - return string(n) -} - -// Conn is a connection to systemd's dbus endpoint. -type Conn struct { - // sysconn/sysobj are only used to call dbus methods - sysconn *dbus.Conn - sysobj dbus.BusObject - - // sigconn/sigobj are only used to receive dbus signals - sigconn *dbus.Conn - sigobj dbus.BusObject - - jobListener struct { - jobs map[dbus.ObjectPath]chan<- string - sync.Mutex - } - subStateSubscriber struct { - updateCh chan<- *SubStateUpdate - errCh chan<- error - sync.Mutex - ignore map[dbus.ObjectPath]int64 - cleanIgnore int64 - } - propertiesSubscriber struct { - updateCh chan<- *PropertiesUpdate - errCh chan<- error - sync.Mutex - } -} - -// Deprecated: use NewWithContext instead. -func New() (*Conn, error) { - return NewWithContext(context.Background()) -} - -// NewWithContext establishes a connection to any available bus and authenticates. -// Callers should call Close() when done with the connection. -func NewWithContext(ctx context.Context) (*Conn, error) { - conn, err := NewSystemConnectionContext(ctx) - if err != nil && os.Geteuid() == 0 { - return NewSystemdConnectionContext(ctx) - } - return conn, err -} - -// Deprecated: use NewSystemConnectionContext instead. -func NewSystemConnection() (*Conn, error) { - return NewSystemConnectionContext(context.Background()) -} - -// NewSystemConnectionContext establishes a connection to the system bus and authenticates. -// Callers should call Close() when done with the connection. -func NewSystemConnectionContext(ctx context.Context) (*Conn, error) { - return NewConnection(func() (*dbus.Conn, error) { - return dbusAuthHelloConnection(ctx, dbus.SystemBusPrivate) - }) -} - -// Deprecated: use NewUserConnectionContext instead. -func NewUserConnection() (*Conn, error) { - return NewUserConnectionContext(context.Background()) -} - -// NewUserConnectionContext establishes a connection to the session bus and -// authenticates. This can be used to connect to systemd user instances. -// Callers should call Close() when done with the connection. -func NewUserConnectionContext(ctx context.Context) (*Conn, error) { - return NewConnection(func() (*dbus.Conn, error) { - return dbusAuthHelloConnection(ctx, dbus.SessionBusPrivate) - }) -} - -// Deprecated: use NewSystemdConnectionContext instead. -func NewSystemdConnection() (*Conn, error) { - return NewSystemdConnectionContext(context.Background()) -} - -// NewSystemdConnectionContext establishes a private, direct connection to systemd. -// This can be used for communicating with systemd without a dbus daemon. -// Callers should call Close() when done with the connection. -func NewSystemdConnectionContext(ctx context.Context) (*Conn, error) { - return NewConnection(func() (*dbus.Conn, error) { - // We skip Hello when talking directly to systemd. - return dbusAuthConnection(ctx, func(opts ...dbus.ConnOption) (*dbus.Conn, error) { - return dbus.Dial("unix:path=/run/systemd/private", opts...) - }) - }) -} - -// Close closes an established connection. -func (c *Conn) Close() { - c.sysconn.Close() - c.sigconn.Close() -} - -// NewConnection establishes a connection to a bus using a caller-supplied function. -// This allows connecting to remote buses through a user-supplied mechanism. -// The supplied function may be called multiple times, and should return independent connections. -// The returned connection must be fully initialised: the org.freedesktop.DBus.Hello call must have succeeded, -// and any authentication should be handled by the function. -func NewConnection(dialBus func() (*dbus.Conn, error)) (*Conn, error) { - sysconn, err := dialBus() - if err != nil { - return nil, err - } - - sigconn, err := dialBus() - if err != nil { - sysconn.Close() - return nil, err - } - - c := &Conn{ - sysconn: sysconn, - sysobj: systemdObject(sysconn), - sigconn: sigconn, - sigobj: systemdObject(sigconn), - } - - c.subStateSubscriber.ignore = make(map[dbus.ObjectPath]int64) - c.jobListener.jobs = make(map[dbus.ObjectPath]chan<- string) - - // Setup the listeners on jobs so that we can get completions - c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'") - - c.dispatch() - return c, nil -} - -// GetManagerProperty returns the value of a property on the org.freedesktop.systemd1.Manager -// interface. The value is returned in its string representation, as defined at -// https://developer.gnome.org/glib/unstable/gvariant-text.html. -func (c *Conn) GetManagerProperty(prop string) (string, error) { - variant, err := c.sysobj.GetProperty("org.freedesktop.systemd1.Manager." + prop) - if err != nil { - return "", err - } - return variant.String(), nil -} - -func dbusAuthConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) { - conn, err := createBus(dbus.WithContext(ctx)) - if err != nil { - return nil, err - } - - // Only use EXTERNAL method, and hardcode the uid (not username) - // to avoid a username lookup (which requires a dynamically linked - // libc) - methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))} - - err = conn.Auth(methods) - if err != nil { - conn.Close() - return nil, err - } - - return conn, nil -} - -func dbusAuthHelloConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) { - conn, err := dbusAuthConnection(ctx, createBus) - if err != nil { - return nil, err - } - - if err = conn.Hello(); err != nil { - conn.Close() - return nil, err - } - - return conn, nil -} - -func systemdObject(conn *dbus.Conn) dbus.BusObject { - return conn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1")) -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go deleted file mode 100644 index fa04afc7..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go +++ /dev/null @@ -1,830 +0,0 @@ -// Copyright 2015, 2018 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 dbus - -import ( - "context" - "errors" - "fmt" - "path" - "strconv" - - "github.com/godbus/dbus/v5" -) - -// Who can be used to specify which process to kill in the unit via the KillUnitWithTarget API -type Who string - -const ( - // All sends the signal to all processes in the unit - All Who = "all" - // Main sends the signal to the main process of the unit - Main Who = "main" - // Control sends the signal to the control process of the unit - Control Who = "control" -) - -func (c *Conn) jobComplete(signal *dbus.Signal) { - var id uint32 - var job dbus.ObjectPath - var unit string - var result string - dbus.Store(signal.Body, &id, &job, &unit, &result) - c.jobListener.Lock() - out, ok := c.jobListener.jobs[job] - if ok { - out <- result - delete(c.jobListener.jobs, job) - } - c.jobListener.Unlock() -} - -func (c *Conn) startJob(ctx context.Context, ch chan<- string, job string, args ...interface{}) (int, error) { - if ch != nil { - c.jobListener.Lock() - defer c.jobListener.Unlock() - } - - var p dbus.ObjectPath - err := c.sysobj.CallWithContext(ctx, job, 0, args...).Store(&p) - if err != nil { - return 0, err - } - - if ch != nil { - c.jobListener.jobs[p] = ch - } - - // ignore error since 0 is fine if conversion fails - jobID, _ := strconv.Atoi(path.Base(string(p))) - - return jobID, nil -} - -// Deprecated: use StartUnitContext instead. -func (c *Conn) StartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.StartUnitContext(context.Background(), name, mode, ch) -} - -// StartUnitContext enqueues a start job and depending jobs, if any (unless otherwise -// specified by the mode string). -// -// Takes the unit to activate, plus a mode string. The mode needs to be one of -// replace, fail, isolate, ignore-dependencies, ignore-requirements. If -// "replace" the call will start the unit and its dependencies, possibly -// replacing already queued jobs that conflict with this. If "fail" the call -// will start the unit and its dependencies, but will fail if this would change -// an already queued job. If "isolate" the call will start the unit in question -// and terminate all units that aren't dependencies of it. If -// "ignore-dependencies" it will start a unit but ignore all its dependencies. -// If "ignore-requirements" it will start a unit but only ignore the -// requirement dependencies. It is not recommended to make use of the latter -// two options. -// -// If the provided channel is non-nil, a result string will be sent to it upon -// job completion: one of done, canceled, timeout, failed, dependency, skipped. -// done indicates successful execution of a job. canceled indicates that a job -// has been canceled before it finished execution. timeout indicates that the -// job timeout was reached. failed indicates that the job failed. dependency -// indicates that a job this job has been depending on failed and the job hence -// has been removed too. skipped indicates that a job was skipped because it -// didn't apply to the units current state. -// -// If no error occurs, the ID of the underlying systemd job will be returned. There -// does exist the possibility for no error to be returned, but for the returned job -// ID to be 0. In this case, the actual underlying ID is not 0 and this datapoint -// should not be considered authoritative. -// -// If an error does occur, it will be returned to the user alongside a job ID of 0. -func (c *Conn) StartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode) -} - -// Deprecated: use StopUnitContext instead. -func (c *Conn) StopUnit(name string, mode string, ch chan<- string) (int, error) { - return c.StopUnitContext(context.Background(), name, mode, ch) -} - -// StopUnitContext is similar to StartUnitContext, but stops the specified unit -// rather than starting it. -func (c *Conn) StopUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode) -} - -// Deprecated: use ReloadUnitContext instead. -func (c *Conn) ReloadUnit(name string, mode string, ch chan<- string) (int, error) { - return c.ReloadUnitContext(context.Background(), name, mode, ch) -} - -// ReloadUnitContext reloads a unit. Reloading is done only if the unit -// is already running, and fails otherwise. -func (c *Conn) ReloadUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode) -} - -// Deprecated: use RestartUnitContext instead. -func (c *Conn) RestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.RestartUnitContext(context.Background(), name, mode, ch) -} - -// RestartUnitContext restarts a service. If a service is restarted that isn't -// running it will be started. -func (c *Conn) RestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode) -} - -// Deprecated: use TryRestartUnitContext instead. -func (c *Conn) TryRestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.TryRestartUnitContext(context.Background(), name, mode, ch) -} - -// TryRestartUnitContext is like RestartUnitContext, except that a service that -// isn't running is not affected by the restart. -func (c *Conn) TryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode) -} - -// Deprecated: use ReloadOrRestartUnitContext instead. -func (c *Conn) ReloadOrRestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.ReloadOrRestartUnitContext(context.Background(), name, mode, ch) -} - -// ReloadOrRestartUnitContext attempts a reload if the unit supports it and use -// a restart otherwise. -func (c *Conn) ReloadOrRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode) -} - -// Deprecated: use ReloadOrTryRestartUnitContext instead. -func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.ReloadOrTryRestartUnitContext(context.Background(), name, mode, ch) -} - -// ReloadOrTryRestartUnitContext attempts a reload if the unit supports it, -// and use a "Try" flavored restart otherwise. -func (c *Conn) ReloadOrTryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode) -} - -// Deprecated: use StartTransientUnitContext instead. -func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) { - return c.StartTransientUnitContext(context.Background(), name, mode, properties, ch) -} - -// StartTransientUnitContext may be used to create and start a transient unit, which -// will be released as soon as it is not running or referenced anymore or the -// system is rebooted. name is the unit name including suffix, and must be -// unique. mode is the same as in StartUnitContext, properties contains properties -// of the unit. -func (c *Conn) StartTransientUnitContext(ctx context.Context, name string, mode string, properties []Property, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0)) -} - -// Deprecated: use KillUnitContext instead. -func (c *Conn) KillUnit(name string, signal int32) { - c.KillUnitContext(context.Background(), name, signal) -} - -// KillUnitContext takes the unit name and a UNIX signal number to send. -// All of the unit's processes are killed. -func (c *Conn) KillUnitContext(ctx context.Context, name string, signal int32) { - c.KillUnitWithTarget(ctx, name, All, signal) -} - -// KillUnitWithTarget is like KillUnitContext, but allows you to specify which -// process in the unit to send the signal to. -func (c *Conn) KillUnitWithTarget(ctx context.Context, name string, target Who, signal int32) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.KillUnit", 0, name, string(target), signal).Store() -} - -// Deprecated: use ResetFailedUnitContext instead. -func (c *Conn) ResetFailedUnit(name string) error { - return c.ResetFailedUnitContext(context.Background(), name) -} - -// ResetFailedUnitContext resets the "failed" state of a specific unit. -func (c *Conn) ResetFailedUnitContext(ctx context.Context, name string) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store() -} - -// Deprecated: use SystemStateContext instead. -func (c *Conn) SystemState() (*Property, error) { - return c.SystemStateContext(context.Background()) -} - -// SystemStateContext returns the systemd state. Equivalent to -// systemctl is-system-running. -func (c *Conn) SystemStateContext(ctx context.Context) (*Property, error) { - var err error - var prop dbus.Variant - - obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") - err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop) - if err != nil { - return nil, err - } - - return &Property{Name: "SystemState", Value: prop}, nil -} - -// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface. -func (c *Conn) getProperties(ctx context.Context, path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) { - var err error - var props map[string]dbus.Variant - - if !path.IsValid() { - return nil, fmt.Errorf("invalid unit name: %v", path) - } - - obj := c.sysconn.Object("org.freedesktop.systemd1", path) - err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props) - if err != nil { - return nil, err - } - - out := make(map[string]interface{}, len(props)) - for k, v := range props { - out[k] = v.Value() - } - - return out, nil -} - -// Deprecated: use GetUnitPropertiesContext instead. -func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) { - return c.GetUnitPropertiesContext(context.Background(), unit) -} - -// GetUnitPropertiesContext takes the (unescaped) unit name and returns all of -// its dbus object properties. -func (c *Conn) GetUnitPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) { - path := unitPath(unit) - return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit") -} - -// Deprecated: use GetUnitPathPropertiesContext instead. -func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) { - return c.GetUnitPathPropertiesContext(context.Background(), path) -} - -// GetUnitPathPropertiesContext takes the (escaped) unit path and returns all -// of its dbus object properties. -func (c *Conn) GetUnitPathPropertiesContext(ctx context.Context, path dbus.ObjectPath) (map[string]interface{}, error) { - return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit") -} - -// Deprecated: use GetAllPropertiesContext instead. -func (c *Conn) GetAllProperties(unit string) (map[string]interface{}, error) { - return c.GetAllPropertiesContext(context.Background(), unit) -} - -// GetAllPropertiesContext takes the (unescaped) unit name and returns all of -// its dbus object properties. -func (c *Conn) GetAllPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) { - path := unitPath(unit) - return c.getProperties(ctx, path, "") -} - -func (c *Conn) getProperty(ctx context.Context, unit string, dbusInterface string, propertyName string) (*Property, error) { - var err error - var prop dbus.Variant - - path := unitPath(unit) - if !path.IsValid() { - return nil, errors.New("invalid unit name: " + unit) - } - - obj := c.sysconn.Object("org.freedesktop.systemd1", path) - err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop) - if err != nil { - return nil, err - } - - return &Property{Name: propertyName, Value: prop}, nil -} - -// Deprecated: use GetUnitPropertyContext instead. -func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) { - return c.GetUnitPropertyContext(context.Background(), unit, propertyName) -} - -// GetUnitPropertyContext takes an (unescaped) unit name, and a property name, -// and returns the property value. -func (c *Conn) GetUnitPropertyContext(ctx context.Context, unit string, propertyName string) (*Property, error) { - return c.getProperty(ctx, unit, "org.freedesktop.systemd1.Unit", propertyName) -} - -// Deprecated: use GetServicePropertyContext instead. -func (c *Conn) GetServiceProperty(service string, propertyName string) (*Property, error) { - return c.GetServicePropertyContext(context.Background(), service, propertyName) -} - -// GetServiceProperty returns property for given service name and property name. -func (c *Conn) GetServicePropertyContext(ctx context.Context, service string, propertyName string) (*Property, error) { - return c.getProperty(ctx, service, "org.freedesktop.systemd1.Service", propertyName) -} - -// Deprecated: use GetUnitTypePropertiesContext instead. -func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) { - return c.GetUnitTypePropertiesContext(context.Background(), unit, unitType) -} - -// GetUnitTypePropertiesContext returns the extra properties for a unit, specific to the unit type. -// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope. -// Returns "dbus.Error: Unknown interface" error if the unitType is not the correct type of the unit. -func (c *Conn) GetUnitTypePropertiesContext(ctx context.Context, unit string, unitType string) (map[string]interface{}, error) { - path := unitPath(unit) - return c.getProperties(ctx, path, "org.freedesktop.systemd1."+unitType) -} - -// Deprecated: use SetUnitPropertiesContext instead. -func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error { - return c.SetUnitPropertiesContext(context.Background(), name, runtime, properties...) -} - -// SetUnitPropertiesContext may be used to modify certain unit properties at runtime. -// Not all properties may be changed at runtime, but many resource management -// settings (primarily those in systemd.cgroup(5)) may. The changes are applied -// instantly, and stored on disk for future boots, unless runtime is true, in which -// case the settings only apply until the next reboot. name is the name of the unit -// to modify. properties are the settings to set, encoded as an array of property -// name and value pairs. -func (c *Conn) SetUnitPropertiesContext(ctx context.Context, name string, runtime bool, properties ...Property) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store() -} - -// Deprecated: use GetUnitTypePropertyContext instead. -func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) { - return c.GetUnitTypePropertyContext(context.Background(), unit, unitType, propertyName) -} - -// GetUnitTypePropertyContext takes a property name, a unit name, and a unit type, -// and returns a property value. For valid values of unitType, see GetUnitTypePropertiesContext. -func (c *Conn) GetUnitTypePropertyContext(ctx context.Context, unit string, unitType string, propertyName string) (*Property, error) { - return c.getProperty(ctx, unit, "org.freedesktop.systemd1."+unitType, propertyName) -} - -type UnitStatus struct { - Name string // The primary unit name as string - Description string // The human readable description string - LoadState string // The load state (i.e. whether the unit file has been loaded successfully) - ActiveState string // The active state (i.e. whether the unit is currently started or not) - SubState string // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not) - Followed string // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string. - Path dbus.ObjectPath // The unit object path - JobId uint32 // If there is a job queued for the job unit the numeric job id, 0 otherwise - JobType string // The job type as string - JobPath dbus.ObjectPath // The job object path -} - -type storeFunc func(retvalues ...interface{}) error - -func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) { - result := make([][]interface{}, 0) - err := f(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - status := make([]UnitStatus, len(result)) - statusInterface := make([]interface{}, len(status)) - for i := range status { - statusInterface[i] = &status[i] - } - - err = dbus.Store(resultInterface, statusInterface...) - if err != nil { - return nil, err - } - - return status, nil -} - -// Deprecated: use ListUnitsContext instead. -func (c *Conn) ListUnits() ([]UnitStatus, error) { - return c.ListUnitsContext(context.Background()) -} - -// ListUnitsContext returns an array with all currently loaded units. Note that -// units may be known by multiple names at the same time, and hence there might -// be more unit names loaded than actual units behind them. -// Also note that a unit is only loaded if it is active and/or enabled. -// Units that are both disabled and inactive will thus not be returned. -func (c *Conn) ListUnitsContext(ctx context.Context) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnits", 0).Store) -} - -// Deprecated: use ListUnitsFilteredContext instead. -func (c *Conn) ListUnitsFiltered(states []string) ([]UnitStatus, error) { - return c.ListUnitsFilteredContext(context.Background(), states) -} - -// ListUnitsFilteredContext returns an array with units filtered by state. -// It takes a list of units' statuses to filter. -func (c *Conn) ListUnitsFilteredContext(ctx context.Context, states []string) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store) -} - -// Deprecated: use ListUnitsByPatternsContext instead. -func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitStatus, error) { - return c.ListUnitsByPatternsContext(context.Background(), states, patterns) -} - -// ListUnitsByPatternsContext returns an array with units. -// It takes a list of units' statuses and names to filter. -// Note that units may be known by multiple names at the same time, -// and hence there might be more unit names loaded than actual units behind them. -func (c *Conn) ListUnitsByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store) -} - -// Deprecated: use ListUnitsByNamesContext instead. -func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) { - return c.ListUnitsByNamesContext(context.Background(), units) -} - -// ListUnitsByNamesContext returns an array with units. It takes a list of units' -// names and returns an UnitStatus array. Comparing to ListUnitsByPatternsContext -// method, this method returns statuses even for inactive or non-existing -// units. Input array should contain exact unit names, but not patterns. -// -// Requires systemd v230 or higher. -func (c *Conn) ListUnitsByNamesContext(ctx context.Context, units []string) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store) -} - -type UnitFile struct { - Path string - Type string -} - -func (c *Conn) listUnitFilesInternal(f storeFunc) ([]UnitFile, error) { - result := make([][]interface{}, 0) - err := f(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - files := make([]UnitFile, len(result)) - fileInterface := make([]interface{}, len(files)) - for i := range files { - fileInterface[i] = &files[i] - } - - err = dbus.Store(resultInterface, fileInterface...) - if err != nil { - return nil, err - } - - return files, nil -} - -// Deprecated: use ListUnitFilesContext instead. -func (c *Conn) ListUnitFiles() ([]UnitFile, error) { - return c.ListUnitFilesContext(context.Background()) -} - -// ListUnitFiles returns an array of all available units on disk. -func (c *Conn) ListUnitFilesContext(ctx context.Context) ([]UnitFile, error) { - return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store) -} - -// Deprecated: use ListUnitFilesByPatternsContext instead. -func (c *Conn) ListUnitFilesByPatterns(states []string, patterns []string) ([]UnitFile, error) { - return c.ListUnitFilesByPatternsContext(context.Background(), states, patterns) -} - -// ListUnitFilesByPatternsContext returns an array of all available units on disk matched the patterns. -func (c *Conn) ListUnitFilesByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitFile, error) { - return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store) -} - -type LinkUnitFileChange EnableUnitFileChange - -// Deprecated: use LinkUnitFilesContext instead. -func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { - return c.LinkUnitFilesContext(context.Background(), files, runtime, force) -} - -// LinkUnitFilesContext links unit files (that are located outside of the -// usual unit search paths) into the unit search path. -// -// It takes a list of absolute paths to unit files to link and two -// booleans. -// -// The first boolean controls whether the unit shall be -// enabled for runtime only (true, /run), or persistently (false, -// /etc). -// -// The second controls whether symlinks pointing to other units shall -// be replaced if necessary. -// -// This call returns a list of the changes made. The list consists of -// structures with three strings: the type of the change (one of symlink -// or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) LinkUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]LinkUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -// Deprecated: use EnableUnitFilesContext instead. -func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { - return c.EnableUnitFilesContext(context.Background(), files, runtime, force) -} - -// EnableUnitFilesContext may be used to enable one or more units in the system -// (by creating symlinks to them in /etc or /run). -// -// It takes a list of unit files to enable (either just file names or full -// absolute paths if the unit files are residing outside the usual unit -// search paths), and two booleans: the first controls whether the unit shall -// be enabled for runtime only (true, /run), or persistently (false, /etc). -// The second one controls whether symlinks pointing to other units shall -// be replaced if necessary. -// -// This call returns one boolean and an array with the changes made. The -// boolean signals whether the unit files contained any enablement -// information (i.e. an [Install]) section. The changes list consists of -// structures with three strings: the type of the change (one of symlink -// or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) EnableUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { - var carries_install_info bool - - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result) - if err != nil { - return false, nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]EnableUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return false, nil, err - } - - return carries_install_info, changes, nil -} - -type EnableUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use DisableUnitFilesContext instead. -func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) { - return c.DisableUnitFilesContext(context.Background(), files, runtime) -} - -// DisableUnitFilesContext may be used to disable one or more units in the -// system (by removing symlinks to them from /etc or /run). -// -// It takes a list of unit files to disable (either just file names or full -// absolute paths if the unit files are residing outside the usual unit -// search paths), and one boolean: whether the unit was enabled for runtime -// only (true, /run), or persistently (false, /etc). -// -// This call returns an array with the changes made. The changes list -// consists of structures with three strings: the type of the change (one of -// symlink or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) DisableUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]DisableUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]DisableUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -type DisableUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use MaskUnitFilesContext instead. -func (c *Conn) MaskUnitFiles(files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) { - return c.MaskUnitFilesContext(context.Background(), files, runtime, force) -} - -// MaskUnitFilesContext masks one or more units in the system. -// -// The files argument contains a list of units to mask (either just file names -// or full absolute paths if the unit files are residing outside the usual unit -// search paths). -// -// The runtime argument is used to specify whether the unit was enabled for -// runtime only (true, /run/systemd/..), or persistently (false, -// /etc/systemd/..). -func (c *Conn) MaskUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]MaskUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -type MaskUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use UnmaskUnitFilesContext instead. -func (c *Conn) UnmaskUnitFiles(files []string, runtime bool) ([]UnmaskUnitFileChange, error) { - return c.UnmaskUnitFilesContext(context.Background(), files, runtime) -} - -// UnmaskUnitFilesContext unmasks one or more units in the system. -// -// It takes the list of unit files to mask (either just file names or full -// absolute paths if the unit files are residing outside the usual unit search -// paths), and a boolean runtime flag to specify whether the unit was enabled -// for runtime only (true, /run/systemd/..), or persistently (false, -// /etc/systemd/..). -func (c *Conn) UnmaskUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]UnmaskUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]UnmaskUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -type UnmaskUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use ReloadContext instead. -func (c *Conn) Reload() error { - return c.ReloadContext(context.Background()) -} - -// ReloadContext instructs systemd to scan for and reload unit files. This is -// an equivalent to systemctl daemon-reload. -func (c *Conn) ReloadContext(ctx context.Context) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.Reload", 0).Store() -} - -func unitPath(name string) dbus.ObjectPath { - return dbus.ObjectPath("/org/freedesktop/systemd1/unit/" + PathBusEscape(name)) -} - -// unitName returns the unescaped base element of the supplied escaped path. -func unitName(dpath dbus.ObjectPath) string { - return pathBusUnescape(path.Base(string(dpath))) -} - -// JobStatus holds a currently queued job definition. -type JobStatus struct { - Id uint32 // The numeric job id - Unit string // The primary unit name for this job - JobType string // The job type as string - Status string // The job state as string - JobPath dbus.ObjectPath // The job object path - UnitPath dbus.ObjectPath // The unit object path -} - -// Deprecated: use ListJobsContext instead. -func (c *Conn) ListJobs() ([]JobStatus, error) { - return c.ListJobsContext(context.Background()) -} - -// ListJobsContext returns an array with all currently queued jobs. -func (c *Conn) ListJobsContext(ctx context.Context) ([]JobStatus, error) { - return c.listJobsInternal(ctx) -} - -func (c *Conn) listJobsInternal(ctx context.Context) ([]JobStatus, error) { - result := make([][]interface{}, 0) - if err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListJobs", 0).Store(&result); err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - status := make([]JobStatus, len(result)) - statusInterface := make([]interface{}, len(status)) - for i := range status { - statusInterface[i] = &status[i] - } - - if err := dbus.Store(resultInterface, statusInterface...); err != nil { - return nil, err - } - - return status, nil -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go b/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go deleted file mode 100644 index fb42b627..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go +++ /dev/null @@ -1,237 +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 dbus - -import ( - "github.com/godbus/dbus/v5" -) - -// From the systemd docs: -// -// The properties array of StartTransientUnit() may take many of the settings -// that may also be configured in unit files. Not all parameters are currently -// accepted though, but we plan to cover more properties with future release. -// Currently you may set the Description, Slice and all dependency types of -// units, as well as RemainAfterExit, ExecStart for service units, -// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares, -// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth, -// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit, -// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map -// directly to their counterparts in unit files and as normal D-Bus object -// properties. The exception here is the PIDs field of scope units which is -// used for construction of the scope only and specifies the initial PIDs to -// add to the scope object. - -type Property struct { - Name string - Value dbus.Variant -} - -type PropertyCollection struct { - Name string - Properties []Property -} - -type execStart struct { - Path string // the binary path to execute - Args []string // an array with all arguments to pass to the executed command, starting with argument 0 - UncleanIsFailure bool // a boolean whether it should be considered a failure if the process exits uncleanly -} - -// PropExecStart sets the ExecStart service property. The first argument is a -// slice with the binary path to execute followed by the arguments to pass to -// the executed command. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= -func PropExecStart(command []string, uncleanIsFailure bool) Property { - execStarts := []execStart{ - { - Path: command[0], - Args: command, - UncleanIsFailure: uncleanIsFailure, - }, - } - - return Property{ - Name: "ExecStart", - Value: dbus.MakeVariant(execStarts), - } -} - -// PropRemainAfterExit sets the RemainAfterExit service property. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit= -func PropRemainAfterExit(b bool) Property { - return Property{ - Name: "RemainAfterExit", - Value: dbus.MakeVariant(b), - } -} - -// PropType sets the Type service property. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= -func PropType(t string) Property { - return Property{ - Name: "Type", - Value: dbus.MakeVariant(t), - } -} - -// PropDescription sets the Description unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description= -func PropDescription(desc string) Property { - return Property{ - Name: "Description", - Value: dbus.MakeVariant(desc), - } -} - -func propDependency(name string, units []string) Property { - return Property{ - Name: name, - Value: dbus.MakeVariant(units), - } -} - -// PropRequires sets the Requires unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires= -func PropRequires(units ...string) Property { - return propDependency("Requires", units) -} - -// PropRequiresOverridable sets the RequiresOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresOverridable= -func PropRequiresOverridable(units ...string) Property { - return propDependency("RequiresOverridable", units) -} - -// PropRequisite sets the Requisite unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requisite= -func PropRequisite(units ...string) Property { - return propDependency("Requisite", units) -} - -// PropRequisiteOverridable sets the RequisiteOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequisiteOverridable= -func PropRequisiteOverridable(units ...string) Property { - return propDependency("RequisiteOverridable", units) -} - -// PropWants sets the Wants unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Wants= -func PropWants(units ...string) Property { - return propDependency("Wants", units) -} - -// PropBindsTo sets the BindsTo unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo= -func PropBindsTo(units ...string) Property { - return propDependency("BindsTo", units) -} - -// PropRequiredBy sets the RequiredBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredBy= -func PropRequiredBy(units ...string) Property { - return propDependency("RequiredBy", units) -} - -// PropRequiredByOverridable sets the RequiredByOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredByOverridable= -func PropRequiredByOverridable(units ...string) Property { - return propDependency("RequiredByOverridable", units) -} - -// PropWantedBy sets the WantedBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy= -func PropWantedBy(units ...string) Property { - return propDependency("WantedBy", units) -} - -// PropBoundBy sets the BoundBy unit property. See -// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy= -func PropBoundBy(units ...string) Property { - return propDependency("BoundBy", units) -} - -// PropConflicts sets the Conflicts unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Conflicts= -func PropConflicts(units ...string) Property { - return propDependency("Conflicts", units) -} - -// PropConflictedBy sets the ConflictedBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConflictedBy= -func PropConflictedBy(units ...string) Property { - return propDependency("ConflictedBy", units) -} - -// PropBefore sets the Before unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before= -func PropBefore(units ...string) Property { - return propDependency("Before", units) -} - -// PropAfter sets the After unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#After= -func PropAfter(units ...string) Property { - return propDependency("After", units) -} - -// PropOnFailure sets the OnFailure unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#OnFailure= -func PropOnFailure(units ...string) Property { - return propDependency("OnFailure", units) -} - -// PropTriggers sets the Triggers unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Triggers= -func PropTriggers(units ...string) Property { - return propDependency("Triggers", units) -} - -// PropTriggeredBy sets the TriggeredBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#TriggeredBy= -func PropTriggeredBy(units ...string) Property { - return propDependency("TriggeredBy", units) -} - -// PropPropagatesReloadTo sets the PropagatesReloadTo unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#PropagatesReloadTo= -func PropPropagatesReloadTo(units ...string) Property { - return propDependency("PropagatesReloadTo", units) -} - -// PropRequiresMountsFor sets the RequiresMountsFor unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresMountsFor= -func PropRequiresMountsFor(units ...string) Property { - return propDependency("RequiresMountsFor", units) -} - -// PropSlice sets the Slice unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Slice= -func PropSlice(slice string) Property { - return Property{ - Name: "Slice", - Value: dbus.MakeVariant(slice), - } -} - -// PropPids sets the PIDs field of scope units used in the initial construction -// of the scope only and specifies the initial PIDs to add to the scope object. -// See https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/#properties -func PropPids(pids ...uint32) Property { - return Property{ - Name: "PIDs", - Value: dbus.MakeVariant(pids), - } -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/set.go deleted file mode 100644 index 17c5d485..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/set.go +++ /dev/null @@ -1,47 +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 dbus - -type set struct { - data map[string]bool -} - -func (s *set) Add(value string) { - s.data[value] = true -} - -func (s *set) Remove(value string) { - delete(s.data, value) -} - -func (s *set) Contains(value string) (exists bool) { - _, exists = s.data[value] - return -} - -func (s *set) Length() int { - return len(s.data) -} - -func (s *set) Values() (values []string) { - for val := range s.data { - values = append(values, val) - } - return -} - -func newSet() *set { - return &set{make(map[string]bool)} -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go deleted file mode 100644 index 7e370fea..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go +++ /dev/null @@ -1,333 +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 dbus - -import ( - "errors" - "log" - "time" - - "github.com/godbus/dbus/v5" -) - -const ( - cleanIgnoreInterval = int64(10 * time.Second) - ignoreInterval = int64(30 * time.Millisecond) -) - -// Subscribe sets up this connection to subscribe to all systemd dbus events. -// This is required before calling SubscribeUnits. When the connection closes -// systemd will automatically stop sending signals so there is no need to -// explicitly call Unsubscribe(). -func (c *Conn) Subscribe() error { - c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'") - c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'") - - return c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store() -} - -// Unsubscribe this connection from systemd dbus events. -func (c *Conn) Unsubscribe() error { - return c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store() -} - -func (c *Conn) dispatch() { - ch := make(chan *dbus.Signal, signalBuffer) - - c.sigconn.Signal(ch) - - go func() { - for { - signal, ok := <-ch - if !ok { - return - } - - if signal.Name == "org.freedesktop.systemd1.Manager.JobRemoved" { - c.jobComplete(signal) - } - - if c.subStateSubscriber.updateCh == nil && - c.propertiesSubscriber.updateCh == nil { - continue - } - - var unitPath dbus.ObjectPath - switch signal.Name { - case "org.freedesktop.systemd1.Manager.JobRemoved": - unitName := signal.Body[2].(string) - c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath) - case "org.freedesktop.systemd1.Manager.UnitNew": - unitPath = signal.Body[1].(dbus.ObjectPath) - case "org.freedesktop.DBus.Properties.PropertiesChanged": - if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" { - unitPath = signal.Path - - if len(signal.Body) >= 2 { - if changed, ok := signal.Body[1].(map[string]dbus.Variant); ok { - c.sendPropertiesUpdate(unitPath, changed) - } - } - } - } - - if unitPath == dbus.ObjectPath("") { - continue - } - - c.sendSubStateUpdate(unitPath) - } - }() -} - -// SubscribeUnits returns two unbuffered channels which will receive all changed units every -// interval. Deleted units are sent as nil. -func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) { - return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, nil) -} - -// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer -// size of the channels, the comparison function for detecting changes and a filter -// function for cutting down on the noise that your channel receives. -func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func(string) bool) (<-chan map[string]*UnitStatus, <-chan error) { - old := make(map[string]*UnitStatus) - statusChan := make(chan map[string]*UnitStatus, buffer) - errChan := make(chan error, buffer) - - go func() { - for { - timerChan := time.After(interval) - - units, err := c.ListUnits() - if err == nil { - cur := make(map[string]*UnitStatus) - for i := range units { - if filterUnit != nil && filterUnit(units[i].Name) { - continue - } - cur[units[i].Name] = &units[i] - } - - // add all new or changed units - changed := make(map[string]*UnitStatus) - for n, u := range cur { - if oldU, ok := old[n]; !ok || isChanged(oldU, u) { - changed[n] = u - } - delete(old, n) - } - - // add all deleted units - for oldN := range old { - changed[oldN] = nil - } - - old = cur - - if len(changed) != 0 { - statusChan <- changed - } - } else { - errChan <- err - } - - <-timerChan - } - }() - - return statusChan, errChan -} - -type SubStateUpdate struct { - UnitName string - SubState string -} - -// SetSubStateSubscriber writes to updateCh when any unit's substate changes. -// Although this writes to updateCh on every state change, the reported state -// may be more recent than the change that generated it (due to an unavoidable -// race in the systemd dbus interface). That is, this method provides a good -// way to keep a current view of all units' states, but is not guaranteed to -// show every state transition they go through. Furthermore, state changes -// will only be written to the channel with non-blocking writes. If updateCh -// is full, it attempts to write an error to errCh; if errCh is full, the error -// passes silently. -func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) { - if c == nil { - msg := "nil receiver" - select { - case errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } - - c.subStateSubscriber.Lock() - defer c.subStateSubscriber.Unlock() - c.subStateSubscriber.updateCh = updateCh - c.subStateSubscriber.errCh = errCh -} - -func (c *Conn) sendSubStateUpdate(unitPath dbus.ObjectPath) { - c.subStateSubscriber.Lock() - defer c.subStateSubscriber.Unlock() - - if c.subStateSubscriber.updateCh == nil { - return - } - - isIgnored := c.shouldIgnore(unitPath) - defer c.cleanIgnore() - if isIgnored { - return - } - - info, err := c.GetUnitPathProperties(unitPath) - if err != nil { - select { - case c.subStateSubscriber.errCh <- err: - default: - log.Printf("full error channel while reporting: %s\n", err) - } - return - } - defer c.updateIgnore(unitPath, info) - - name, ok := info["Id"].(string) - if !ok { - msg := "failed to cast info.Id" - select { - case c.subStateSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", err) - } - return - } - substate, ok := info["SubState"].(string) - if !ok { - msg := "failed to cast info.SubState" - select { - case c.subStateSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } - - update := &SubStateUpdate{name, substate} - select { - case c.subStateSubscriber.updateCh <- update: - default: - msg := "update channel is full" - select { - case c.subStateSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } -} - -// The ignore functions work around a wart in the systemd dbus interface. -// Requesting the properties of an unloaded unit will cause systemd to send a -// pair of UnitNew/UnitRemoved signals. Because we need to get a unit's -// properties on UnitNew (as that's the only indication of a new unit coming up -// for the first time), we would enter an infinite loop if we did not attempt -// to detect and ignore these spurious signals. The signal themselves are -// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an -// unloaded unit's signals for a short time after requesting its properties. -// This means that we will miss e.g. a transient unit being restarted -// *immediately* upon failure and also a transient unit being started -// immediately after requesting its status (with systemctl status, for example, -// because this causes a UnitNew signal to be sent which then causes us to fetch -// the properties). - -func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool { - t, ok := c.subStateSubscriber.ignore[path] - return ok && t >= time.Now().UnixNano() -} - -func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) { - loadState, ok := info["LoadState"].(string) - if !ok { - return - } - - // unit is unloaded - it will trigger bad systemd dbus behavior - if loadState == "not-found" { - c.subStateSubscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval - } -} - -// without this, ignore would grow unboundedly over time -func (c *Conn) cleanIgnore() { - now := time.Now().UnixNano() - if c.subStateSubscriber.cleanIgnore < now { - c.subStateSubscriber.cleanIgnore = now + cleanIgnoreInterval - - for p, t := range c.subStateSubscriber.ignore { - if t < now { - delete(c.subStateSubscriber.ignore, p) - } - } - } -} - -// PropertiesUpdate holds a map of a unit's changed properties -type PropertiesUpdate struct { - UnitName string - Changed map[string]dbus.Variant -} - -// SetPropertiesSubscriber writes to updateCh when any unit's properties -// change. Every property change reported by systemd will be sent; that is, no -// transitions will be "missed" (as they might be with SetSubStateSubscriber). -// However, state changes will only be written to the channel with non-blocking -// writes. If updateCh is full, it attempts to write an error to errCh; if -// errCh is full, the error passes silently. -func (c *Conn) SetPropertiesSubscriber(updateCh chan<- *PropertiesUpdate, errCh chan<- error) { - c.propertiesSubscriber.Lock() - defer c.propertiesSubscriber.Unlock() - c.propertiesSubscriber.updateCh = updateCh - c.propertiesSubscriber.errCh = errCh -} - -// we don't need to worry about shouldIgnore() here because -// sendPropertiesUpdate doesn't call GetProperties() -func (c *Conn) sendPropertiesUpdate(unitPath dbus.ObjectPath, changedProps map[string]dbus.Variant) { - c.propertiesSubscriber.Lock() - defer c.propertiesSubscriber.Unlock() - - if c.propertiesSubscriber.updateCh == nil { - return - } - - update := &PropertiesUpdate{unitName(unitPath), changedProps} - - select { - case c.propertiesSubscriber.updateCh <- update: - default: - msg := "update channel is full" - select { - case c.propertiesSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go deleted file mode 100644 index 5b408d58..00000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go +++ /dev/null @@ -1,57 +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 dbus - -import ( - "time" -) - -// SubscriptionSet returns a subscription set which is like conn.Subscribe but -// can filter to only return events for a set of units. -type SubscriptionSet struct { - *set - conn *Conn -} - -func (s *SubscriptionSet) filter(unit string) bool { - return !s.Contains(unit) -} - -// Subscribe starts listening for dbus events for all of the units in the set. -// Returns channels identical to conn.SubscribeUnits. -func (s *SubscriptionSet) Subscribe() (<-chan map[string]*UnitStatus, <-chan error) { - // TODO: Make fully evented by using systemd 209 with properties changed values - return s.conn.SubscribeUnitsCustom(time.Second, 0, - mismatchUnitStatus, - func(unit string) bool { return s.filter(unit) }, - ) -} - -// NewSubscriptionSet returns a new subscription set. -func (conn *Conn) NewSubscriptionSet() *SubscriptionSet { - return &SubscriptionSet{newSet(), conn} -} - -// mismatchUnitStatus returns true if the provided UnitStatus objects -// are not equivalent. false is returned if the objects are equivalent. -// Only the Name, Description and state-related fields are used in -// the comparison. -func mismatchUnitStatus(u1, u2 *UnitStatus) bool { - return u1.Name != u2.Name || - u1.Description != u2.Description || - u1.LoadState != u2.LoadState || - u1.ActiveState != u2.ActiveState || - u1.SubState != u2.SubState -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/.travis.yml b/vendor/github.com/cyphar/filepath-securejoin/.travis.yml deleted file mode 100644 index b94ff8cf..00000000 --- a/vendor/github.com/cyphar/filepath-securejoin/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2017 SUSE LLC. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -language: go -go: - - 1.13.x - - 1.16.x - - tip -arch: - - AMD64 - - ppc64le -os: - - linux - - osx - -script: - - go test -cover -v ./... - -notifications: - email: false diff --git a/vendor/github.com/cyphar/filepath-securejoin/LICENSE b/vendor/github.com/cyphar/filepath-securejoin/LICENSE deleted file mode 100644 index bec842f2..00000000 --- a/vendor/github.com/cyphar/filepath-securejoin/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. -Copyright (C) 2017 SUSE LLC. 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/cyphar/filepath-securejoin/README.md b/vendor/github.com/cyphar/filepath-securejoin/README.md deleted file mode 100644 index 3624617c..00000000 --- a/vendor/github.com/cyphar/filepath-securejoin/README.md +++ /dev/null @@ -1,79 +0,0 @@ -## `filepath-securejoin` ## - -[![Build Status](https://travis-ci.org/cyphar/filepath-securejoin.svg?branch=master)](https://travis-ci.org/cyphar/filepath-securejoin) - -An implementation of `SecureJoin`, a [candidate for inclusion in the Go -standard library][go#20126]. The purpose of this function is to be a "secure" -alternative to `filepath.Join`, and in particular it provides certain -guarantees that are not provided by `filepath.Join`. - -> **NOTE**: This code is *only* safe if you are not at risk of other processes -> modifying path components after you've used `SecureJoin`. If it is possible -> for a malicious process to modify path components of the resolved path, then -> you will be vulnerable to some fairly trivial TOCTOU race conditions. [There -> are some Linux kernel patches I'm working on which might allow for a better -> solution.][lwn-obeneath] -> -> In addition, with a slightly modified API it might be possible to use -> `O_PATH` and verify that the opened path is actually the resolved one -- but -> I have not done that yet. I might add it in the future as a helper function -> to help users verify the path (we can't just return `/proc/self/fd/` -> because that doesn't always work transparently for all users). - -This is the function prototype: - -```go -func SecureJoin(root, unsafePath string) (string, error) -``` - -This library **guarantees** the following: - -* If no error is set, the resulting string **must** be a child path of - `root` and will not contain any symlink path components (they will all be - expanded). - -* When expanding symlinks, all symlink path components **must** be resolved - relative to the provided root. In particular, this can be considered a - userspace implementation of how `chroot(2)` operates on file paths. Note that - these symlinks will **not** be expanded lexically (`filepath.Clean` is not - called on the input before processing). - -* Non-existent path components are unaffected by `SecureJoin` (similar to - `filepath.EvalSymlinks`'s semantics). - -* The returned path will always be `filepath.Clean`ed and thus not contain any - `..` components. - -A (trivial) implementation of this function on GNU/Linux systems could be done -with the following (note that this requires root privileges and is far more -opaque than the implementation in this library, and also requires that -`readlink` is inside the `root` path): - -```go -package securejoin - -import ( - "os/exec" - "path/filepath" -) - -func SecureJoin(root, unsafePath string) (string, error) { - unsafePath = string(filepath.Separator) + unsafePath - cmd := exec.Command("chroot", root, - "readlink", "--canonicalize-missing", "--no-newline", unsafePath) - output, err := cmd.CombinedOutput() - if err != nil { - return "", err - } - expanded := string(output) - return filepath.Join(root, expanded), nil -} -``` - -[lwn-obeneath]: https://lwn.net/Articles/767547/ -[go#20126]: https://github.com/golang/go/issues/20126 - -### License ### - -The license of this project is the same as Go, which is a BSD 3-clause license -available in the `LICENSE` file. diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION deleted file mode 100644 index 71790396..00000000 --- a/vendor/github.com/cyphar/filepath-securejoin/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.2.3 diff --git a/vendor/github.com/cyphar/filepath-securejoin/join.go b/vendor/github.com/cyphar/filepath-securejoin/join.go deleted file mode 100644 index 7dd08dbb..00000000 --- a/vendor/github.com/cyphar/filepath-securejoin/join.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. -// Copyright (C) 2017 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package securejoin is an implementation of the hopefully-soon-to-be-included -// SecureJoin helper that is meant to be part of the "path/filepath" package. -// The purpose of this project is to provide a PoC implementation to make the -// SecureJoin proposal (https://github.com/golang/go/issues/20126) more -// tangible. -package securejoin - -import ( - "bytes" - "errors" - "os" - "path/filepath" - "strings" - "syscall" -) - -// IsNotExist tells you if err is an error that implies that either the path -// accessed does not exist (or path components don't exist). This is -// effectively a more broad version of os.IsNotExist. -func IsNotExist(err error) bool { - // Check that it's not actually an ENOTDIR, which in some cases is a more - // convoluted case of ENOENT (usually involving weird paths). - return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT) -} - -// SecureJoinVFS joins the two given path components (similar to Join) except -// that the returned path is guaranteed to be scoped inside the provided root -// path (when evaluated). Any symbolic links in the path are evaluated with the -// given root treated as the root of the filesystem, similar to a chroot. The -// filesystem state is evaluated through the given VFS interface (if nil, the -// standard os.* family of functions are used). -// -// Note that the guarantees provided by this function only apply if the path -// components in the returned string are not modified (in other words are not -// replaced with symlinks on the filesystem) after this function has returned. -// Such a symlink race is necessarily out-of-scope of SecureJoin. -func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { - // Use the os.* VFS implementation if none was specified. - if vfs == nil { - vfs = osVFS{} - } - - var path bytes.Buffer - n := 0 - for unsafePath != "" { - if n > 255 { - return "", &os.PathError{Op: "SecureJoin", Path: root + "/" + unsafePath, Err: syscall.ELOOP} - } - - // Next path component, p. - i := strings.IndexRune(unsafePath, filepath.Separator) - var p string - if i == -1 { - p, unsafePath = unsafePath, "" - } else { - p, unsafePath = unsafePath[:i], unsafePath[i+1:] - } - - // Create a cleaned path, using the lexical semantics of /../a, to - // create a "scoped" path component which can safely be joined to fullP - // for evaluation. At this point, path.String() doesn't contain any - // symlink components. - cleanP := filepath.Clean(string(filepath.Separator) + path.String() + p) - if cleanP == string(filepath.Separator) { - path.Reset() - continue - } - fullP := filepath.Clean(root + cleanP) - - // Figure out whether the path is a symlink. - fi, err := vfs.Lstat(fullP) - if err != nil && !IsNotExist(err) { - return "", err - } - // Treat non-existent path components the same as non-symlinks (we - // can't do any better here). - if IsNotExist(err) || fi.Mode()&os.ModeSymlink == 0 { - path.WriteString(p) - path.WriteRune(filepath.Separator) - continue - } - - // Only increment when we actually dereference a link. - n++ - - // It's a symlink, expand it by prepending it to the yet-unparsed path. - dest, err := vfs.Readlink(fullP) - if err != nil { - return "", err - } - // Absolute symlinks reset any work we've already done. - if filepath.IsAbs(dest) { - path.Reset() - } - unsafePath = dest + string(filepath.Separator) + unsafePath - } - - // We have to clean path.String() here because it may contain '..' - // components that are entirely lexical, but would be misleading otherwise. - // And finally do a final clean to ensure that root is also lexically - // clean. - fullP := filepath.Clean(string(filepath.Separator) + path.String()) - return filepath.Clean(root + fullP), nil -} - -// SecureJoin is a wrapper around SecureJoinVFS that just uses the os.* library -// of functions as the VFS. If in doubt, use this function over SecureJoinVFS. -func SecureJoin(root, unsafePath string) (string, error) { - return SecureJoinVFS(root, unsafePath, nil) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/vfs.go b/vendor/github.com/cyphar/filepath-securejoin/vfs.go deleted file mode 100644 index a82a5eae..00000000 --- a/vendor/github.com/cyphar/filepath-securejoin/vfs.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2017 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package securejoin - -import "os" - -// In future this should be moved into a separate package, because now there -// are several projects (umoci and go-mtree) that are using this sort of -// interface. - -// VFS is the minimal interface necessary to use SecureJoinVFS. A nil VFS is -// equivalent to using the standard os.* family of functions. This is mainly -// used for the purposes of mock testing, but also can be used to otherwise use -// SecureJoin with VFS-like system. -type VFS interface { - // Lstat returns a FileInfo describing the named file. If the file is a - // symbolic link, the returned FileInfo describes the symbolic link. Lstat - // makes no attempt to follow the link. These semantics are identical to - // os.Lstat. - Lstat(name string) (os.FileInfo, error) - - // Readlink returns the destination of the named symbolic link. These - // semantics are identical to os.Readlink. - Readlink(name string) (string, error) -} - -// osVFS is the "nil" VFS, in that it just passes everything through to the os -// module. -type osVFS struct{} - -// Lstat returns a FileInfo describing the named file. If the file is a -// symbolic link, the returned FileInfo describes the symbolic link. Lstat -// makes no attempt to follow the link. These semantics are identical to -// os.Lstat. -func (o osVFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) } - -// Readlink returns the destination of the named symbolic link. These -// semantics are identical to os.Readlink. -func (o osVFS) Readlink(name string) (string, error) { return os.Readlink(name) } diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE deleted file mode 100644 index bc52e96f..00000000 --- a/vendor/github.com/davecgh/go-spew/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -ISC License - -Copyright (c) 2012-2016 Dave Collins - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go deleted file mode 100644 index 79299478..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is not running on Google App Engine, compiled by GopherJS, and -// "-tags safe" is not added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// Go versions prior to 1.4 are disabled because they use a different layout -// for interfaces which make the implementation of unsafeReflectValue more complex. -// +build !js,!appengine,!safe,!disableunsafe,go1.4 - -package spew - -import ( - "reflect" - "unsafe" -) - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = false - - // ptrSize is the size of a pointer on the current arch. - ptrSize = unsafe.Sizeof((*byte)(nil)) -) - -type flag uintptr - -var ( - // flagRO indicates whether the value field of a reflect.Value - // is read-only. - flagRO flag - - // flagAddr indicates whether the address of the reflect.Value's - // value may be taken. - flagAddr flag -) - -// flagKindMask holds the bits that make up the kind -// part of the flags field. In all the supported versions, -// it is in the lower 5 bits. -const flagKindMask = flag(0x1f) - -// Different versions of Go have used different -// bit layouts for the flags type. This table -// records the known combinations. -var okFlags = []struct { - ro, addr flag -}{{ - // From Go 1.4 to 1.5 - ro: 1 << 5, - addr: 1 << 7, -}, { - // Up to Go tip. - ro: 1<<5 | 1<<6, - addr: 1 << 8, -}} - -var flagValOffset = func() uintptr { - field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") - if !ok { - panic("reflect.Value has no flag field") - } - return field.Offset -}() - -// flagField returns a pointer to the flag field of a reflect.Value. -func flagField(v *reflect.Value) *flag { - return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) -} - -// unsafeReflectValue converts the passed reflect.Value into a one that bypasses -// the typical safety restrictions preventing access to unaddressable and -// unexported data. It works by digging the raw pointer to the underlying -// value out of the protected value and generating a new unprotected (unsafe) -// reflect.Value to it. -// -// This allows us to check for implementations of the Stringer and error -// interfaces to be used for pretty printing ordinarily unaddressable and -// inaccessible values such as unexported struct fields. -func unsafeReflectValue(v reflect.Value) reflect.Value { - if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { - return v - } - flagFieldPtr := flagField(&v) - *flagFieldPtr &^= flagRO - *flagFieldPtr |= flagAddr - return v -} - -// Sanity checks against future reflect package changes -// to the type or semantics of the Value.flag field. -func init() { - field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") - if !ok { - panic("reflect.Value has no flag field") - } - if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { - panic("reflect.Value flag field has changed kind") - } - type t0 int - var t struct { - A t0 - // t0 will have flagEmbedRO set. - t0 - // a will have flagStickyRO set - a t0 - } - vA := reflect.ValueOf(t).FieldByName("A") - va := reflect.ValueOf(t).FieldByName("a") - vt0 := reflect.ValueOf(t).FieldByName("t0") - - // Infer flagRO from the difference between the flags - // for the (otherwise identical) fields in t. - flagPublic := *flagField(&vA) - flagWithRO := *flagField(&va) | *flagField(&vt0) - flagRO = flagPublic ^ flagWithRO - - // Infer flagAddr from the difference between a value - // taken from a pointer and not. - vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") - flagNoPtr := *flagField(&vA) - flagPtr := *flagField(&vPtrA) - flagAddr = flagNoPtr ^ flagPtr - - // Check that the inferred flags tally with one of the known versions. - for _, f := range okFlags { - if flagRO == f.ro && flagAddr == f.addr { - return - } - } - panic("reflect.Value read-only flag has changed semantics") -} diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go deleted file mode 100644 index 205c28d6..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is running on Google App Engine, compiled by GopherJS, or -// "-tags safe" is added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build js appengine safe disableunsafe !go1.4 - -package spew - -import "reflect" - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = true -) - -// unsafeReflectValue typically converts the passed reflect.Value into a one -// that bypasses the typical safety restrictions preventing access to -// unaddressable and unexported data. However, doing this relies on access to -// the unsafe package. This is a stub version which simply returns the passed -// reflect.Value when the unsafe package is not available. -func unsafeReflectValue(v reflect.Value) reflect.Value { - return v -} diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go deleted file mode 100644 index 1be8ce94..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/common.go +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "reflect" - "sort" - "strconv" -) - -// Some constants in the form of bytes to avoid string overhead. This mirrors -// the technique used in the fmt package. -var ( - panicBytes = []byte("(PANIC=") - plusBytes = []byte("+") - iBytes = []byte("i") - trueBytes = []byte("true") - falseBytes = []byte("false") - interfaceBytes = []byte("(interface {})") - commaNewlineBytes = []byte(",\n") - newlineBytes = []byte("\n") - openBraceBytes = []byte("{") - openBraceNewlineBytes = []byte("{\n") - closeBraceBytes = []byte("}") - asteriskBytes = []byte("*") - colonBytes = []byte(":") - colonSpaceBytes = []byte(": ") - openParenBytes = []byte("(") - closeParenBytes = []byte(")") - spaceBytes = []byte(" ") - pointerChainBytes = []byte("->") - nilAngleBytes = []byte("") - maxNewlineBytes = []byte("\n") - maxShortBytes = []byte("") - circularBytes = []byte("") - circularShortBytes = []byte("") - invalidAngleBytes = []byte("") - openBracketBytes = []byte("[") - closeBracketBytes = []byte("]") - percentBytes = []byte("%") - precisionBytes = []byte(".") - openAngleBytes = []byte("<") - closeAngleBytes = []byte(">") - openMapBytes = []byte("map[") - closeMapBytes = []byte("]") - lenEqualsBytes = []byte("len=") - capEqualsBytes = []byte("cap=") -) - -// hexDigits is used to map a decimal value to a hex digit. -var hexDigits = "0123456789abcdef" - -// catchPanic handles any panics that might occur during the handleMethods -// calls. -func catchPanic(w io.Writer, v reflect.Value) { - if err := recover(); err != nil { - w.Write(panicBytes) - fmt.Fprintf(w, "%v", err) - w.Write(closeParenBytes) - } -} - -// handleMethods attempts to call the Error and String methods on the underlying -// type the passed reflect.Value represents and outputes the result to Writer w. -// -// It handles panics in any called methods by catching and displaying the error -// as the formatted value. -func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { - // We need an interface to check if the type implements the error or - // Stringer interface. However, the reflect package won't give us an - // interface on certain things like unexported struct fields in order - // to enforce visibility rules. We use unsafe, when it's available, - // to bypass these restrictions since this package does not mutate the - // values. - if !v.CanInterface() { - if UnsafeDisabled { - return false - } - - v = unsafeReflectValue(v) - } - - // Choose whether or not to do error and Stringer interface lookups against - // the base type or a pointer to the base type depending on settings. - // Technically calling one of these methods with a pointer receiver can - // mutate the value, however, types which choose to satisify an error or - // Stringer interface with a pointer receiver should not be mutating their - // state inside these interface methods. - if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { - v = unsafeReflectValue(v) - } - if v.CanAddr() { - v = v.Addr() - } - - // Is it an error or Stringer? - switch iface := v.Interface().(type) { - case error: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.Error())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - - w.Write([]byte(iface.Error())) - return true - - case fmt.Stringer: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.String())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - w.Write([]byte(iface.String())) - return true - } - return false -} - -// printBool outputs a boolean value as true or false to Writer w. -func printBool(w io.Writer, val bool) { - if val { - w.Write(trueBytes) - } else { - w.Write(falseBytes) - } -} - -// printInt outputs a signed integer value to Writer w. -func printInt(w io.Writer, val int64, base int) { - w.Write([]byte(strconv.FormatInt(val, base))) -} - -// printUint outputs an unsigned integer value to Writer w. -func printUint(w io.Writer, val uint64, base int) { - w.Write([]byte(strconv.FormatUint(val, base))) -} - -// printFloat outputs a floating point value using the specified precision, -// which is expected to be 32 or 64bit, to Writer w. -func printFloat(w io.Writer, val float64, precision int) { - w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) -} - -// printComplex outputs a complex value using the specified float precision -// for the real and imaginary parts to Writer w. -func printComplex(w io.Writer, c complex128, floatPrecision int) { - r := real(c) - w.Write(openParenBytes) - w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) - i := imag(c) - if i >= 0 { - w.Write(plusBytes) - } - w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) - w.Write(iBytes) - w.Write(closeParenBytes) -} - -// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' -// prefix to Writer w. -func printHexPtr(w io.Writer, p uintptr) { - // Null pointer. - num := uint64(p) - if num == 0 { - w.Write(nilAngleBytes) - return - } - - // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix - buf := make([]byte, 18) - - // It's simpler to construct the hex string right to left. - base := uint64(16) - i := len(buf) - 1 - for num >= base { - buf[i] = hexDigits[num%base] - num /= base - i-- - } - buf[i] = hexDigits[num] - - // Add '0x' prefix. - i-- - buf[i] = 'x' - i-- - buf[i] = '0' - - // Strip unused leading bytes. - buf = buf[i:] - w.Write(buf) -} - -// valuesSorter implements sort.Interface to allow a slice of reflect.Value -// elements to be sorted. -type valuesSorter struct { - values []reflect.Value - strings []string // either nil or same len and values - cs *ConfigState -} - -// newValuesSorter initializes a valuesSorter instance, which holds a set of -// surrogate keys on which the data should be sorted. It uses flags in -// ConfigState to decide if and how to populate those surrogate keys. -func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { - vs := &valuesSorter{values: values, cs: cs} - if canSortSimply(vs.values[0].Kind()) { - return vs - } - if !cs.DisableMethods { - vs.strings = make([]string, len(values)) - for i := range vs.values { - b := bytes.Buffer{} - if !handleMethods(cs, &b, vs.values[i]) { - vs.strings = nil - break - } - vs.strings[i] = b.String() - } - } - if vs.strings == nil && cs.SpewKeys { - vs.strings = make([]string, len(values)) - for i := range vs.values { - vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) - } - } - return vs -} - -// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted -// directly, or whether it should be considered for sorting by surrogate keys -// (if the ConfigState allows it). -func canSortSimply(kind reflect.Kind) bool { - // This switch parallels valueSortLess, except for the default case. - switch kind { - case reflect.Bool: - return true - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return true - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return true - case reflect.Float32, reflect.Float64: - return true - case reflect.String: - return true - case reflect.Uintptr: - return true - case reflect.Array: - return true - } - return false -} - -// Len returns the number of values in the slice. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Len() int { - return len(s.values) -} - -// Swap swaps the values at the passed indices. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Swap(i, j int) { - s.values[i], s.values[j] = s.values[j], s.values[i] - if s.strings != nil { - s.strings[i], s.strings[j] = s.strings[j], s.strings[i] - } -} - -// valueSortLess returns whether the first value should sort before the second -// value. It is used by valueSorter.Less as part of the sort.Interface -// implementation. -func valueSortLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Bool: - return !a.Bool() && b.Bool() - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return a.Int() < b.Int() - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return a.Uint() < b.Uint() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.String: - return a.String() < b.String() - case reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Array: - // Compare the contents of both arrays. - l := a.Len() - for i := 0; i < l; i++ { - av := a.Index(i) - bv := b.Index(i) - if av.Interface() == bv.Interface() { - continue - } - return valueSortLess(av, bv) - } - } - return a.String() < b.String() -} - -// Less returns whether the value at index i should sort before the -// value at index j. It is part of the sort.Interface implementation. -func (s *valuesSorter) Less(i, j int) bool { - if s.strings == nil { - return valueSortLess(s.values[i], s.values[j]) - } - return s.strings[i] < s.strings[j] -} - -// sortValues is a sort function that handles both native types and any type that -// can be converted to error or Stringer. Other inputs are sorted according to -// their Value.String() value to ensure display stability. -func sortValues(values []reflect.Value, cs *ConfigState) { - if len(values) == 0 { - return - } - sort.Sort(newValuesSorter(values, cs)) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go deleted file mode 100644 index 2e3d22f3..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/config.go +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "os" -) - -// ConfigState houses the configuration options used by spew to format and -// display values. There is a global instance, Config, that is used to control -// all top-level Formatter and Dump functionality. Each ConfigState instance -// provides methods equivalent to the top-level functions. -// -// The zero value for ConfigState provides no indentation. You would typically -// want to set it to a space or a tab. -// -// Alternatively, you can use NewDefaultConfig to get a ConfigState instance -// with default settings. See the documentation of NewDefaultConfig for default -// values. -type ConfigState struct { - // Indent specifies the string to use for each indentation level. The - // global config instance that all top-level functions use set this to a - // single space by default. If you would like more indentation, you might - // set this to a tab with "\t" or perhaps two spaces with " ". - Indent string - - // MaxDepth controls the maximum number of levels to descend into nested - // data structures. The default, 0, means there is no limit. - // - // NOTE: Circular data structures are properly detected, so it is not - // necessary to set this value unless you specifically want to limit deeply - // nested data structures. - MaxDepth int - - // DisableMethods specifies whether or not error and Stringer interfaces are - // invoked for types that implement them. - DisableMethods bool - - // DisablePointerMethods specifies whether or not to check for and invoke - // error and Stringer interfaces on types which only accept a pointer - // receiver when the current type is not a pointer. - // - // NOTE: This might be an unsafe action since calling one of these methods - // with a pointer receiver could technically mutate the value, however, - // in practice, types which choose to satisify an error or Stringer - // interface with a pointer receiver should not be mutating their state - // inside these interface methods. As a result, this option relies on - // access to the unsafe package, so it will not have any effect when - // running in environments without access to the unsafe package such as - // Google App Engine or with the "safe" build tag specified. - DisablePointerMethods bool - - // DisablePointerAddresses specifies whether to disable the printing of - // pointer addresses. This is useful when diffing data structures in tests. - DisablePointerAddresses bool - - // DisableCapacities specifies whether to disable the printing of capacities - // for arrays, slices, maps and channels. This is useful when diffing - // data structures in tests. - DisableCapacities bool - - // ContinueOnMethod specifies whether or not recursion should continue once - // a custom error or Stringer interface is invoked. The default, false, - // means it will print the results of invoking the custom error or Stringer - // interface and return immediately instead of continuing to recurse into - // the internals of the data type. - // - // NOTE: This flag does not have any effect if method invocation is disabled - // via the DisableMethods or DisablePointerMethods options. - ContinueOnMethod bool - - // SortKeys specifies map keys should be sorted before being printed. Use - // this to have a more deterministic, diffable output. Note that only - // native types (bool, int, uint, floats, uintptr and string) and types - // that support the error or Stringer interfaces (if methods are - // enabled) are supported, with other types sorted according to the - // reflect.Value.String() output which guarantees display stability. - SortKeys bool - - // SpewKeys specifies that, as a last resort attempt, map keys should - // be spewed to strings and sorted by those strings. This is only - // considered if SortKeys is true. - SpewKeys bool -} - -// Config is the active configuration of the top-level functions. -// The configuration can be changed by modifying the contents of spew.Config. -var Config = ConfigState{Indent: " "} - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the formatted string as a value that satisfies error. See NewFormatter -// for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, c.convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, c.convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, c.convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a Formatter interface returned by c.NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, c.convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Print(a ...interface{}) (n int, err error) { - return fmt.Print(c.convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, c.convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Println(a ...interface{}) (n int, err error) { - return fmt.Println(c.convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprint(a ...interface{}) string { - return fmt.Sprint(c.convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, c.convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a Formatter interface returned by c.NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintln(a ...interface{}) string { - return fmt.Sprintln(c.convertArgs(a)...) -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -c.Printf, c.Println, or c.Printf. -*/ -func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(c, v) -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { - fdump(c, w, a...) -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by modifying the public members -of c. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func (c *ConfigState) Dump(a ...interface{}) { - fdump(c, os.Stdout, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func (c *ConfigState) Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(c, &buf, a...) - return buf.String() -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a spew Formatter interface using -// the ConfigState associated with s. -func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = newFormatter(c, arg) - } - return formatters -} - -// NewDefaultConfig returns a ConfigState with the following default settings. -// -// Indent: " " -// MaxDepth: 0 -// DisableMethods: false -// DisablePointerMethods: false -// ContinueOnMethod: false -// SortKeys: false -func NewDefaultConfig() *ConfigState { - return &ConfigState{Indent: " "} -} diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go deleted file mode 100644 index aacaac6f..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/doc.go +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package spew implements a deep pretty printer for Go data structures to aid in -debugging. - -A quick overview of the additional features spew provides over the built-in -printing facilities for Go data types are as follows: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output (only when using - Dump style) - -There are two different approaches spew allows for dumping Go data structures: - - * Dump style which prints with newlines, customizable indentation, - and additional debug information such as types and all pointer addresses - used to indirect to the final value - * A custom Formatter interface that integrates cleanly with the standard fmt - package and replaces %v, %+v, %#v, and %#+v to provide inline printing - similar to the default %v while providing the additional functionality - outlined above and passing unsupported format verbs such as %x and %q - along to fmt - -Quick Start - -This section demonstrates how to quickly get started with spew. See the -sections below for further details on formatting and configuration options. - -To dump a variable with full newlines, indentation, type, and pointer -information use Dump, Fdump, or Sdump: - spew.Dump(myVar1, myVar2, ...) - spew.Fdump(someWriter, myVar1, myVar2, ...) - str := spew.Sdump(myVar1, myVar2, ...) - -Alternatively, if you would prefer to use format strings with a compacted inline -printing style, use the convenience wrappers Printf, Fprintf, etc with -%v (most compact), %+v (adds pointer addresses), %#v (adds types), or -%#+v (adds types and pointer addresses): - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -Configuration Options - -Configuration of spew is handled by fields in the ConfigState type. For -convenience, all of the top-level functions use a global state available -via the spew.Config global. - -It is also possible to create a ConfigState instance that provides methods -equivalent to the top-level functions. This allows concurrent configuration -options. See the ConfigState documentation for more details. - -The following configuration options are available: - * Indent - String to use for each indentation level for Dump functions. - It is a single space by default. A popular alternative is "\t". - - * MaxDepth - Maximum number of levels to descend into nested data structures. - There is no limit by default. - - * DisableMethods - Disables invocation of error and Stringer interface methods. - Method invocation is enabled by default. - - * DisablePointerMethods - Disables invocation of error and Stringer interface methods on types - which only accept pointer receivers from non-pointer variables. - Pointer method invocation is enabled by default. - - * DisablePointerAddresses - DisablePointerAddresses specifies whether to disable the printing of - pointer addresses. This is useful when diffing data structures in tests. - - * DisableCapacities - DisableCapacities specifies whether to disable the printing of - capacities for arrays, slices, maps and channels. This is useful when - diffing data structures in tests. - - * ContinueOnMethod - Enables recursion into types after invoking error and Stringer interface - methods. Recursion after method invocation is disabled by default. - - * SortKeys - Specifies map keys should be sorted before being printed. Use - this to have a more deterministic, diffable output. Note that - only native types (bool, int, uint, floats, uintptr and string) - and types which implement error or Stringer interfaces are - supported with other types sorted according to the - reflect.Value.String() output which guarantees display - stability. Natural map order is used by default. - - * SpewKeys - Specifies that, as a last resort attempt, map keys should be - spewed to strings and sorted by those strings. This is only - considered if SortKeys is true. - -Dump Usage - -Simply call spew.Dump with a list of variables you want to dump: - - spew.Dump(myVar1, myVar2, ...) - -You may also call spew.Fdump if you would prefer to output to an arbitrary -io.Writer. For example, to dump to standard error: - - spew.Fdump(os.Stderr, myVar1, myVar2, ...) - -A third option is to call spew.Sdump to get the formatted output as a string: - - str := spew.Sdump(myVar1, myVar2, ...) - -Sample Dump Output - -See the Dump example for details on the setup of the types and variables being -shown here. - - (main.Foo) { - unexportedField: (*main.Bar)(0xf84002e210)({ - flag: (main.Flag) flagTwo, - data: (uintptr) - }), - ExportedField: (map[interface {}]interface {}) (len=1) { - (string) (len=3) "one": (bool) true - } - } - -Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C -command as shown. - ([]uint8) (len=32 cap=32) { - 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | - 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| - 00000020 31 32 |12| - } - -Custom Formatter - -Spew provides a custom formatter that implements the fmt.Formatter interface -so that it integrates cleanly with standard fmt package printing functions. The -formatter is useful for inline printing of smaller data types similar to the -standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Custom Formatter Usage - -The simplest way to make use of the spew custom formatter is to call one of the -convenience functions such as spew.Printf, spew.Println, or spew.Printf. The -functions have syntax you are most likely already familiar with: - - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Println(myVar, myVar2) - spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -See the Index for the full list convenience functions. - -Sample Formatter Output - -Double pointer to a uint8: - %v: <**>5 - %+v: <**>(0xf8400420d0->0xf8400420c8)5 - %#v: (**uint8)5 - %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 - -Pointer to circular struct with a uint8 field and a pointer to itself: - %v: <*>{1 <*>} - %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} - %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} - %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} - -See the Printf example for details on the setup of variables being shown -here. - -Errors - -Since it is possible for custom Stringer/error interfaces to panic, spew -detects them and handles them internally by printing the panic information -inline with the output. Since spew is intended to provide deep pretty printing -capabilities on structures, it intentionally does not return any errors. -*/ -package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go deleted file mode 100644 index f78d89fc..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/dump.go +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "encoding/hex" - "fmt" - "io" - "os" - "reflect" - "regexp" - "strconv" - "strings" -) - -var ( - // uint8Type is a reflect.Type representing a uint8. It is used to - // convert cgo types to uint8 slices for hexdumping. - uint8Type = reflect.TypeOf(uint8(0)) - - // cCharRE is a regular expression that matches a cgo char. - // It is used to detect character arrays to hexdump them. - cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) - - // cUnsignedCharRE is a regular expression that matches a cgo unsigned - // char. It is used to detect unsigned character arrays to hexdump - // them. - cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) - - // cUint8tCharRE is a regular expression that matches a cgo uint8_t. - // It is used to detect uint8_t arrays to hexdump them. - cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) -) - -// dumpState contains information about the state of a dump operation. -type dumpState struct { - w io.Writer - depth int - pointers map[uintptr]int - ignoreNextType bool - ignoreNextIndent bool - cs *ConfigState -} - -// indent performs indentation according to the depth level and cs.Indent -// option. -func (d *dumpState) indent() { - if d.ignoreNextIndent { - d.ignoreNextIndent = false - return - } - d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) -} - -// unpackValue returns values inside of non-nil interfaces when possible. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - } - return v -} - -// dumpPtr handles formatting of pointers by indirecting them as necessary. -func (d *dumpState) dumpPtr(v reflect.Value) { - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range d.pointers { - if depth >= d.depth { - delete(d.pointers, k) - } - } - - // Keep list of all dereferenced pointers to show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by dereferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := d.pointers[addr]; ok && pd < d.depth { - cycleFound = true - indirects-- - break - } - d.pointers[addr] = d.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type information. - d.w.Write(openParenBytes) - d.w.Write(bytes.Repeat(asteriskBytes, indirects)) - d.w.Write([]byte(ve.Type().String())) - d.w.Write(closeParenBytes) - - // Display pointer information. - if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { - d.w.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - d.w.Write(pointerChainBytes) - } - printHexPtr(d.w, addr) - } - d.w.Write(closeParenBytes) - } - - // Display dereferenced value. - d.w.Write(openParenBytes) - switch { - case nilFound: - d.w.Write(nilAngleBytes) - - case cycleFound: - d.w.Write(circularBytes) - - default: - d.ignoreNextType = true - d.dump(ve) - } - d.w.Write(closeParenBytes) -} - -// dumpSlice handles formatting of arrays and slices. Byte (uint8 under -// reflection) arrays and slices are dumped in hexdump -C fashion. -func (d *dumpState) dumpSlice(v reflect.Value) { - // Determine whether this type should be hex dumped or not. Also, - // for types which should be hexdumped, try to use the underlying data - // first, then fall back to trying to convert them to a uint8 slice. - var buf []uint8 - doConvert := false - doHexDump := false - numEntries := v.Len() - if numEntries > 0 { - vt := v.Index(0).Type() - vts := vt.String() - switch { - // C types that need to be converted. - case cCharRE.MatchString(vts): - fallthrough - case cUnsignedCharRE.MatchString(vts): - fallthrough - case cUint8tCharRE.MatchString(vts): - doConvert = true - - // Try to use existing uint8 slices and fall back to converting - // and copying if that fails. - case vt.Kind() == reflect.Uint8: - // We need an addressable interface to convert the type - // to a byte slice. However, the reflect package won't - // give us an interface on certain things like - // unexported struct fields in order to enforce - // visibility rules. We use unsafe, when available, to - // bypass these restrictions since this package does not - // mutate the values. - vs := v - if !vs.CanInterface() || !vs.CanAddr() { - vs = unsafeReflectValue(vs) - } - if !UnsafeDisabled { - vs = vs.Slice(0, numEntries) - - // Use the existing uint8 slice if it can be - // type asserted. - iface := vs.Interface() - if slice, ok := iface.([]uint8); ok { - buf = slice - doHexDump = true - break - } - } - - // The underlying data needs to be converted if it can't - // be type asserted to a uint8 slice. - doConvert = true - } - - // Copy and convert the underlying type if needed. - if doConvert && vt.ConvertibleTo(uint8Type) { - // Convert and copy each element into a uint8 byte - // slice. - buf = make([]uint8, numEntries) - for i := 0; i < numEntries; i++ { - vv := v.Index(i) - buf[i] = uint8(vv.Convert(uint8Type).Uint()) - } - doHexDump = true - } - } - - // Hexdump the entire slice as needed. - if doHexDump { - indent := strings.Repeat(d.cs.Indent, d.depth) - str := indent + hex.Dump(buf) - str = strings.Replace(str, "\n", "\n"+indent, -1) - str = strings.TrimRight(str, d.cs.Indent) - d.w.Write([]byte(str)) - return - } - - // Recursively call dump for each item. - for i := 0; i < numEntries; i++ { - d.dump(d.unpackValue(v.Index(i))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } -} - -// dump is the main workhorse for dumping a value. It uses the passed reflect -// value to figure out what kind of object we are dealing with and formats it -// appropriately. It is a recursive function, however circular data structures -// are detected and handled properly. -func (d *dumpState) dump(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - d.w.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - d.indent() - d.dumpPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !d.ignoreNextType { - d.indent() - d.w.Write(openParenBytes) - d.w.Write([]byte(v.Type().String())) - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - d.ignoreNextType = false - - // Display length and capacity if the built-in len and cap functions - // work with the value's kind and the len/cap itself is non-zero. - valueLen, valueCap := 0, 0 - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.Chan: - valueLen, valueCap = v.Len(), v.Cap() - case reflect.Map, reflect.String: - valueLen = v.Len() - } - if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { - d.w.Write(openParenBytes) - if valueLen != 0 { - d.w.Write(lenEqualsBytes) - printInt(d.w, int64(valueLen), 10) - } - if !d.cs.DisableCapacities && valueCap != 0 { - if valueLen != 0 { - d.w.Write(spaceBytes) - } - d.w.Write(capEqualsBytes) - printInt(d.w, int64(valueCap), 10) - } - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - - // Call Stringer/error interfaces if they exist and the handle methods flag - // is enabled - if !d.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(d.cs, d.w, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(d.w, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(d.w, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(d.w, v.Uint(), 10) - - case reflect.Float32: - printFloat(d.w, v.Float(), 32) - - case reflect.Float64: - printFloat(d.w, v.Float(), 64) - - case reflect.Complex64: - printComplex(d.w, v.Complex(), 32) - - case reflect.Complex128: - printComplex(d.w, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - d.dumpSlice(v) - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.String: - d.w.Write([]byte(strconv.Quote(v.String()))) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - d.w.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - numEntries := v.Len() - keys := v.MapKeys() - if d.cs.SortKeys { - sortValues(keys, d.cs) - } - for i, key := range keys { - d.dump(d.unpackValue(key)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.MapIndex(key))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Struct: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - vt := v.Type() - numFields := v.NumField() - for i := 0; i < numFields; i++ { - d.indent() - vtf := vt.Field(i) - d.w.Write([]byte(vtf.Name)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.Field(i))) - if i < (numFields - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(d.w, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(d.w, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it in case any new - // types are added. - default: - if v.CanInterface() { - fmt.Fprintf(d.w, "%v", v.Interface()) - } else { - fmt.Fprintf(d.w, "%v", v.String()) - } - } -} - -// fdump is a helper function to consolidate the logic from the various public -// methods which take varying writers and config states. -func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { - for _, arg := range a { - if arg == nil { - w.Write(interfaceBytes) - w.Write(spaceBytes) - w.Write(nilAngleBytes) - w.Write(newlineBytes) - continue - } - - d := dumpState{w: w, cs: cs} - d.pointers = make(map[uintptr]int) - d.dump(reflect.ValueOf(arg)) - d.w.Write(newlineBytes) - } -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func Fdump(w io.Writer, a ...interface{}) { - fdump(&Config, w, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(&Config, &buf, a...) - return buf.String() -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by an exported package global, -spew.Config. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func Dump(a ...interface{}) { - fdump(&Config, os.Stdout, a...) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go deleted file mode 100644 index b04edb7d..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/format.go +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" -) - -// supportedFlags is a list of all the character flags supported by fmt package. -const supportedFlags = "0-+# " - -// formatState implements the fmt.Formatter interface and contains information -// about the state of a formatting operation. The NewFormatter function can -// be used to get a new Formatter which can be used directly as arguments -// in standard fmt package printing calls. -type formatState struct { - value interface{} - fs fmt.State - depth int - pointers map[uintptr]int - ignoreNextType bool - cs *ConfigState -} - -// buildDefaultFormat recreates the original format string without precision -// and width information to pass in to fmt.Sprintf in the case of an -// unrecognized type. Unless new types are added to the language, this -// function won't ever be called. -func (f *formatState) buildDefaultFormat() (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - buf.WriteRune('v') - - format = buf.String() - return format -} - -// constructOrigFormat recreates the original format string including precision -// and width information to pass along to the standard fmt package. This allows -// automatic deferral of all format strings this package doesn't support. -func (f *formatState) constructOrigFormat(verb rune) (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - if width, ok := f.fs.Width(); ok { - buf.WriteString(strconv.Itoa(width)) - } - - if precision, ok := f.fs.Precision(); ok { - buf.Write(precisionBytes) - buf.WriteString(strconv.Itoa(precision)) - } - - buf.WriteRune(verb) - - format = buf.String() - return format -} - -// unpackValue returns values inside of non-nil interfaces when possible and -// ensures that types for values which have been unpacked from an interface -// are displayed when the show types flag is also set. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (f *formatState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface { - f.ignoreNextType = false - if !v.IsNil() { - v = v.Elem() - } - } - return v -} - -// formatPtr handles formatting of pointers by indirecting them as necessary. -func (f *formatState) formatPtr(v reflect.Value) { - // Display nil if top level pointer is nil. - showTypes := f.fs.Flag('#') - if v.IsNil() && (!showTypes || f.ignoreNextType) { - f.fs.Write(nilAngleBytes) - return - } - - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range f.pointers { - if depth >= f.depth { - delete(f.pointers, k) - } - } - - // Keep list of all dereferenced pointers to possibly show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by derferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := f.pointers[addr]; ok && pd < f.depth { - cycleFound = true - indirects-- - break - } - f.pointers[addr] = f.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type or indirection level depending on flags. - if showTypes && !f.ignoreNextType { - f.fs.Write(openParenBytes) - f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) - f.fs.Write([]byte(ve.Type().String())) - f.fs.Write(closeParenBytes) - } else { - if nilFound || cycleFound { - indirects += strings.Count(ve.Type().String(), "*") - } - f.fs.Write(openAngleBytes) - f.fs.Write([]byte(strings.Repeat("*", indirects))) - f.fs.Write(closeAngleBytes) - } - - // Display pointer information depending on flags. - if f.fs.Flag('+') && (len(pointerChain) > 0) { - f.fs.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - f.fs.Write(pointerChainBytes) - } - printHexPtr(f.fs, addr) - } - f.fs.Write(closeParenBytes) - } - - // Display dereferenced value. - switch { - case nilFound: - f.fs.Write(nilAngleBytes) - - case cycleFound: - f.fs.Write(circularShortBytes) - - default: - f.ignoreNextType = true - f.format(ve) - } -} - -// format is the main workhorse for providing the Formatter interface. It -// uses the passed reflect value to figure out what kind of object we are -// dealing with and formats it appropriately. It is a recursive function, -// however circular data structures are detected and handled properly. -func (f *formatState) format(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - f.fs.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - f.formatPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !f.ignoreNextType && f.fs.Flag('#') { - f.fs.Write(openParenBytes) - f.fs.Write([]byte(v.Type().String())) - f.fs.Write(closeParenBytes) - } - f.ignoreNextType = false - - // Call Stringer/error interfaces if they exist and the handle methods - // flag is enabled. - if !f.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(f.cs, f.fs, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(f.fs, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(f.fs, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(f.fs, v.Uint(), 10) - - case reflect.Float32: - printFloat(f.fs, v.Float(), 32) - - case reflect.Float64: - printFloat(f.fs, v.Float(), 64) - - case reflect.Complex64: - printComplex(f.fs, v.Complex(), 32) - - case reflect.Complex128: - printComplex(f.fs, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - f.fs.Write(openBracketBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - numEntries := v.Len() - for i := 0; i < numEntries; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(v.Index(i))) - } - } - f.depth-- - f.fs.Write(closeBracketBytes) - - case reflect.String: - f.fs.Write([]byte(v.String())) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - f.fs.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - - f.fs.Write(openMapBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - keys := v.MapKeys() - if f.cs.SortKeys { - sortValues(keys, f.cs) - } - for i, key := range keys { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(key)) - f.fs.Write(colonBytes) - f.ignoreNextType = true - f.format(f.unpackValue(v.MapIndex(key))) - } - } - f.depth-- - f.fs.Write(closeMapBytes) - - case reflect.Struct: - numFields := v.NumField() - f.fs.Write(openBraceBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - vt := v.Type() - for i := 0; i < numFields; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - vtf := vt.Field(i) - if f.fs.Flag('+') || f.fs.Flag('#') { - f.fs.Write([]byte(vtf.Name)) - f.fs.Write(colonBytes) - } - f.format(f.unpackValue(v.Field(i))) - } - } - f.depth-- - f.fs.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(f.fs, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(f.fs, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it if any get added. - default: - format := f.buildDefaultFormat() - if v.CanInterface() { - fmt.Fprintf(f.fs, format, v.Interface()) - } else { - fmt.Fprintf(f.fs, format, v.String()) - } - } -} - -// Format satisfies the fmt.Formatter interface. See NewFormatter for usage -// details. -func (f *formatState) Format(fs fmt.State, verb rune) { - f.fs = fs - - // Use standard formatting for verbs that are not v. - if verb != 'v' { - format := f.constructOrigFormat(verb) - fmt.Fprintf(fs, format, f.value) - return - } - - if f.value == nil { - if fs.Flag('#') { - fs.Write(interfaceBytes) - } - fs.Write(nilAngleBytes) - return - } - - f.format(reflect.ValueOf(f.value)) -} - -// newFormatter is a helper function to consolidate the logic from the various -// public methods which take varying config states. -func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { - fs := &formatState{value: v, cs: cs} - fs.pointers = make(map[uintptr]int) - return fs -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -Printf, Println, or Fprintf. -*/ -func NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(&Config, v) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go deleted file mode 100644 index 32c0e338..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/spew.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "fmt" - "io" -) - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the formatted string as a value that satisfies error. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a default Formatter interface returned by NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) -func Print(a ...interface{}) (n int, err error) { - return fmt.Print(convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) -func Println(a ...interface{}) (n int, err error) { - return fmt.Println(convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprint(a ...interface{}) string { - return fmt.Sprint(convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintln(a ...interface{}) string { - return fmt.Sprintln(convertArgs(a)...) -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a default spew Formatter interface. -func convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = NewFormatter(arg) - } - return formatters -} diff --git a/vendor/github.com/emicklei/go-restful/v3/.gitignore b/vendor/github.com/emicklei/go-restful/v3/.gitignore deleted file mode 100644 index 446be09b..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/.gitignore +++ /dev/null @@ -1,71 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe - -restful.html - -*.out - -tmp.prof - -go-restful.test - -examples/restful-basic-authentication - -examples/restful-encoding-filter - -examples/restful-filters - -examples/restful-hello-world - -examples/restful-resource-functions - -examples/restful-serve-static - -examples/restful-user-service - -*.DS_Store -examples/restful-user-resource - -examples/restful-multi-containers - -examples/restful-form-handling - -examples/restful-CORS-filter - -examples/restful-options-filter - -examples/restful-curly-router - -examples/restful-cpuprofiler-service - -examples/restful-pre-post-filters - -curly.prof - -examples/restful-NCSA-logging - -examples/restful-html-template - -s.html -restful-path-tail -.idea diff --git a/vendor/github.com/emicklei/go-restful/v3/.goconvey b/vendor/github.com/emicklei/go-restful/v3/.goconvey deleted file mode 100644 index 8485e986..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/.goconvey +++ /dev/null @@ -1 +0,0 @@ -ignore \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/v3/.travis.yml b/vendor/github.com/emicklei/go-restful/v3/.travis.yml deleted file mode 100644 index 3a0bf5ff..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go - -go: - - 1.x - -before_install: - - go test -v - -script: - - go test -race -coverprofile=coverage.txt -covermode=atomic - -after_success: - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md deleted file mode 100644 index 38169cfd..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md +++ /dev/null @@ -1,372 +0,0 @@ -# Change history of go-restful - -## [v3.8.0] - 20221-06-06 - -- use exact matching of allowed domain entries, issue #489 (#493) - - this changes fixes [security] Authorization Bypass Through User-Controlled Key - by changing the behaviour of the AllowedDomains setting in the CORS filter. - To support the previous behaviour, the CORS filter type now has a AllowedDomainFunc - callback mechanism which is called when a simple domain match fails. -- add test and fix for POST without body and Content-type, issue #492 (#496) -- [Minor] Bad practice to have a mix of Receiver types. (#491) - -## [v3.7.2] - 2021-11-24 - -- restored FilterChain (#482 by SVilgelm) - - -## [v3.7.1] - 2021-10-04 - -- fix problem with contentEncodingEnabled setting (#479) - -## [v3.7.0] - 2021-09-24 - -- feat(parameter): adds additional openapi mappings (#478) - -## [v3.6.0] - 2021-09-18 - -- add support for vendor extensions (#477 thx erraggy) - -## [v3.5.2] - 2021-07-14 - -- fix removing absent route from webservice (#472) - -## [v3.5.1] - 2021-04-12 - -- fix handling no match access selected path -- remove obsolete field - -## [v3.5.0] - 2021-04-10 - -- add check for wildcard (#463) in CORS -- add access to Route from Request, issue #459 (#462) - -## [v3.4.0] - 2020-11-10 - -- Added OPTIONS to WebService - -## [v3.3.2] - 2020-01-23 - -- Fixed duplicate compression in dispatch. #449 - - -## [v3.3.1] - 2020-08-31 - -- Added check on writer to prevent compression of response twice. #447 - -## [v3.3.0] - 2020-08-19 - -- Enable content encoding on Handle and ServeHTTP (#446) -- List available representations in 406 body (#437) -- Convert to string using rune() (#443) - -## [v3.2.0] - 2020-06-21 - -- 405 Method Not Allowed must have Allow header (#436) (thx Bracken ) -- add field allowedMethodsWithoutContentType (#424) - -## [v3.1.0] - -- support describing response headers (#426) -- fix openapi examples (#425) - -v3.0.0 - -- fix: use request/response resulting from filter chain -- add Go module - Module consumer should use github.com/emicklei/go-restful/v3 as import path - -v2.10.0 - -- support for Custom Verbs (thanks Vinci Xu <277040271@qq.com>) -- fixed static example (thanks Arthur ) -- simplify code (thanks Christian Muehlhaeuser ) -- added JWT HMAC with SHA-512 authentication code example (thanks Amim Knabben ) - -v2.9.6 - -- small optimization in filter code - -v2.11.1 - -- fix WriteError return value (#415) - -v2.11.0 - -- allow prefix and suffix in path variable expression (#414) - -v2.9.6 - -- support google custome verb (#413) - -v2.9.5 - -- fix panic in Response.WriteError if err == nil - -v2.9.4 - -- fix issue #400 , parsing mime type quality -- Route Builder added option for contentEncodingEnabled (#398) - -v2.9.3 - -- Avoid return of 415 Unsupported Media Type when request body is empty (#396) - -v2.9.2 - -- Reduce allocations in per-request methods to improve performance (#395) - -v2.9.1 - -- Fix issue with default responses and invalid status code 0. (#393) - -v2.9.0 - -- add per Route content encoding setting (overrides container setting) - -v2.8.0 - -- add Request.QueryParameters() -- add json-iterator (via build tag) -- disable vgo module (until log is moved) - -v2.7.1 - -- add vgo module - -v2.6.1 - -- add JSONNewDecoderFunc to allow custom JSON Decoder usage (go 1.10+) - -v2.6.0 - -- Make JSR 311 routing and path param processing consistent -- Adding description to RouteBuilder.Reads() -- Update example for Swagger12 and OpenAPI - -2017-09-13 - -- added route condition functions using `.If(func)` in route building. - -2017-02-16 - -- solved issue #304, make operation names unique - -2017-01-30 - - [IMPORTANT] For swagger users, change your import statement to: - swagger "github.com/emicklei/go-restful-swagger12" - -- moved swagger 1.2 code to go-restful-swagger12 -- created TAG 2.0.0 - -2017-01-27 - -- remove defer request body close -- expose Dispatch for testing filters and Routefunctions -- swagger response model cannot be array -- created TAG 1.0.0 - -2016-12-22 - -- (API change) Remove code related to caching request content. Removes SetCacheReadEntity(doCache bool) - -2016-11-26 - -- Default change! now use CurlyRouter (was RouterJSR311) -- Default change! no more caching of request content -- Default change! do not recover from panics - -2016-09-22 - -- fix the DefaultRequestContentType feature - -2016-02-14 - -- take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response -- add constructors for custom entity accessors for xml and json - -2015-09-27 - -- rename new WriteStatusAnd... to WriteHeaderAnd... for consistency - -2015-09-25 - -- fixed problem with changing Header after WriteHeader (issue 235) - -2015-09-14 - -- changed behavior of WriteHeader (immediate write) and WriteEntity (no status write) -- added support for custom EntityReaderWriters. - -2015-08-06 - -- add support for reading entities from compressed request content -- use sync.Pool for compressors of http response and request body -- add Description to Parameter for documentation in Swagger UI - -2015-03-20 - -- add configurable logging - -2015-03-18 - -- if not specified, the Operation is derived from the Route function - -2015-03-17 - -- expose Parameter creation functions -- make trace logger an interface -- fix OPTIONSFilter -- customize rendering of ServiceError -- JSR311 router now handles wildcards -- add Notes to Route - -2014-11-27 - -- (api add) PrettyPrint per response. (as proposed in #167) - -2014-11-12 - -- (api add) ApiVersion(.) for documentation in Swagger UI - -2014-11-10 - -- (api change) struct fields tagged with "description" show up in Swagger UI - -2014-10-31 - -- (api change) ReturnsError -> Returns -- (api add) RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder -- fix swagger nested structs -- sort Swagger response messages by code - -2014-10-23 - -- (api add) ReturnsError allows you to document Http codes in swagger -- fixed problem with greedy CurlyRouter -- (api add) Access-Control-Max-Age in CORS -- add tracing functionality (injectable) for debugging purposes -- support JSON parse 64bit int -- fix empty parameters for swagger -- WebServicesUrl is now optional for swagger -- fixed duplicate AccessControlAllowOrigin in CORS -- (api change) expose ServeMux in container -- (api add) added AllowedDomains in CORS -- (api add) ParameterNamed for detailed documentation - -2014-04-16 - -- (api add) expose constructor of Request for testing. - -2014-06-27 - -- (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification). -- (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons). - -2014-07-03 - -- (api add) CORS can be configured with a list of allowed domains - -2014-03-12 - -- (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter) - -2014-02-26 - -- (api add) Request now provides information about the matched Route, see method SelectedRoutePath - -2014-02-17 - -- (api change) renamed parameter constants (go-lint checks) - -2014-01-10 - -- (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier - -2014-01-07 - -- (api change) Write* methods in Response now return the error or nil. -- added example of serving HTML from a Go template. -- fixed comparing Allowed headers in CORS (is now case-insensitive) - -2013-11-13 - -- (api add) Response knows how many bytes are written to the response body. - -2013-10-29 - -- (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information. - -2013-10-04 - -- (api add) Response knows what HTTP status has been written -- (api add) Request can have attributes (map of string->interface, also called request-scoped variables - -2013-09-12 - -- (api change) Router interface simplified -- Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths - -2013-08-05 - - add OPTIONS support - - add CORS support - -2013-08-27 - -- fixed some reported issues (see github) -- (api change) deprecated use of WriteError; use WriteErrorString instead - -2014-04-15 - -- (fix) v1.0.1 tag: fix Issue 111: WriteErrorString - -2013-08-08 - -- (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer. -- (api add) the swagger package has be extended to have a UI per container. -- if panic is detected then a small stack trace is printed (thanks to runner-mei) -- (api add) WriteErrorString to Response - -Important API changes: - -- (api remove) package variable DoNotRecover no longer works ; use restful.DefaultContainer.DoNotRecover(true) instead. -- (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead. - - -2013-07-06 - -- (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature. - -2013-06-19 - -- (improve) DoNotRecover option, moved request body closer, improved ReadEntity - -2013-06-03 - -- (api change) removed Dispatcher interface, hide PathExpression -- changed receiver names of type functions to be more idiomatic Go - -2013-06-02 - -- (optimize) Cache the RegExp compilation of Paths. - -2013-05-22 - -- (api add) Added support for request/response filter functions - -2013-05-18 - - -- (api add) Added feature to change the default Http Request Dispatch function (travis cline) -- (api change) Moved Swagger Webservice to swagger package (see example restful-user) - -[2012-11-14 .. 2013-05-18> - -- See https://github.com/emicklei/go-restful/commits - -2012-11-14 - -- Initial commit - - diff --git a/vendor/github.com/emicklei/go-restful/v3/LICENSE b/vendor/github.com/emicklei/go-restful/v3/LICENSE deleted file mode 100644 index ece7ec61..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2012,2013 Ernest Micklei - -MIT License - -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. \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/v3/Makefile b/vendor/github.com/emicklei/go-restful/v3/Makefile deleted file mode 100644 index 16d0b80b..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -all: test - -test: - go vet . - go test -cover -v . - -ex: - find ./examples -type f -name "*.go" | xargs -I {} go build -o /tmp/ignore {} \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md deleted file mode 100644 index 23166d3b..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/README.md +++ /dev/null @@ -1,110 +0,0 @@ -go-restful -========== -package for building REST-style Web Services using Google Go - -[![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful) -[![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful) -[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful) -[![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful) - -- [Code examples use v3](https://github.com/emicklei/go-restful/tree/v3/examples) - -REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping: - -- GET = Retrieve a representation of a resource -- POST = Create if you are sending content to the server to create a subordinate of the specified resource collection, using some server-side algorithm. -- PUT = Create if you are sending the full content of the specified resource (URI). -- PUT = Update if you are updating the full content of the specified resource. -- DELETE = Delete if you are requesting the server to delete the resource -- PATCH = Update partial content of a resource -- OPTIONS = Get information about the communication options for the request URI - -### Usage - -#### Without Go Modules - -All versions up to `v2.*.*` (on the master) are not supporting Go modules. - -``` -import ( - restful "github.com/emicklei/go-restful" -) -``` - -#### Using Go Modules - -As of version `v3.0.0` (on the v3 branch), this package supports Go modules. - -``` -import ( - restful "github.com/emicklei/go-restful/v3" -) -``` - -### Example - -```Go -ws := new(restful.WebService) -ws. - Path("/users"). - Consumes(restful.MIME_XML, restful.MIME_JSON). - Produces(restful.MIME_JSON, restful.MIME_XML) - -ws.Route(ws.GET("/{user-id}").To(u.findUser). - Doc("get a user"). - Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")). - Writes(User{})) -... - -func (u UserResource) findUser(request *restful.Request, response *restful.Response) { - id := request.PathParameter("user-id") - ... -} -``` - -[Full API of a UserResource](https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go) - -### Features - -- Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support -- Configurable router: - - (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*}) - - Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions -- Request API for reading structs from JSON/XML and accessing parameters (path,query,header) -- Response API for writing structs to JSON/XML and setting headers -- Customizable encoding using EntityReaderWriter registration -- Filters for intercepting the request → response flow on Service or Route level -- Request-scoped variables using attributes -- Containers for WebServices on different HTTP endpoints -- Content encoding (gzip,deflate) of request and response payloads -- Automatic responses on OPTIONS (using a filter) -- Automatic CORS request handling (using a filter) -- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi), see [go-restful-swagger12](https://github.com/emicklei/go-restful-swagger12)) -- Panic recovery to produce HTTP 500, customizable using RecoverHandler(...) -- Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...) -- Configurable (trace) logging -- Customizable gzip/deflate readers and writers using CompressorProvider registration - -## How to customize -There are several hooks to customize the behavior of the go-restful package. - -- Router algorithm -- Panic recovery -- JSON decoder -- Trace logging -- Compression -- Encoders for other serializers -- Use [jsoniter](https://github.com/json-iterator/go) by build this package using a tag, e.g. `go build -tags=jsoniter .` - -## Resources - -- [Example programs](./examples) -- [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/) -- [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/) -- [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful) -- [showcase: Zazkia - tcp proxy for testing resiliency](https://github.com/emicklei/zazkia) -- [showcase: Mora - MongoDB REST Api server](https://github.com/emicklei/mora) - -Type ```git shortlog -s``` for a full list of contributors. - -© 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome. diff --git a/vendor/github.com/emicklei/go-restful/v3/SECURITY.md b/vendor/github.com/emicklei/go-restful/v3/SECURITY.md deleted file mode 100644 index 810d3b51..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/SECURITY.md +++ /dev/null @@ -1,13 +0,0 @@ -# Security Policy - -## Supported Versions - -| Version | Supported | -| ------- | ------------------ | -| v3.7.x | :white_check_mark: | -| < v3.0.1 | :x: | - -## Reporting a Vulnerability - -Create an Issue and put the label `[security]` in the title of the issue. -Valid reported security issues are expected to be solved within a week. diff --git a/vendor/github.com/emicklei/go-restful/v3/Srcfile b/vendor/github.com/emicklei/go-restful/v3/Srcfile deleted file mode 100644 index 16fd1868..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/Srcfile +++ /dev/null @@ -1 +0,0 @@ -{"SkipDirs": ["examples"]} diff --git a/vendor/github.com/emicklei/go-restful/v3/bench_test.sh b/vendor/github.com/emicklei/go-restful/v3/bench_test.sh deleted file mode 100644 index 47ffbe4a..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/bench_test.sh +++ /dev/null @@ -1,10 +0,0 @@ -#go test -run=none -file bench_test.go -test.bench . -cpuprofile=bench_test.out - -go test -c -./go-restful.test -test.run=none -test.cpuprofile=tmp.prof -test.bench=BenchmarkMany -./go-restful.test -test.run=none -test.cpuprofile=curly.prof -test.bench=BenchmarkManyCurly - -#go tool pprof go-restful.test tmp.prof -go tool pprof go-restful.test curly.prof - - diff --git a/vendor/github.com/emicklei/go-restful/v3/compress.go b/vendor/github.com/emicklei/go-restful/v3/compress.go deleted file mode 100644 index 1ff239f9..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/compress.go +++ /dev/null @@ -1,127 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bufio" - "compress/gzip" - "compress/zlib" - "errors" - "io" - "net" - "net/http" - "strings" -) - -// OBSOLETE : use restful.DefaultContainer.EnableContentEncoding(true) to change this setting. -var EnableContentEncoding = false - -// CompressingResponseWriter is a http.ResponseWriter that can perform content encoding (gzip and zlib) -type CompressingResponseWriter struct { - writer http.ResponseWriter - compressor io.WriteCloser - encoding string -} - -// Header is part of http.ResponseWriter interface -func (c *CompressingResponseWriter) Header() http.Header { - return c.writer.Header() -} - -// WriteHeader is part of http.ResponseWriter interface -func (c *CompressingResponseWriter) WriteHeader(status int) { - c.writer.WriteHeader(status) -} - -// Write is part of http.ResponseWriter interface -// It is passed through the compressor -func (c *CompressingResponseWriter) Write(bytes []byte) (int, error) { - if c.isCompressorClosed() { - return -1, errors.New("Compressing error: tried to write data using closed compressor") - } - return c.compressor.Write(bytes) -} - -// CloseNotify is part of http.CloseNotifier interface -func (c *CompressingResponseWriter) CloseNotify() <-chan bool { - return c.writer.(http.CloseNotifier).CloseNotify() -} - -// Close the underlying compressor -func (c *CompressingResponseWriter) Close() error { - if c.isCompressorClosed() { - return errors.New("Compressing error: tried to close already closed compressor") - } - - c.compressor.Close() - if ENCODING_GZIP == c.encoding { - currentCompressorProvider.ReleaseGzipWriter(c.compressor.(*gzip.Writer)) - } - if ENCODING_DEFLATE == c.encoding { - currentCompressorProvider.ReleaseZlibWriter(c.compressor.(*zlib.Writer)) - } - // gc hint needed? - c.compressor = nil - return nil -} - -func (c *CompressingResponseWriter) isCompressorClosed() bool { - return nil == c.compressor -} - -// Hijack implements the Hijacker interface -// This is especially useful when combining Container.EnabledContentEncoding -// in combination with websockets (for instance gorilla/websocket) -func (c *CompressingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { - hijacker, ok := c.writer.(http.Hijacker) - if !ok { - return nil, nil, errors.New("ResponseWriter doesn't support Hijacker interface") - } - return hijacker.Hijack() -} - -// WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested. -// It also inspects the httpWriter whether its content-encoding is already set (non-empty). -func wantsCompressedResponse(httpRequest *http.Request, httpWriter http.ResponseWriter) (bool, string) { - if contentEncoding := httpWriter.Header().Get(HEADER_ContentEncoding); contentEncoding != "" { - return false, "" - } - header := httpRequest.Header.Get(HEADER_AcceptEncoding) - gi := strings.Index(header, ENCODING_GZIP) - zi := strings.Index(header, ENCODING_DEFLATE) - // use in order of appearance - if gi == -1 { - return zi != -1, ENCODING_DEFLATE - } else if zi == -1 { - return gi != -1, ENCODING_GZIP - } else { - if gi < zi { - return true, ENCODING_GZIP - } - return true, ENCODING_DEFLATE - } -} - -// NewCompressingResponseWriter create a CompressingResponseWriter for a known encoding = {gzip,deflate} -func NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding string) (*CompressingResponseWriter, error) { - httpWriter.Header().Set(HEADER_ContentEncoding, encoding) - c := new(CompressingResponseWriter) - c.writer = httpWriter - var err error - if ENCODING_GZIP == encoding { - w := currentCompressorProvider.AcquireGzipWriter() - w.Reset(httpWriter) - c.compressor = w - c.encoding = ENCODING_GZIP - } else if ENCODING_DEFLATE == encoding { - w := currentCompressorProvider.AcquireZlibWriter() - w.Reset(httpWriter) - c.compressor = w - c.encoding = ENCODING_DEFLATE - } else { - return nil, errors.New("Unknown encoding:" + encoding) - } - return c, err -} diff --git a/vendor/github.com/emicklei/go-restful/v3/compressor_cache.go b/vendor/github.com/emicklei/go-restful/v3/compressor_cache.go deleted file mode 100644 index ee426010..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/compressor_cache.go +++ /dev/null @@ -1,103 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "compress/gzip" - "compress/zlib" -) - -// BoundedCachedCompressors is a CompressorProvider that uses a cache with a fixed amount -// of writers and readers (resources). -// If a new resource is acquired and all are in use, it will return a new unmanaged resource. -type BoundedCachedCompressors struct { - gzipWriters chan *gzip.Writer - gzipReaders chan *gzip.Reader - zlibWriters chan *zlib.Writer - writersCapacity int - readersCapacity int -} - -// NewBoundedCachedCompressors returns a new, with filled cache, BoundedCachedCompressors. -func NewBoundedCachedCompressors(writersCapacity, readersCapacity int) *BoundedCachedCompressors { - b := &BoundedCachedCompressors{ - gzipWriters: make(chan *gzip.Writer, writersCapacity), - gzipReaders: make(chan *gzip.Reader, readersCapacity), - zlibWriters: make(chan *zlib.Writer, writersCapacity), - writersCapacity: writersCapacity, - readersCapacity: readersCapacity, - } - for ix := 0; ix < writersCapacity; ix++ { - b.gzipWriters <- newGzipWriter() - b.zlibWriters <- newZlibWriter() - } - for ix := 0; ix < readersCapacity; ix++ { - b.gzipReaders <- newGzipReader() - } - return b -} - -// AcquireGzipWriter returns an resettable *gzip.Writer. Needs to be released. -func (b *BoundedCachedCompressors) AcquireGzipWriter() *gzip.Writer { - var writer *gzip.Writer - select { - case writer, _ = <-b.gzipWriters: - default: - // return a new unmanaged one - writer = newGzipWriter() - } - return writer -} - -// ReleaseGzipWriter accepts a writer (does not have to be one that was cached) -// only when the cache has room for it. It will ignore it otherwise. -func (b *BoundedCachedCompressors) ReleaseGzipWriter(w *gzip.Writer) { - // forget the unmanaged ones - if len(b.gzipWriters) < b.writersCapacity { - b.gzipWriters <- w - } -} - -// AcquireGzipReader returns a *gzip.Reader. Needs to be released. -func (b *BoundedCachedCompressors) AcquireGzipReader() *gzip.Reader { - var reader *gzip.Reader - select { - case reader, _ = <-b.gzipReaders: - default: - // return a new unmanaged one - reader = newGzipReader() - } - return reader -} - -// ReleaseGzipReader accepts a reader (does not have to be one that was cached) -// only when the cache has room for it. It will ignore it otherwise. -func (b *BoundedCachedCompressors) ReleaseGzipReader(r *gzip.Reader) { - // forget the unmanaged ones - if len(b.gzipReaders) < b.readersCapacity { - b.gzipReaders <- r - } -} - -// AcquireZlibWriter returns an resettable *zlib.Writer. Needs to be released. -func (b *BoundedCachedCompressors) AcquireZlibWriter() *zlib.Writer { - var writer *zlib.Writer - select { - case writer, _ = <-b.zlibWriters: - default: - // return a new unmanaged one - writer = newZlibWriter() - } - return writer -} - -// ReleaseZlibWriter accepts a writer (does not have to be one that was cached) -// only when the cache has room for it. It will ignore it otherwise. -func (b *BoundedCachedCompressors) ReleaseZlibWriter(w *zlib.Writer) { - // forget the unmanaged ones - if len(b.zlibWriters) < b.writersCapacity { - b.zlibWriters <- w - } -} diff --git a/vendor/github.com/emicklei/go-restful/v3/compressor_pools.go b/vendor/github.com/emicklei/go-restful/v3/compressor_pools.go deleted file mode 100644 index d866ce64..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/compressor_pools.go +++ /dev/null @@ -1,91 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bytes" - "compress/gzip" - "compress/zlib" - "sync" -) - -// SyncPoolCompessors is a CompressorProvider that use the standard sync.Pool. -type SyncPoolCompessors struct { - GzipWriterPool *sync.Pool - GzipReaderPool *sync.Pool - ZlibWriterPool *sync.Pool -} - -// NewSyncPoolCompessors returns a new ("empty") SyncPoolCompessors. -func NewSyncPoolCompessors() *SyncPoolCompessors { - return &SyncPoolCompessors{ - GzipWriterPool: &sync.Pool{ - New: func() interface{} { return newGzipWriter() }, - }, - GzipReaderPool: &sync.Pool{ - New: func() interface{} { return newGzipReader() }, - }, - ZlibWriterPool: &sync.Pool{ - New: func() interface{} { return newZlibWriter() }, - }, - } -} - -func (s *SyncPoolCompessors) AcquireGzipWriter() *gzip.Writer { - return s.GzipWriterPool.Get().(*gzip.Writer) -} - -func (s *SyncPoolCompessors) ReleaseGzipWriter(w *gzip.Writer) { - s.GzipWriterPool.Put(w) -} - -func (s *SyncPoolCompessors) AcquireGzipReader() *gzip.Reader { - return s.GzipReaderPool.Get().(*gzip.Reader) -} - -func (s *SyncPoolCompessors) ReleaseGzipReader(r *gzip.Reader) { - s.GzipReaderPool.Put(r) -} - -func (s *SyncPoolCompessors) AcquireZlibWriter() *zlib.Writer { - return s.ZlibWriterPool.Get().(*zlib.Writer) -} - -func (s *SyncPoolCompessors) ReleaseZlibWriter(w *zlib.Writer) { - s.ZlibWriterPool.Put(w) -} - -func newGzipWriter() *gzip.Writer { - // create with an empty bytes writer; it will be replaced before using the gzipWriter - writer, err := gzip.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed) - if err != nil { - panic(err.Error()) - } - return writer -} - -func newGzipReader() *gzip.Reader { - // create with an empty reader (but with GZIP header); it will be replaced before using the gzipReader - // we can safely use currentCompressProvider because it is set on package initialization. - w := currentCompressorProvider.AcquireGzipWriter() - defer currentCompressorProvider.ReleaseGzipWriter(w) - b := new(bytes.Buffer) - w.Reset(b) - w.Flush() - w.Close() - reader, err := gzip.NewReader(bytes.NewReader(b.Bytes())) - if err != nil { - panic(err.Error()) - } - return reader -} - -func newZlibWriter() *zlib.Writer { - writer, err := zlib.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed) - if err != nil { - panic(err.Error()) - } - return writer -} diff --git a/vendor/github.com/emicklei/go-restful/v3/compressors.go b/vendor/github.com/emicklei/go-restful/v3/compressors.go deleted file mode 100644 index 9db4a8c8..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/compressors.go +++ /dev/null @@ -1,54 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "compress/gzip" - "compress/zlib" -) - -// CompressorProvider describes a component that can provider compressors for the std methods. -type CompressorProvider interface { - // Returns a *gzip.Writer which needs to be released later. - // Before using it, call Reset(). - AcquireGzipWriter() *gzip.Writer - - // Releases an acquired *gzip.Writer. - ReleaseGzipWriter(w *gzip.Writer) - - // Returns a *gzip.Reader which needs to be released later. - AcquireGzipReader() *gzip.Reader - - // Releases an acquired *gzip.Reader. - ReleaseGzipReader(w *gzip.Reader) - - // Returns a *zlib.Writer which needs to be released later. - // Before using it, call Reset(). - AcquireZlibWriter() *zlib.Writer - - // Releases an acquired *zlib.Writer. - ReleaseZlibWriter(w *zlib.Writer) -} - -// DefaultCompressorProvider is the actual provider of compressors (zlib or gzip). -var currentCompressorProvider CompressorProvider - -func init() { - currentCompressorProvider = NewSyncPoolCompessors() -} - -// CurrentCompressorProvider returns the current CompressorProvider. -// It is initialized using a SyncPoolCompessors. -func CurrentCompressorProvider() CompressorProvider { - return currentCompressorProvider -} - -// SetCompressorProvider sets the actual provider of compressors (zlib or gzip). -func SetCompressorProvider(p CompressorProvider) { - if p == nil { - panic("cannot set compressor provider to nil") - } - currentCompressorProvider = p -} diff --git a/vendor/github.com/emicklei/go-restful/v3/constants.go b/vendor/github.com/emicklei/go-restful/v3/constants.go deleted file mode 100644 index 203439c5..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/constants.go +++ /dev/null @@ -1,30 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -const ( - MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces() - MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces() - MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default - - HEADER_Allow = "Allow" - HEADER_Accept = "Accept" - HEADER_Origin = "Origin" - HEADER_ContentType = "Content-Type" - HEADER_LastModified = "Last-Modified" - HEADER_AcceptEncoding = "Accept-Encoding" - HEADER_ContentEncoding = "Content-Encoding" - HEADER_AccessControlExposeHeaders = "Access-Control-Expose-Headers" - HEADER_AccessControlRequestMethod = "Access-Control-Request-Method" - HEADER_AccessControlRequestHeaders = "Access-Control-Request-Headers" - HEADER_AccessControlAllowMethods = "Access-Control-Allow-Methods" - HEADER_AccessControlAllowOrigin = "Access-Control-Allow-Origin" - HEADER_AccessControlAllowCredentials = "Access-Control-Allow-Credentials" - HEADER_AccessControlAllowHeaders = "Access-Control-Allow-Headers" - HEADER_AccessControlMaxAge = "Access-Control-Max-Age" - - ENCODING_GZIP = "gzip" - ENCODING_DEFLATE = "deflate" -) diff --git a/vendor/github.com/emicklei/go-restful/v3/container.go b/vendor/github.com/emicklei/go-restful/v3/container.go deleted file mode 100644 index dd56246d..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/container.go +++ /dev/null @@ -1,450 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bytes" - "errors" - "fmt" - "net/http" - "os" - "runtime" - "strings" - "sync" - - "github.com/emicklei/go-restful/v3/log" -) - -// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests. -// The requests are further dispatched to routes of WebServices using a RouteSelector -type Container struct { - webServicesLock sync.RWMutex - webServices []*WebService - ServeMux *http.ServeMux - isRegisteredOnRoot bool - containerFilters []FilterFunction - doNotRecover bool // default is true - recoverHandleFunc RecoverHandleFunction - serviceErrorHandleFunc ServiceErrorHandleFunction - router RouteSelector // default is a CurlyRouter (RouterJSR311 is a slower alternative) - contentEncodingEnabled bool // default is false -} - -// NewContainer creates a new Container using a new ServeMux and default router (CurlyRouter) -func NewContainer() *Container { - return &Container{ - webServices: []*WebService{}, - ServeMux: http.NewServeMux(), - isRegisteredOnRoot: false, - containerFilters: []FilterFunction{}, - doNotRecover: true, - recoverHandleFunc: logStackOnRecover, - serviceErrorHandleFunc: writeServiceError, - router: CurlyRouter{}, - contentEncodingEnabled: false} -} - -// RecoverHandleFunction declares functions that can be used to handle a panic situation. -// The first argument is what recover() returns. The second must be used to communicate an error response. -type RecoverHandleFunction func(interface{}, http.ResponseWriter) - -// RecoverHandler changes the default function (logStackOnRecover) to be called -// when a panic is detected. DoNotRecover must be have its default value (=false). -func (c *Container) RecoverHandler(handler RecoverHandleFunction) { - c.recoverHandleFunc = handler -} - -// ServiceErrorHandleFunction declares functions that can be used to handle a service error situation. -// The first argument is the service error, the second is the request that resulted in the error and -// the third must be used to communicate an error response. -type ServiceErrorHandleFunction func(ServiceError, *Request, *Response) - -// ServiceErrorHandler changes the default function (writeServiceError) to be called -// when a ServiceError is detected. -func (c *Container) ServiceErrorHandler(handler ServiceErrorHandleFunction) { - c.serviceErrorHandleFunc = handler -} - -// DoNotRecover controls whether panics will be caught to return HTTP 500. -// If set to true, Route functions are responsible for handling any error situation. -// Default value is true. -func (c *Container) DoNotRecover(doNot bool) { - c.doNotRecover = doNot -} - -// Router changes the default Router (currently CurlyRouter) -func (c *Container) Router(aRouter RouteSelector) { - c.router = aRouter -} - -// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses. -func (c *Container) EnableContentEncoding(enabled bool) { - c.contentEncodingEnabled = enabled -} - -// Add a WebService to the Container. It will detect duplicate root paths and exit in that case. -func (c *Container) Add(service *WebService) *Container { - c.webServicesLock.Lock() - defer c.webServicesLock.Unlock() - - // if rootPath was not set then lazy initialize it - if len(service.rootPath) == 0 { - service.Path("/") - } - - // cannot have duplicate root paths - for _, each := range c.webServices { - if each.RootPath() == service.RootPath() { - log.Printf("WebService with duplicate root path detected:['%v']", each) - os.Exit(1) - } - } - - // If not registered on root then add specific mapping - if !c.isRegisteredOnRoot { - c.isRegisteredOnRoot = c.addHandler(service, c.ServeMux) - } - c.webServices = append(c.webServices, service) - return c -} - -// addHandler may set a new HandleFunc for the serveMux -// this function must run inside the critical region protected by the webServicesLock. -// returns true if the function was registered on root ("/") -func (c *Container) addHandler(service *WebService, serveMux *http.ServeMux) bool { - pattern := fixedPrefixPath(service.RootPath()) - // check if root path registration is needed - if "/" == pattern || "" == pattern { - serveMux.HandleFunc("/", c.dispatch) - return true - } - // detect if registration already exists - alreadyMapped := false - for _, each := range c.webServices { - if each.RootPath() == service.RootPath() { - alreadyMapped = true - break - } - } - if !alreadyMapped { - serveMux.HandleFunc(pattern, c.dispatch) - if !strings.HasSuffix(pattern, "/") { - serveMux.HandleFunc(pattern+"/", c.dispatch) - } - } - return false -} - -func (c *Container) Remove(ws *WebService) error { - if c.ServeMux == http.DefaultServeMux { - errMsg := fmt.Sprintf("cannot remove a WebService from a Container using the DefaultServeMux: ['%v']", ws) - log.Print(errMsg) - return errors.New(errMsg) - } - c.webServicesLock.Lock() - defer c.webServicesLock.Unlock() - // build a new ServeMux and re-register all WebServices - newServeMux := http.NewServeMux() - newServices := []*WebService{} - newIsRegisteredOnRoot := false - for _, each := range c.webServices { - if each.rootPath != ws.rootPath { - // If not registered on root then add specific mapping - if !newIsRegisteredOnRoot { - newIsRegisteredOnRoot = c.addHandler(each, newServeMux) - } - newServices = append(newServices, each) - } - } - c.webServices, c.ServeMux, c.isRegisteredOnRoot = newServices, newServeMux, newIsRegisteredOnRoot - return nil -} - -// logStackOnRecover is the default RecoverHandleFunction and is called -// when DoNotRecover is false and the recoverHandleFunc is not set for the container. -// Default implementation logs the stacktrace and writes the stacktrace on the response. -// This may be a security issue as it exposes sourcecode information. -func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) { - var buffer bytes.Buffer - buffer.WriteString(fmt.Sprintf("recover from panic situation: - %v\r\n", panicReason)) - for i := 2; ; i += 1 { - _, file, line, ok := runtime.Caller(i) - if !ok { - break - } - buffer.WriteString(fmt.Sprintf(" %s:%d\r\n", file, line)) - } - log.Print(buffer.String()) - httpWriter.WriteHeader(http.StatusInternalServerError) - httpWriter.Write(buffer.Bytes()) -} - -// writeServiceError is the default ServiceErrorHandleFunction and is called -// when a ServiceError is returned during route selection. Default implementation -// calls resp.WriteErrorString(err.Code, err.Message) -func writeServiceError(err ServiceError, req *Request, resp *Response) { - for header, values := range err.Header { - for _, value := range values { - resp.Header().Add(header, value) - } - } - resp.WriteErrorString(err.Code, err.Message) -} - -// Dispatch the incoming Http Request to a matching WebService. -func (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { - if httpWriter == nil { - panic("httpWriter cannot be nil") - } - if httpRequest == nil { - panic("httpRequest cannot be nil") - } - c.dispatch(httpWriter, httpRequest) -} - -// Dispatch the incoming Http Request to a matching WebService. -func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) { - // so we can assign a compressing one later - writer := httpWriter - - // CompressingResponseWriter should be closed after all operations are done - defer func() { - if compressWriter, ok := writer.(*CompressingResponseWriter); ok { - compressWriter.Close() - } - }() - - // Instal panic recovery unless told otherwise - if !c.doNotRecover { // catch all for 500 response - defer func() { - if r := recover(); r != nil { - c.recoverHandleFunc(r, writer) - return - } - }() - } - - // Find best match Route ; err is non nil if no match was found - var webService *WebService - var route *Route - var err error - func() { - c.webServicesLock.RLock() - defer c.webServicesLock.RUnlock() - webService, route, err = c.router.SelectRoute( - c.webServices, - httpRequest) - }() - if err != nil { - // a non-200 response (may be compressed) has already been written - // run container filters anyway ; they should not touch the response... - chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { - switch err.(type) { - case ServiceError: - ser := err.(ServiceError) - c.serviceErrorHandleFunc(ser, req, resp) - } - // TODO - }} - chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer)) - return - } - - // Unless httpWriter is already an CompressingResponseWriter see if we need to install one - if _, isCompressing := httpWriter.(*CompressingResponseWriter); !isCompressing { - // Detect if compression is needed - // assume without compression, test for override - contentEncodingEnabled := c.contentEncodingEnabled - if route != nil && route.contentEncodingEnabled != nil { - contentEncodingEnabled = *route.contentEncodingEnabled - } - if contentEncodingEnabled { - doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - } - } - - pathProcessor, routerProcessesPath := c.router.(PathProcessor) - if !routerProcessesPath { - pathProcessor = defaultPathProcessor{} - } - pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path) - wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams) - // pass through filters (if any) - if size := len(c.containerFilters) + len(webService.filters) + len(route.Filters); size > 0 { - // compose filter chain - allFilters := make([]FilterFunction, 0, size) - allFilters = append(allFilters, c.containerFilters...) - allFilters = append(allFilters, webService.filters...) - allFilters = append(allFilters, route.Filters...) - chain := FilterChain{ - Filters: allFilters, - Target: route.Function, - ParameterDocs: route.ParameterDocs, - Operation: route.Operation, - } - chain.ProcessFilter(wrappedRequest, wrappedResponse) - } else { - // no filters, handle request by route - route.Function(wrappedRequest, wrappedResponse) - } -} - -// fixedPrefixPath returns the fixed part of the partspec ; it may include template vars {} -func fixedPrefixPath(pathspec string) string { - varBegin := strings.Index(pathspec, "{") - if -1 == varBegin { - return pathspec - } - return pathspec[:varBegin] -} - -// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server -func (c *Container) ServeHTTP(httpWriter http.ResponseWriter, httpRequest *http.Request) { - // Skip, if content encoding is disabled - if !c.contentEncodingEnabled { - c.ServeMux.ServeHTTP(httpWriter, httpRequest) - return - } - // content encoding is enabled - - // Skip, if httpWriter is already an CompressingResponseWriter - if _, ok := httpWriter.(*CompressingResponseWriter); ok { - c.ServeMux.ServeHTTP(httpWriter, httpRequest) - return - } - - writer := httpWriter - // CompressingResponseWriter should be closed after all operations are done - defer func() { - if compressWriter, ok := writer.(*CompressingResponseWriter); ok { - compressWriter.Close() - } - }() - - doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - - c.ServeMux.ServeHTTP(writer, httpRequest) -} - -// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics. -func (c *Container) Handle(pattern string, handler http.Handler) { - c.ServeMux.Handle(pattern, http.HandlerFunc(func(httpWriter http.ResponseWriter, httpRequest *http.Request) { - // Skip, if httpWriter is already an CompressingResponseWriter - if _, ok := httpWriter.(*CompressingResponseWriter); ok { - handler.ServeHTTP(httpWriter, httpRequest) - return - } - - writer := httpWriter - - // CompressingResponseWriter should be closed after all operations are done - defer func() { - if compressWriter, ok := writer.(*CompressingResponseWriter); ok { - compressWriter.Close() - } - }() - - if c.contentEncodingEnabled { - doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter) - if doCompress { - var err error - writer, err = NewCompressingResponseWriter(httpWriter, encoding) - if err != nil { - log.Print("unable to install compressor: ", err) - httpWriter.WriteHeader(http.StatusInternalServerError) - return - } - } - } - - handler.ServeHTTP(writer, httpRequest) - })) -} - -// HandleWithFilter registers the handler for the given pattern. -// Container's filter chain is applied for handler. -// If a handler already exists for pattern, HandleWithFilter panics. -func (c *Container) HandleWithFilter(pattern string, handler http.Handler) { - f := func(httpResponse http.ResponseWriter, httpRequest *http.Request) { - if len(c.containerFilters) == 0 { - handler.ServeHTTP(httpResponse, httpRequest) - return - } - - chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) { - handler.ServeHTTP(resp, req.Request) - }} - chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse)) - } - - c.Handle(pattern, http.HandlerFunc(f)) -} - -// Filter appends a container FilterFunction. These are called before dispatching -// a http.Request to a WebService from the container -func (c *Container) Filter(filter FilterFunction) { - c.containerFilters = append(c.containerFilters, filter) -} - -// RegisteredWebServices returns the collections of added WebServices -func (c *Container) RegisteredWebServices() []*WebService { - c.webServicesLock.RLock() - defer c.webServicesLock.RUnlock() - result := make([]*WebService, len(c.webServices)) - for ix := range c.webServices { - result[ix] = c.webServices[ix] - } - return result -} - -// computeAllowedMethods returns a list of HTTP methods that are valid for a Request -func (c *Container) computeAllowedMethods(req *Request) []string { - // Go through all RegisteredWebServices() and all its Routes to collect the options - methods := []string{} - requestPath := req.Request.URL.Path - for _, ws := range c.RegisteredWebServices() { - matches := ws.pathExpr.Matcher.FindStringSubmatch(requestPath) - if matches != nil { - finalMatch := matches[len(matches)-1] - for _, rt := range ws.Routes() { - matches := rt.pathExpr.Matcher.FindStringSubmatch(finalMatch) - if matches != nil { - lastMatch := matches[len(matches)-1] - if lastMatch == "" || lastMatch == "/" { // do not include if value is neither empty nor ‘/’. - methods = append(methods, rt.Method) - } - } - } - } - } - // methods = append(methods, "OPTIONS") not sure about this - return methods -} - -// newBasicRequestResponse creates a pair of Request,Response from its http versions. -// It is basic because no parameter or (produces) content-type information is given. -func newBasicRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request) (*Request, *Response) { - resp := NewResponse(httpWriter) - resp.requestAccept = httpRequest.Header.Get(HEADER_Accept) - return NewRequest(httpRequest), resp -} diff --git a/vendor/github.com/emicklei/go-restful/v3/cors_filter.go b/vendor/github.com/emicklei/go-restful/v3/cors_filter.go deleted file mode 100644 index 9d18dfb7..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/cors_filter.go +++ /dev/null @@ -1,193 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "regexp" - "strconv" - "strings" -) - -// CrossOriginResourceSharing is used to create a Container Filter that implements CORS. -// Cross-origin resource sharing (CORS) is a mechanism that allows JavaScript on a web page -// to make XMLHttpRequests to another domain, not the domain the JavaScript originated from. -// -// http://en.wikipedia.org/wiki/Cross-origin_resource_sharing -// http://enable-cors.org/server.html -// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request -type CrossOriginResourceSharing struct { - ExposeHeaders []string // list of Header names - - // AllowedHeaders is alist of Header names. Checking is case-insensitive. - // The list may contain the special wildcard string ".*" ; all is allowed - AllowedHeaders []string - - // AllowedDomains is a list of allowed values for Http Origin. - // The list may contain the special wildcard string ".*" ; all is allowed - // If empty all are allowed. - AllowedDomains []string - - // AllowedDomainFunc is optional and is a function that will do the check - // when the origin is not part of the AllowedDomains and it does not contain the wildcard ".*". - AllowedDomainFunc func(origin string) bool - - // AllowedMethods is either empty or has a list of http methods names. Checking is case-insensitive. - AllowedMethods []string - MaxAge int // number of seconds before requiring new Options request - CookiesAllowed bool - Container *Container - - allowedOriginPatterns []*regexp.Regexp // internal field for origin regexp check. -} - -// Filter is a filter function that implements the CORS flow as documented on http://enable-cors.org/server.html -// and http://www.html5rocks.com/static/images/cors_server_flowchart.png -func (c CrossOriginResourceSharing) Filter(req *Request, resp *Response, chain *FilterChain) { - origin := req.Request.Header.Get(HEADER_Origin) - if len(origin) == 0 { - if trace { - traceLogger.Print("no Http header Origin set") - } - chain.ProcessFilter(req, resp) - return - } - if !c.isOriginAllowed(origin) { // check whether this origin is allowed - if trace { - traceLogger.Printf("HTTP Origin:%s is not part of %v, neither matches any part of %v", origin, c.AllowedDomains, c.allowedOriginPatterns) - } - chain.ProcessFilter(req, resp) - return - } - if req.Request.Method != "OPTIONS" { - c.doActualRequest(req, resp) - chain.ProcessFilter(req, resp) - return - } - if acrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod); acrm != "" { - c.doPreflightRequest(req, resp) - } else { - c.doActualRequest(req, resp) - chain.ProcessFilter(req, resp) - return - } -} - -func (c CrossOriginResourceSharing) doActualRequest(req *Request, resp *Response) { - c.setOptionsHeaders(req, resp) - // continue processing the response -} - -func (c *CrossOriginResourceSharing) doPreflightRequest(req *Request, resp *Response) { - if len(c.AllowedMethods) == 0 { - if c.Container == nil { - c.AllowedMethods = DefaultContainer.computeAllowedMethods(req) - } else { - c.AllowedMethods = c.Container.computeAllowedMethods(req) - } - } - - acrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod) - if !c.isValidAccessControlRequestMethod(acrm, c.AllowedMethods) { - if trace { - traceLogger.Printf("Http header %s:%s is not in %v", - HEADER_AccessControlRequestMethod, - acrm, - c.AllowedMethods) - } - return - } - acrhs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders) - if len(acrhs) > 0 { - for _, each := range strings.Split(acrhs, ",") { - if !c.isValidAccessControlRequestHeader(strings.Trim(each, " ")) { - if trace { - traceLogger.Printf("Http header %s:%s is not in %v", - HEADER_AccessControlRequestHeaders, - acrhs, - c.AllowedHeaders) - } - return - } - } - } - resp.AddHeader(HEADER_AccessControlAllowMethods, strings.Join(c.AllowedMethods, ",")) - resp.AddHeader(HEADER_AccessControlAllowHeaders, acrhs) - c.setOptionsHeaders(req, resp) - - // return http 200 response, no body -} - -func (c CrossOriginResourceSharing) setOptionsHeaders(req *Request, resp *Response) { - c.checkAndSetExposeHeaders(resp) - c.setAllowOriginHeader(req, resp) - c.checkAndSetAllowCredentials(resp) - if c.MaxAge > 0 { - resp.AddHeader(HEADER_AccessControlMaxAge, strconv.Itoa(c.MaxAge)) - } -} - -func (c CrossOriginResourceSharing) isOriginAllowed(origin string) bool { - if len(origin) == 0 { - return false - } - lowerOrigin := strings.ToLower(origin) - if len(c.AllowedDomains) == 0 { - if c.AllowedDomainFunc != nil { - return c.AllowedDomainFunc(lowerOrigin) - } - return true - } - - // exact match on each allowed domain - for _, domain := range c.AllowedDomains { - if domain == ".*" || strings.ToLower(domain) == lowerOrigin { - return true - } - } - if c.AllowedDomainFunc != nil { - return c.AllowedDomainFunc(origin) - } - return false -} - -func (c CrossOriginResourceSharing) setAllowOriginHeader(req *Request, resp *Response) { - origin := req.Request.Header.Get(HEADER_Origin) - if c.isOriginAllowed(origin) { - resp.AddHeader(HEADER_AccessControlAllowOrigin, origin) - } -} - -func (c CrossOriginResourceSharing) checkAndSetExposeHeaders(resp *Response) { - if len(c.ExposeHeaders) > 0 { - resp.AddHeader(HEADER_AccessControlExposeHeaders, strings.Join(c.ExposeHeaders, ",")) - } -} - -func (c CrossOriginResourceSharing) checkAndSetAllowCredentials(resp *Response) { - if c.CookiesAllowed { - resp.AddHeader(HEADER_AccessControlAllowCredentials, "true") - } -} - -func (c CrossOriginResourceSharing) isValidAccessControlRequestMethod(method string, allowedMethods []string) bool { - for _, each := range allowedMethods { - if each == method { - return true - } - } - return false -} - -func (c CrossOriginResourceSharing) isValidAccessControlRequestHeader(header string) bool { - for _, each := range c.AllowedHeaders { - if strings.ToLower(each) == strings.ToLower(header) { - return true - } - if each == "*" { - return true - } - } - return false -} diff --git a/vendor/github.com/emicklei/go-restful/v3/coverage.sh b/vendor/github.com/emicklei/go-restful/v3/coverage.sh deleted file mode 100644 index e27dbf1a..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/coverage.sh +++ /dev/null @@ -1,2 +0,0 @@ -go test -coverprofile=coverage.out -go tool cover -html=coverage.out \ No newline at end of file diff --git a/vendor/github.com/emicklei/go-restful/v3/curly.go b/vendor/github.com/emicklei/go-restful/v3/curly.go deleted file mode 100644 index ba1fc5d5..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/curly.go +++ /dev/null @@ -1,173 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "net/http" - "regexp" - "sort" - "strings" -) - -// CurlyRouter expects Routes with paths that contain zero or more parameters in curly brackets. -type CurlyRouter struct{} - -// SelectRoute is part of the Router interface and returns the best match -// for the WebService and its Route for the given Request. -func (c CurlyRouter) SelectRoute( - webServices []*WebService, - httpRequest *http.Request) (selectedService *WebService, selected *Route, err error) { - - requestTokens := tokenizePath(httpRequest.URL.Path) - - detectedService := c.detectWebService(requestTokens, webServices) - if detectedService == nil { - if trace { - traceLogger.Printf("no WebService was found to match URL path:%s\n", httpRequest.URL.Path) - } - return nil, nil, NewError(http.StatusNotFound, "404: Page Not Found") - } - candidateRoutes := c.selectRoutes(detectedService, requestTokens) - if len(candidateRoutes) == 0 { - if trace { - traceLogger.Printf("no Route in WebService with path %s was found to match URL path:%s\n", detectedService.rootPath, httpRequest.URL.Path) - } - return detectedService, nil, NewError(http.StatusNotFound, "404: Page Not Found") - } - selectedRoute, err := c.detectRoute(candidateRoutes, httpRequest) - if selectedRoute == nil { - return detectedService, nil, err - } - return detectedService, selectedRoute, nil -} - -// selectRoutes return a collection of Route from a WebService that matches the path tokens from the request. -func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes { - candidates := make(sortableCurlyRoutes, 0, 8) - for _, each := range ws.routes { - matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb) - if matches { - candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers? - } - } - sort.Sort(candidates) - return candidates -} - -// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are. -func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string, routeHasCustomVerb bool) (matches bool, paramCount int, staticCount int) { - if len(routeTokens) < len(requestTokens) { - // proceed in matching only if last routeToken is wildcard - count := len(routeTokens) - if count == 0 || !strings.HasSuffix(routeTokens[count-1], "*}") { - return false, 0, 0 - } - // proceed - } - for i, routeToken := range routeTokens { - if i == len(requestTokens) { - // reached end of request path - return false, 0, 0 - } - requestToken := requestTokens[i] - if routeHasCustomVerb && hasCustomVerb(routeToken){ - if !isMatchCustomVerb(routeToken, requestToken) { - return false, 0, 0 - } - staticCount++ - requestToken = removeCustomVerb(requestToken) - routeToken = removeCustomVerb(routeToken) - } - - if strings.HasPrefix(routeToken, "{") { - paramCount++ - if colon := strings.Index(routeToken, ":"); colon != -1 { - // match by regex - matchesToken, matchesRemainder := c.regularMatchesPathToken(routeToken, colon, requestToken) - if !matchesToken { - return false, 0, 0 - } - if matchesRemainder { - break - } - } - } else { // no { prefix - if requestToken != routeToken { - return false, 0, 0 - } - staticCount++ - } - } - return true, paramCount, staticCount -} - -// regularMatchesPathToken tests whether the regular expression part of routeToken matches the requestToken or all remaining tokens -// format routeToken is {someVar:someExpression}, e.g. {zipcode:[\d][\d][\d][\d][A-Z][A-Z]} -func (c CurlyRouter) regularMatchesPathToken(routeToken string, colon int, requestToken string) (matchesToken bool, matchesRemainder bool) { - regPart := routeToken[colon+1 : len(routeToken)-1] - if regPart == "*" { - if trace { - traceLogger.Printf("wildcard parameter detected in route token %s that matches %s\n", routeToken, requestToken) - } - return true, true - } - matched, err := regexp.MatchString(regPart, requestToken) - return (matched && err == nil), false -} - -var jsr311Router = RouterJSR311{} - -// detectRoute selectes from a list of Route the first match by inspecting both the Accept and Content-Type -// headers of the Request. See also RouterJSR311 in jsr311.go -func (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpRequest *http.Request) (*Route, error) { - // tracing is done inside detectRoute - return jsr311Router.detectRoute(candidateRoutes.routes(), httpRequest) -} - -// detectWebService returns the best matching webService given the list of path tokens. -// see also computeWebserviceScore -func (c CurlyRouter) detectWebService(requestTokens []string, webServices []*WebService) *WebService { - var best *WebService - score := -1 - for _, each := range webServices { - matches, eachScore := c.computeWebserviceScore(requestTokens, each.pathExpr.tokens) - if matches && (eachScore > score) { - best = each - score = eachScore - } - } - return best -} - -// computeWebserviceScore returns whether tokens match and -// the weighted score of the longest matching consecutive tokens from the beginning. -func (c CurlyRouter) computeWebserviceScore(requestTokens []string, tokens []string) (bool, int) { - if len(tokens) > len(requestTokens) { - return false, 0 - } - score := 0 - for i := 0; i < len(tokens); i++ { - each := requestTokens[i] - other := tokens[i] - if len(each) == 0 && len(other) == 0 { - score++ - continue - } - if len(other) > 0 && strings.HasPrefix(other, "{") { - // no empty match - if len(each) == 0 { - return false, score - } - score += 1 - } else { - // not a parameter - if each != other { - return false, score - } - score += (len(tokens) - i) * 10 //fuzzy - } - } - return true, score -} diff --git a/vendor/github.com/emicklei/go-restful/v3/curly_route.go b/vendor/github.com/emicklei/go-restful/v3/curly_route.go deleted file mode 100644 index 403dd3be..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/curly_route.go +++ /dev/null @@ -1,54 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// curlyRoute exits for sorting Routes by the CurlyRouter based on number of parameters and number of static path elements. -type curlyRoute struct { - route Route - paramCount int - staticCount int -} - -// sortableCurlyRoutes orders by most parameters and path elements first. -type sortableCurlyRoutes []curlyRoute - -func (s *sortableCurlyRoutes) add(route curlyRoute) { - *s = append(*s, route) -} - -func (s sortableCurlyRoutes) routes() (routes []Route) { - routes = make([]Route, 0, len(s)) - for _, each := range s { - routes = append(routes, each.route) // TODO change return type - } - return routes -} - -func (s sortableCurlyRoutes) Len() int { - return len(s) -} -func (s sortableCurlyRoutes) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} -func (s sortableCurlyRoutes) Less(i, j int) bool { - a := s[j] - b := s[i] - - // primary key - if a.staticCount < b.staticCount { - return true - } - if a.staticCount > b.staticCount { - return false - } - // secundary key - if a.paramCount < b.paramCount { - return true - } - if a.paramCount > b.paramCount { - return false - } - return a.route.Path < b.route.Path -} diff --git a/vendor/github.com/emicklei/go-restful/v3/custom_verb.go b/vendor/github.com/emicklei/go-restful/v3/custom_verb.go deleted file mode 100644 index bfc17efd..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/custom_verb.go +++ /dev/null @@ -1,29 +0,0 @@ -package restful - -import ( - "fmt" - "regexp" -) - -var ( - customVerbReg = regexp.MustCompile(":([A-Za-z]+)$") -) - -func hasCustomVerb(routeToken string) bool { - return customVerbReg.MatchString(routeToken) -} - -func isMatchCustomVerb(routeToken string, pathToken string) bool { - rs := customVerbReg.FindStringSubmatch(routeToken) - if len(rs) < 2 { - return false - } - - customVerb := rs[1] - specificVerbReg := regexp.MustCompile(fmt.Sprintf(":%s$", customVerb)) - return specificVerbReg.MatchString(pathToken) -} - -func removeCustomVerb(str string) string { - return customVerbReg.ReplaceAllString(str, "") -} diff --git a/vendor/github.com/emicklei/go-restful/v3/doc.go b/vendor/github.com/emicklei/go-restful/v3/doc.go deleted file mode 100644 index 69b13057..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/doc.go +++ /dev/null @@ -1,185 +0,0 @@ -/* -Package restful , a lean package for creating REST-style WebServices without magic. - -WebServices and Routes - -A WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls. -Typically, a WebService has a root path (e.g. /users) and defines common MIME types for its routes. -WebServices must be added to a container (see below) in order to handler Http requests from a server. - -A Route is defined by a HTTP method, an URL path and (optionally) the MIME types it consumes (Content-Type) and produces (Accept). -This package has the logic to find the best matching Route and if found, call its Function. - - ws := new(restful.WebService) - ws. - Path("/users"). - Consumes(restful.MIME_JSON, restful.MIME_XML). - Produces(restful.MIME_JSON, restful.MIME_XML) - - ws.Route(ws.GET("/{user-id}").To(u.findUser)) // u is a UserResource - - ... - - // GET http://localhost:8080/users/1 - func (u UserResource) findUser(request *restful.Request, response *restful.Response) { - id := request.PathParameter("user-id") - ... - } - -The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response. - -See the example https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go with a full implementation. - -Regular expression matching Routes - -A Route parameter can be specified using the format "uri/{var[:regexp]}" or the special version "uri/{var:*}" for matching the tail of the path. -For example, /persons/{name:[A-Z][A-Z]} can be used to restrict values for the parameter "name" to only contain capital alphabetic characters. -Regular expressions must use the standard Go syntax as described in the regexp package. (https://code.google.com/p/re2/wiki/Syntax) -This feature requires the use of a CurlyRouter. - -Containers - -A Container holds a collection of WebServices, Filters and a http.ServeMux for multiplexing http requests. -Using the statements "restful.Add(...) and restful.Filter(...)" will register WebServices and Filters to the Default Container. -The Default container of go-restful uses the http.DefaultServeMux. -You can create your own Container and create a new http.Server for that particular container. - - container := restful.NewContainer() - server := &http.Server{Addr: ":8081", Handler: container} - -Filters - -A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. -You can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc. -In the restful package there are three hooks into the request,response flow where filters can be added. -Each filter must define a FilterFunction: - - func (req *restful.Request, resp *restful.Response, chain *restful.FilterChain) - -Use the following statement to pass the request,response pair to the next filter or RouteFunction - - chain.ProcessFilter(req, resp) - -Container Filters - -These are processed before any registered WebService. - - // install a (global) filter for the default container (processed before any webservice) - restful.Filter(globalLogging) - -WebService Filters - -These are processed before any Route of a WebService. - - // install a webservice filter (processed before any route) - ws.Filter(webserviceLogging).Filter(measureTime) - - -Route Filters - -These are processed before calling the function associated with the Route. - - // install 2 chained route filters (processed before calling findUser) - ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser)) - -See the example https://github.com/emicklei/go-restful/blob/v3/examples/filters/restful-filters.go with full implementations. - -Response Encoding - -Two encodings are supported: gzip and deflate. To enable this for all responses: - - restful.DefaultContainer.EnableContentEncoding(true) - -If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding. -Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route. - -See the example https://github.com/emicklei/go-restful/blob/v3/examples/encoding/restful-encoding-filter.go - -OPTIONS support - -By installing a pre-defined container filter, your Webservice(s) can respond to the OPTIONS Http request. - - Filter(OPTIONSFilter()) - -CORS - -By installing the filter of a CrossOriginResourceSharing (CORS), your WebService(s) can handle CORS requests. - - cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer} - Filter(cors.Filter) - -Error Handling - -Unexpected things happen. If a request cannot be processed because of a failure, your service needs to tell via the response what happened and why. -For this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation. - - 400: Bad Request - -If path or query parameters are not valid (content or type) then use http.StatusBadRequest. - - 404: Not Found - -Despite a valid URI, the resource requested may not be available - - 500: Internal Server Error - -If the application logic could not process the request (or write the response) then use http.StatusInternalServerError. - - 405: Method Not Allowed - -The request has a valid URL but the method (GET,PUT,POST,...) is not allowed. - - 406: Not Acceptable - -The request does not have or has an unknown Accept Header set for this operation. - - 415: Unsupported Media Type - -The request does not have or has an unknown Content-Type Header set for this operation. - -ServiceError - -In addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response. - -Performance options - -This package has several options that affect the performance of your service. It is important to understand them and how you can change it. - - restful.DefaultContainer.DoNotRecover(false) - -DoNotRecover controls whether panics will be caught to return HTTP 500. -If set to false, the container will recover from panics. -Default value is true - - restful.SetCompressorProvider(NewBoundedCachedCompressors(20, 20)) - -If content encoding is enabled then the default strategy for getting new gzip/zlib writers and readers is to use a sync.Pool. -Because writers are expensive structures, performance is even more improved when using a preloaded cache. You can also inject your own implementation. - -Trouble shooting - -This package has the means to produce detail logging of the complete Http request matching process and filter invocation. -Enabling this feature requires you to set an implementation of restful.StdLogger (e.g. log.Logger) instance such as: - - restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile)) - -Logging - -The restful.SetLogger() method allows you to override the logger used by the package. By default restful -uses the standard library `log` package and logs to stdout. Different logging packages are supported as -long as they conform to `StdLogger` interface defined in the `log` sub-package, writing an adapter for your -preferred package is simple. - -Resources - -[project]: https://github.com/emicklei/go-restful - -[examples]: https://github.com/emicklei/go-restful/blob/master/examples - -[design]: http://ernestmicklei.com/2012/11/11/go-restful-api-design/ - -[showcases]: https://github.com/emicklei/mora, https://github.com/emicklei/landskape - -(c) 2012-2015, http://ernestmicklei.com. MIT License -*/ -package restful diff --git a/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go b/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go deleted file mode 100644 index 66dfc824..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/entity_accessors.go +++ /dev/null @@ -1,162 +0,0 @@ -package restful - -// Copyright 2015 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "encoding/xml" - "strings" - "sync" -) - -// EntityReaderWriter can read and write values using an encoding such as JSON,XML. -type EntityReaderWriter interface { - // Read a serialized version of the value from the request. - // The Request may have a decompressing reader. Depends on Content-Encoding. - Read(req *Request, v interface{}) error - - // Write a serialized version of the value on the response. - // The Response may have a compressing writer. Depends on Accept-Encoding. - // status should be a valid Http Status code - Write(resp *Response, status int, v interface{}) error -} - -// entityAccessRegistry is a singleton -var entityAccessRegistry = &entityReaderWriters{ - protection: new(sync.RWMutex), - accessors: map[string]EntityReaderWriter{}, -} - -// entityReaderWriters associates MIME to an EntityReaderWriter -type entityReaderWriters struct { - protection *sync.RWMutex - accessors map[string]EntityReaderWriter -} - -func init() { - RegisterEntityAccessor(MIME_JSON, NewEntityAccessorJSON(MIME_JSON)) - RegisterEntityAccessor(MIME_XML, NewEntityAccessorXML(MIME_XML)) -} - -// RegisterEntityAccessor add/overrides the ReaderWriter for encoding content with this MIME type. -func RegisterEntityAccessor(mime string, erw EntityReaderWriter) { - entityAccessRegistry.protection.Lock() - defer entityAccessRegistry.protection.Unlock() - entityAccessRegistry.accessors[mime] = erw -} - -// NewEntityAccessorJSON returns a new EntityReaderWriter for accessing JSON content. -// This package is already initialized with such an accessor using the MIME_JSON contentType. -func NewEntityAccessorJSON(contentType string) EntityReaderWriter { - return entityJSONAccess{ContentType: contentType} -} - -// NewEntityAccessorXML returns a new EntityReaderWriter for accessing XML content. -// This package is already initialized with such an accessor using the MIME_XML contentType. -func NewEntityAccessorXML(contentType string) EntityReaderWriter { - return entityXMLAccess{ContentType: contentType} -} - -// accessorAt returns the registered ReaderWriter for this MIME type. -func (r *entityReaderWriters) accessorAt(mime string) (EntityReaderWriter, bool) { - r.protection.RLock() - defer r.protection.RUnlock() - er, ok := r.accessors[mime] - if !ok { - // retry with reverse lookup - // more expensive but we are in an exceptional situation anyway - for k, v := range r.accessors { - if strings.Contains(mime, k) { - return v, true - } - } - } - return er, ok -} - -// entityXMLAccess is a EntityReaderWriter for XML encoding -type entityXMLAccess struct { - // This is used for setting the Content-Type header when writing - ContentType string -} - -// Read unmarshalls the value from XML -func (e entityXMLAccess) Read(req *Request, v interface{}) error { - return xml.NewDecoder(req.Request.Body).Decode(v) -} - -// Write marshalls the value to JSON and set the Content-Type Header. -func (e entityXMLAccess) Write(resp *Response, status int, v interface{}) error { - return writeXML(resp, status, e.ContentType, v) -} - -// writeXML marshalls the value to JSON and set the Content-Type Header. -func writeXML(resp *Response, status int, contentType string, v interface{}) error { - if v == nil { - resp.WriteHeader(status) - // do not write a nil representation - return nil - } - if resp.prettyPrint { - // pretty output must be created and written explicitly - output, err := xml.MarshalIndent(v, " ", " ") - if err != nil { - return err - } - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - _, err = resp.Write([]byte(xml.Header)) - if err != nil { - return err - } - _, err = resp.Write(output) - return err - } - // not-so-pretty - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - return xml.NewEncoder(resp).Encode(v) -} - -// entityJSONAccess is a EntityReaderWriter for JSON encoding -type entityJSONAccess struct { - // This is used for setting the Content-Type header when writing - ContentType string -} - -// Read unmarshalls the value from JSON -func (e entityJSONAccess) Read(req *Request, v interface{}) error { - decoder := NewDecoder(req.Request.Body) - decoder.UseNumber() - return decoder.Decode(v) -} - -// Write marshalls the value to JSON and set the Content-Type Header. -func (e entityJSONAccess) Write(resp *Response, status int, v interface{}) error { - return writeJSON(resp, status, e.ContentType, v) -} - -// write marshalls the value to JSON and set the Content-Type Header. -func writeJSON(resp *Response, status int, contentType string, v interface{}) error { - if v == nil { - resp.WriteHeader(status) - // do not write a nil representation - return nil - } - if resp.prettyPrint { - // pretty output must be created and written explicitly - output, err := MarshalIndent(v, "", " ") - if err != nil { - return err - } - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - _, err = resp.Write(output) - return err - } - // not-so-pretty - resp.Header().Set(HEADER_ContentType, contentType) - resp.WriteHeader(status) - return NewEncoder(resp).Encode(v) -} diff --git a/vendor/github.com/emicklei/go-restful/v3/extensions.go b/vendor/github.com/emicklei/go-restful/v3/extensions.go deleted file mode 100644 index 5023fa04..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/extensions.go +++ /dev/null @@ -1,21 +0,0 @@ -package restful - -// Copyright 2021 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// ExtensionProperties provides storage of vendor extensions for entities -type ExtensionProperties struct { - // Extensions vendor extensions used to describe extra functionality - // (https://swagger.io/docs/specification/2-0/swagger-extensions/) - Extensions map[string]interface{} -} - -// AddExtension adds or updates a key=value pair to the extension map. -func (ep *ExtensionProperties) AddExtension(key string, value interface{}) { - if ep.Extensions == nil { - ep.Extensions = map[string]interface{}{key: value} - } else { - ep.Extensions[key] = value - } -} diff --git a/vendor/github.com/emicklei/go-restful/v3/filter.go b/vendor/github.com/emicklei/go-restful/v3/filter.go deleted file mode 100644 index fd88c536..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/filter.go +++ /dev/null @@ -1,37 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction. -type FilterChain struct { - Filters []FilterFunction // ordered list of FilterFunction - Index int // index into filters that is currently in progress - Target RouteFunction // function to call after passing all filters - ParameterDocs []*Parameter // the parameter docs for the route - Operation string // the name of the operation -} - -// ProcessFilter passes the request,response pair through the next of Filters. -// Each filter can decide to proceed to the next Filter or handle the Response itself. -func (f *FilterChain) ProcessFilter(request *Request, response *Response) { - if f.Index < len(f.Filters) { - f.Index++ - f.Filters[f.Index-1](request, response, f) - } else { - f.Target(request, response) - } -} - -// FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction -type FilterFunction func(*Request, *Response, *FilterChain) - -// NoBrowserCacheFilter is a filter function to set HTTP headers that disable browser caching -// See examples/restful-no-cache-filter.go for usage -func NoBrowserCacheFilter(req *Request, resp *Response, chain *FilterChain) { - resp.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1. - resp.Header().Set("Pragma", "no-cache") // HTTP 1.0. - resp.Header().Set("Expires", "0") // Proxies. - chain.ProcessFilter(req, resp) -} diff --git a/vendor/github.com/emicklei/go-restful/v3/json.go b/vendor/github.com/emicklei/go-restful/v3/json.go deleted file mode 100644 index 87116516..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/json.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !jsoniter - -package restful - -import "encoding/json" - -var ( - MarshalIndent = json.MarshalIndent - NewDecoder = json.NewDecoder - NewEncoder = json.NewEncoder -) diff --git a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go b/vendor/github.com/emicklei/go-restful/v3/jsoniter.go deleted file mode 100644 index 11b8f8ae..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/jsoniter.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build jsoniter - -package restful - -import "github.com/json-iterator/go" - -var ( - json = jsoniter.ConfigCompatibleWithStandardLibrary - MarshalIndent = json.MarshalIndent - NewDecoder = json.NewDecoder - NewEncoder = json.NewEncoder -) diff --git a/vendor/github.com/emicklei/go-restful/v3/jsr311.go b/vendor/github.com/emicklei/go-restful/v3/jsr311.go deleted file mode 100644 index 07a0c91e..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/jsr311.go +++ /dev/null @@ -1,326 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "errors" - "fmt" - "net/http" - "sort" - "strings" -) - -// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions) -// as specified by the JSR311 http://jsr311.java.net/nonav/releases/1.1/spec/spec.html. -// RouterJSR311 implements the Router interface. -// Concept of locators is not implemented. -type RouterJSR311 struct{} - -// SelectRoute is part of the Router interface and returns the best match -// for the WebService and its Route for the given Request. -func (r RouterJSR311) SelectRoute( - webServices []*WebService, - httpRequest *http.Request) (selectedService *WebService, selectedRoute *Route, err error) { - - // Identify the root resource class (WebService) - dispatcher, finalMatch, err := r.detectDispatcher(httpRequest.URL.Path, webServices) - if err != nil { - return nil, nil, NewError(http.StatusNotFound, "") - } - // Obtain the set of candidate methods (Routes) - routes := r.selectRoutes(dispatcher, finalMatch) - if len(routes) == 0 { - return dispatcher, nil, NewError(http.StatusNotFound, "404: Page Not Found") - } - - // Identify the method (Route) that will handle the request - route, ok := r.detectRoute(routes, httpRequest) - return dispatcher, route, ok -} - -// ExtractParameters is used to obtain the path parameters from the route using the same matching -// engine as the JSR 311 router. -func (r RouterJSR311) ExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string { - webServiceExpr := webService.pathExpr - webServiceMatches := webServiceExpr.Matcher.FindStringSubmatch(urlPath) - pathParameters := r.extractParams(webServiceExpr, webServiceMatches) - routeExpr := route.pathExpr - routeMatches := routeExpr.Matcher.FindStringSubmatch(webServiceMatches[len(webServiceMatches)-1]) - routeParams := r.extractParams(routeExpr, routeMatches) - for key, value := range routeParams { - pathParameters[key] = value - } - return pathParameters -} - -func (RouterJSR311) extractParams(pathExpr *pathExpression, matches []string) map[string]string { - params := map[string]string{} - for i := 1; i < len(matches); i++ { - if len(pathExpr.VarNames) >= i { - params[pathExpr.VarNames[i-1]] = matches[i] - } - } - return params -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 -func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*Route, error) { - candidates := make([]*Route, 0, 8) - for i, each := range routes { - ok := true - for _, fn := range each.If { - if !fn(httpRequest) { - ok = false - break - } - } - if ok { - candidates = append(candidates, &routes[i]) - } - } - if len(candidates) == 0 { - if trace { - traceLogger.Printf("no Route found (from %d) that passes conditional checks", len(routes)) - } - return nil, NewError(http.StatusNotFound, "404: Not Found") - } - - // http method - previous := candidates - candidates = candidates[:0] - for _, each := range previous { - if httpRequest.Method == each.Method { - candidates = append(candidates, each) - } - } - if len(candidates) == 0 { - if trace { - traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(previous), httpRequest.Method) - } - allowed := []string{} - allowedLoop: - for _, candidate := range previous { - for _, method := range allowed { - if method == candidate.Method { - continue allowedLoop - } - } - allowed = append(allowed, candidate.Method) - } - header := http.Header{"Allow": []string{strings.Join(allowed, ", ")}} - return nil, NewErrorWithHeader(http.StatusMethodNotAllowed, "405: Method Not Allowed", header) - } - - // content-type - contentType := httpRequest.Header.Get(HEADER_ContentType) - previous = candidates - candidates = candidates[:0] - for _, each := range previous { - if each.matchesContentType(contentType) { - candidates = append(candidates, each) - } - } - if len(candidates) == 0 { - if trace { - traceLogger.Printf("no Route found (from %d) that matches HTTP Content-Type: %s\n", len(previous), contentType) - } - if httpRequest.ContentLength > 0 { - return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type") - } - } - - // accept - previous = candidates - candidates = candidates[:0] - accept := httpRequest.Header.Get(HEADER_Accept) - if len(accept) == 0 { - accept = "*/*" - } - for _, each := range previous { - if each.matchesAccept(accept) { - candidates = append(candidates, each) - } - } - if len(candidates) == 0 { - if trace { - traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(previous), accept) - } - available := []string{} - for _, candidate := range previous { - available = append(available, candidate.Produces...) - } - // if POST,PUT,PATCH without body - method, length := httpRequest.Method, httpRequest.Header.Get("Content-Length") - if (method == http.MethodPost || - method == http.MethodPut || - method == http.MethodPatch) && length == "" { - return nil, NewError( - http.StatusUnsupportedMediaType, - fmt.Sprintf("415: Unsupported Media Type\n\nAvailable representations: %s", strings.Join(available, ", ")), - ) - } - return nil, NewError( - http.StatusNotAcceptable, - fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")), - ) - } - // return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil - return candidates[0], nil -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 -// n/m > n/* > */* -func (r RouterJSR311) bestMatchByMedia(routes []Route, contentType string, accept string) *Route { - // TODO - return &routes[0] -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 2) -func (r RouterJSR311) selectRoutes(dispatcher *WebService, pathRemainder string) []Route { - filtered := &sortableRouteCandidates{} - for _, each := range dispatcher.Routes() { - pathExpr := each.pathExpr - matches := pathExpr.Matcher.FindStringSubmatch(pathRemainder) - if matches != nil { - lastMatch := matches[len(matches)-1] - if len(lastMatch) == 0 || lastMatch == "/" { // do not include if value is neither empty nor ‘/’. - filtered.candidates = append(filtered.candidates, - routeCandidate{each, len(matches) - 1, pathExpr.LiteralCount, pathExpr.VarCount}) - } - } - } - if len(filtered.candidates) == 0 { - if trace { - traceLogger.Printf("WebService on path %s has no routes that match URL path remainder:%s\n", dispatcher.rootPath, pathRemainder) - } - return []Route{} - } - sort.Sort(sort.Reverse(filtered)) - - // select other routes from candidates whoes expression matches rmatch - matchingRoutes := []Route{filtered.candidates[0].route} - for c := 1; c < len(filtered.candidates); c++ { - each := filtered.candidates[c] - if each.route.pathExpr.Matcher.MatchString(pathRemainder) { - matchingRoutes = append(matchingRoutes, each.route) - } - } - return matchingRoutes -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 1) -func (r RouterJSR311) detectDispatcher(requestPath string, dispatchers []*WebService) (*WebService, string, error) { - filtered := &sortableDispatcherCandidates{} - for _, each := range dispatchers { - matches := each.pathExpr.Matcher.FindStringSubmatch(requestPath) - if matches != nil { - filtered.candidates = append(filtered.candidates, - dispatcherCandidate{each, matches[len(matches)-1], len(matches), each.pathExpr.LiteralCount, each.pathExpr.VarCount}) - } - } - if len(filtered.candidates) == 0 { - if trace { - traceLogger.Printf("no WebService was found to match URL path:%s\n", requestPath) - } - return nil, "", errors.New("not found") - } - sort.Sort(sort.Reverse(filtered)) - return filtered.candidates[0].dispatcher, filtered.candidates[0].finalMatch, nil -} - -// Types and functions to support the sorting of Routes - -type routeCandidate struct { - route Route - matchesCount int // the number of capturing groups - literalCount int // the number of literal characters (means those not resulting from template variable substitution) - nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’) -} - -func (r routeCandidate) expressionToMatch() string { - return r.route.pathExpr.Source -} - -func (r routeCandidate) String() string { - return fmt.Sprintf("(m=%d,l=%d,n=%d)", r.matchesCount, r.literalCount, r.nonDefaultCount) -} - -type sortableRouteCandidates struct { - candidates []routeCandidate -} - -func (rcs *sortableRouteCandidates) Len() int { - return len(rcs.candidates) -} -func (rcs *sortableRouteCandidates) Swap(i, j int) { - rcs.candidates[i], rcs.candidates[j] = rcs.candidates[j], rcs.candidates[i] -} -func (rcs *sortableRouteCandidates) Less(i, j int) bool { - ci := rcs.candidates[i] - cj := rcs.candidates[j] - // primary key - if ci.literalCount < cj.literalCount { - return true - } - if ci.literalCount > cj.literalCount { - return false - } - // secundary key - if ci.matchesCount < cj.matchesCount { - return true - } - if ci.matchesCount > cj.matchesCount { - return false - } - // tertiary key - if ci.nonDefaultCount < cj.nonDefaultCount { - return true - } - if ci.nonDefaultCount > cj.nonDefaultCount { - return false - } - // quaternary key ("source" is interpreted as Path) - return ci.route.Path < cj.route.Path -} - -// Types and functions to support the sorting of Dispatchers - -type dispatcherCandidate struct { - dispatcher *WebService - finalMatch string - matchesCount int // the number of capturing groups - literalCount int // the number of literal characters (means those not resulting from template variable substitution) - nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’) -} -type sortableDispatcherCandidates struct { - candidates []dispatcherCandidate -} - -func (dc *sortableDispatcherCandidates) Len() int { - return len(dc.candidates) -} -func (dc *sortableDispatcherCandidates) Swap(i, j int) { - dc.candidates[i], dc.candidates[j] = dc.candidates[j], dc.candidates[i] -} -func (dc *sortableDispatcherCandidates) Less(i, j int) bool { - ci := dc.candidates[i] - cj := dc.candidates[j] - // primary key - if ci.matchesCount < cj.matchesCount { - return true - } - if ci.matchesCount > cj.matchesCount { - return false - } - // secundary key - if ci.literalCount < cj.literalCount { - return true - } - if ci.literalCount > cj.literalCount { - return false - } - // tertiary key - return ci.nonDefaultCount < cj.nonDefaultCount -} diff --git a/vendor/github.com/emicklei/go-restful/v3/log/log.go b/vendor/github.com/emicklei/go-restful/v3/log/log.go deleted file mode 100644 index 6cd44c7a..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/log/log.go +++ /dev/null @@ -1,34 +0,0 @@ -package log - -import ( - stdlog "log" - "os" -) - -// StdLogger corresponds to a minimal subset of the interface satisfied by stdlib log.Logger -type StdLogger interface { - Print(v ...interface{}) - Printf(format string, v ...interface{}) -} - -var Logger StdLogger - -func init() { - // default Logger - SetLogger(stdlog.New(os.Stderr, "[restful] ", stdlog.LstdFlags|stdlog.Lshortfile)) -} - -// SetLogger sets the logger for this package -func SetLogger(customLogger StdLogger) { - Logger = customLogger -} - -// Print delegates to the Logger -func Print(v ...interface{}) { - Logger.Print(v...) -} - -// Printf delegates to the Logger -func Printf(format string, v ...interface{}) { - Logger.Printf(format, v...) -} diff --git a/vendor/github.com/emicklei/go-restful/v3/logger.go b/vendor/github.com/emicklei/go-restful/v3/logger.go deleted file mode 100644 index 29202726..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/logger.go +++ /dev/null @@ -1,32 +0,0 @@ -package restful - -// Copyright 2014 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. -import ( - "github.com/emicklei/go-restful/v3/log" -) - -var trace bool = false -var traceLogger log.StdLogger - -func init() { - traceLogger = log.Logger // use the package logger by default -} - -// TraceLogger enables detailed logging of Http request matching and filter invocation. Default no logger is set. -// You may call EnableTracing() directly to enable trace logging to the package-wide logger. -func TraceLogger(logger log.StdLogger) { - traceLogger = logger - EnableTracing(logger != nil) -} - -// SetLogger exposes the setter for the global logger on the top-level package -func SetLogger(customLogger log.StdLogger) { - log.SetLogger(customLogger) -} - -// EnableTracing can be used to Trace logging on and off. -func EnableTracing(enabled bool) { - trace = enabled -} diff --git a/vendor/github.com/emicklei/go-restful/v3/mime.go b/vendor/github.com/emicklei/go-restful/v3/mime.go deleted file mode 100644 index 33014471..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/mime.go +++ /dev/null @@ -1,50 +0,0 @@ -package restful - -import ( - "strconv" - "strings" -) - -type mime struct { - media string - quality float64 -} - -// insertMime adds a mime to a list and keeps it sorted by quality. -func insertMime(l []mime, e mime) []mime { - for i, each := range l { - // if current mime has lower quality then insert before - if e.quality > each.quality { - left := append([]mime{}, l[0:i]...) - return append(append(left, e), l[i:]...) - } - } - return append(l, e) -} - -const qFactorWeightingKey = "q" - -// sortedMimes returns a list of mime sorted (desc) by its specified quality. -// e.g. text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 -func sortedMimes(accept string) (sorted []mime) { - for _, each := range strings.Split(accept, ",") { - typeAndQuality := strings.Split(strings.Trim(each, " "), ";") - if len(typeAndQuality) == 1 { - sorted = insertMime(sorted, mime{typeAndQuality[0], 1.0}) - } else { - // take factor - qAndWeight := strings.Split(typeAndQuality[1], "=") - if len(qAndWeight) == 2 && strings.Trim(qAndWeight[0], " ") == qFactorWeightingKey { - f, err := strconv.ParseFloat(qAndWeight[1], 64) - if err != nil { - traceLogger.Printf("unable to parse quality in %s, %v", each, err) - } else { - sorted = insertMime(sorted, mime{typeAndQuality[0], f}) - } - } else { - sorted = insertMime(sorted, mime{typeAndQuality[0], 1.0}) - } - } - } - return -} diff --git a/vendor/github.com/emicklei/go-restful/v3/options_filter.go b/vendor/github.com/emicklei/go-restful/v3/options_filter.go deleted file mode 100644 index 5c1b3425..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/options_filter.go +++ /dev/null @@ -1,34 +0,0 @@ -package restful - -import "strings" - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method -// and provides the response with a set of allowed methods for the request URL Path. -// As for any filter, you can also install it for a particular WebService within a Container. -// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS). -func (c *Container) OPTIONSFilter(req *Request, resp *Response, chain *FilterChain) { - if "OPTIONS" != req.Request.Method { - chain.ProcessFilter(req, resp) - return - } - - archs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders) - methods := strings.Join(c.computeAllowedMethods(req), ",") - origin := req.Request.Header.Get(HEADER_Origin) - - resp.AddHeader(HEADER_Allow, methods) - resp.AddHeader(HEADER_AccessControlAllowOrigin, origin) - resp.AddHeader(HEADER_AccessControlAllowHeaders, archs) - resp.AddHeader(HEADER_AccessControlAllowMethods, methods) -} - -// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method -// and provides the response with a set of allowed methods for the request URL Path. -// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS). -func OPTIONSFilter() FilterFunction { - return DefaultContainer.OPTIONSFilter -} diff --git a/vendor/github.com/emicklei/go-restful/v3/parameter.go b/vendor/github.com/emicklei/go-restful/v3/parameter.go deleted file mode 100644 index 0e658af5..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/parameter.go +++ /dev/null @@ -1,234 +0,0 @@ -package restful - -import "sort" - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -const ( - // PathParameterKind = indicator of Request parameter type "path" - PathParameterKind = iota - - // QueryParameterKind = indicator of Request parameter type "query" - QueryParameterKind - - // BodyParameterKind = indicator of Request parameter type "body" - BodyParameterKind - - // HeaderParameterKind = indicator of Request parameter type "header" - HeaderParameterKind - - // FormParameterKind = indicator of Request parameter type "form" - FormParameterKind - - // CollectionFormatCSV comma separated values `foo,bar` - CollectionFormatCSV = CollectionFormat("csv") - - // CollectionFormatSSV space separated values `foo bar` - CollectionFormatSSV = CollectionFormat("ssv") - - // CollectionFormatTSV tab separated values `foo\tbar` - CollectionFormatTSV = CollectionFormat("tsv") - - // CollectionFormatPipes pipe separated values `foo|bar` - CollectionFormatPipes = CollectionFormat("pipes") - - // CollectionFormatMulti corresponds to multiple parameter instances instead of multiple values for a single - // instance `foo=bar&foo=baz`. This is valid only for QueryParameters and FormParameters - CollectionFormatMulti = CollectionFormat("multi") -) - -type CollectionFormat string - -func (cf CollectionFormat) String() string { - return string(cf) -} - -// Parameter is for documententing the parameter used in a Http Request -// ParameterData kinds are Path,Query and Body -type Parameter struct { - data *ParameterData -} - -// ParameterData represents the state of a Parameter. -// It is made public to make it accessible to e.g. the Swagger package. -type ParameterData struct { - ExtensionProperties - Name, Description, DataType, DataFormat string - Kind int - Required bool - // AllowableValues is deprecated. Use PossibleValues instead - AllowableValues map[string]string - PossibleValues []string - AllowMultiple bool - AllowEmptyValue bool - DefaultValue string - CollectionFormat string - Pattern string - Minimum *float64 - Maximum *float64 - MinLength *int64 - MaxLength *int64 - MinItems *int64 - MaxItems *int64 - UniqueItems bool -} - -// Data returns the state of the Parameter -func (p *Parameter) Data() ParameterData { - return *p.data -} - -// Kind returns the parameter type indicator (see const for valid values) -func (p *Parameter) Kind() int { - return p.data.Kind -} - -func (p *Parameter) bePath() *Parameter { - p.data.Kind = PathParameterKind - return p -} -func (p *Parameter) beQuery() *Parameter { - p.data.Kind = QueryParameterKind - return p -} -func (p *Parameter) beBody() *Parameter { - p.data.Kind = BodyParameterKind - return p -} - -func (p *Parameter) beHeader() *Parameter { - p.data.Kind = HeaderParameterKind - return p -} - -func (p *Parameter) beForm() *Parameter { - p.data.Kind = FormParameterKind - return p -} - -// Required sets the required field and returns the receiver -func (p *Parameter) Required(required bool) *Parameter { - p.data.Required = required - return p -} - -// AllowMultiple sets the allowMultiple field and returns the receiver -func (p *Parameter) AllowMultiple(multiple bool) *Parameter { - p.data.AllowMultiple = multiple - return p -} - -// AddExtension adds or updates a key=value pair to the extension map -func (p *Parameter) AddExtension(key string, value interface{}) *Parameter { - p.data.AddExtension(key, value) - return p -} - -// AllowEmptyValue sets the AllowEmptyValue field and returns the receiver -func (p *Parameter) AllowEmptyValue(multiple bool) *Parameter { - p.data.AllowEmptyValue = multiple - return p -} - -// AllowableValues is deprecated. Use PossibleValues instead. Both will be set. -func (p *Parameter) AllowableValues(values map[string]string) *Parameter { - p.data.AllowableValues = values - - allowableSortedKeys := make([]string, 0, len(values)) - for k := range values { - allowableSortedKeys = append(allowableSortedKeys, k) - } - sort.Strings(allowableSortedKeys) - - p.data.PossibleValues = make([]string, 0, len(values)) - for _, k := range allowableSortedKeys { - p.data.PossibleValues = append(p.data.PossibleValues, values[k]) - } - return p -} - -// PossibleValues sets the possible values field and returns the receiver -func (p *Parameter) PossibleValues(values []string) *Parameter { - p.data.PossibleValues = values - return p -} - -// DataType sets the dataType field and returns the receiver -func (p *Parameter) DataType(typeName string) *Parameter { - p.data.DataType = typeName - return p -} - -// DataFormat sets the dataFormat field for Swagger UI -func (p *Parameter) DataFormat(formatName string) *Parameter { - p.data.DataFormat = formatName - return p -} - -// DefaultValue sets the default value field and returns the receiver -func (p *Parameter) DefaultValue(stringRepresentation string) *Parameter { - p.data.DefaultValue = stringRepresentation - return p -} - -// Description sets the description value field and returns the receiver -func (p *Parameter) Description(doc string) *Parameter { - p.data.Description = doc - return p -} - -// CollectionFormat sets the collection format for an array type -func (p *Parameter) CollectionFormat(format CollectionFormat) *Parameter { - p.data.CollectionFormat = format.String() - return p -} - -// Pattern sets the pattern field and returns the receiver -func (p *Parameter) Pattern(pattern string) *Parameter { - p.data.Pattern = pattern - return p -} - -// Minimum sets the minimum field and returns the receiver -func (p *Parameter) Minimum(minimum float64) *Parameter { - p.data.Minimum = &minimum - return p -} - -// Maximum sets the maximum field and returns the receiver -func (p *Parameter) Maximum(maximum float64) *Parameter { - p.data.Maximum = &maximum - return p -} - -// MinLength sets the minLength field and returns the receiver -func (p *Parameter) MinLength(minLength int64) *Parameter { - p.data.MinLength = &minLength - return p -} - -// MaxLength sets the maxLength field and returns the receiver -func (p *Parameter) MaxLength(maxLength int64) *Parameter { - p.data.MaxLength = &maxLength - return p -} - -// MinItems sets the minItems field and returns the receiver -func (p *Parameter) MinItems(minItems int64) *Parameter { - p.data.MinItems = &minItems - return p -} - -// MaxItems sets the maxItems field and returns the receiver -func (p *Parameter) MaxItems(maxItems int64) *Parameter { - p.data.MaxItems = &maxItems - return p -} - -// UniqueItems sets the uniqueItems field and returns the receiver -func (p *Parameter) UniqueItems(uniqueItems bool) *Parameter { - p.data.UniqueItems = uniqueItems - return p -} diff --git a/vendor/github.com/emicklei/go-restful/v3/path_expression.go b/vendor/github.com/emicklei/go-restful/v3/path_expression.go deleted file mode 100644 index 95a9a254..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/path_expression.go +++ /dev/null @@ -1,74 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bytes" - "fmt" - "regexp" - "strings" -) - -// PathExpression holds a compiled path expression (RegExp) needed to match against -// Http request paths and to extract path parameter values. -type pathExpression struct { - LiteralCount int // the number of literal characters (means those not resulting from template variable substitution) - VarNames []string // the names of parameters (enclosed by {}) in the path - VarCount int // the number of named parameters (enclosed by {}) in the path - Matcher *regexp.Regexp - Source string // Path as defined by the RouteBuilder - tokens []string -} - -// NewPathExpression creates a PathExpression from the input URL path. -// Returns an error if the path is invalid. -func newPathExpression(path string) (*pathExpression, error) { - expression, literalCount, varNames, varCount, tokens := templateToRegularExpression(path) - compiled, err := regexp.Compile(expression) - if err != nil { - return nil, err - } - return &pathExpression{literalCount, varNames, varCount, compiled, expression, tokens}, nil -} - -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-370003.7.3 -func templateToRegularExpression(template string) (expression string, literalCount int, varNames []string, varCount int, tokens []string) { - var buffer bytes.Buffer - buffer.WriteString("^") - //tokens = strings.Split(template, "/") - tokens = tokenizePath(template) - for _, each := range tokens { - if each == "" { - continue - } - buffer.WriteString("/") - if strings.HasPrefix(each, "{") { - // check for regular expression in variable - colon := strings.Index(each, ":") - var varName string - if colon != -1 { - // extract expression - varName = strings.TrimSpace(each[1:colon]) - paramExpr := strings.TrimSpace(each[colon+1 : len(each)-1]) - if paramExpr == "*" { // special case - buffer.WriteString("(.*)") - } else { - buffer.WriteString(fmt.Sprintf("(%s)", paramExpr)) // between colon and closing moustache - } - } else { - // plain var - varName = strings.TrimSpace(each[1 : len(each)-1]) - buffer.WriteString("([^/]+?)") - } - varNames = append(varNames, varName) - varCount += 1 - } else { - literalCount += len(each) - encoded := each // TODO URI encode - buffer.WriteString(regexp.QuoteMeta(encoded)) - } - } - return strings.TrimRight(buffer.String(), "/") + "(/.*)?$", literalCount, varNames, varCount, tokens -} diff --git a/vendor/github.com/emicklei/go-restful/v3/path_processor.go b/vendor/github.com/emicklei/go-restful/v3/path_processor.go deleted file mode 100644 index 14157324..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/path_processor.go +++ /dev/null @@ -1,74 +0,0 @@ -package restful - -import ( - "bytes" - "strings" -) - -// Copyright 2018 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// PathProcessor is extra behaviour that a Router can provide to extract path parameters from the path. -// If a Router does not implement this interface then the default behaviour will be used. -type PathProcessor interface { - // ExtractParameters gets the path parameters defined in the route and webService from the urlPath - ExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string -} - -type defaultPathProcessor struct{} - -// Extract the parameters from the request url path -func (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath string) map[string]string { - urlParts := tokenizePath(urlPath) - pathParameters := map[string]string{} - for i, key := range r.pathParts { - var value string - if i >= len(urlParts) { - value = "" - } else { - value = urlParts[i] - } - if r.hasCustomVerb && hasCustomVerb(key) { - key = removeCustomVerb(key) - value = removeCustomVerb(value) - } - - if strings.Index(key, "{") > -1 { // path-parameter - if colon := strings.Index(key, ":"); colon != -1 { - // extract by regex - regPart := key[colon+1 : len(key)-1] - keyPart := key[1:colon] - if regPart == "*" { - pathParameters[keyPart] = untokenizePath(i, urlParts) - break - } else { - pathParameters[keyPart] = value - } - } else { - // without enclosing {} - startIndex := strings.Index(key, "{") - endKeyIndex := strings.Index(key, "}") - - suffixLength := len(key) - endKeyIndex - 1 - endValueIndex := len(value) - suffixLength - - pathParameters[key[startIndex+1:endKeyIndex]] = value[startIndex:endValueIndex] - } - } - } - return pathParameters -} - -// Untokenize back into an URL path using the slash separator -func untokenizePath(offset int, parts []string) string { - var buffer bytes.Buffer - for p := offset; p < len(parts); p++ { - buffer.WriteString(parts[p]) - // do not end - if p < len(parts)-1 { - buffer.WriteString("/") - } - } - return buffer.String() -} diff --git a/vendor/github.com/emicklei/go-restful/v3/request.go b/vendor/github.com/emicklei/go-restful/v3/request.go deleted file mode 100644 index 5725a075..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/request.go +++ /dev/null @@ -1,132 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "compress/zlib" - "net/http" -) - -var defaultRequestContentType string - -// Request is a wrapper for a http Request that provides convenience methods -type Request struct { - Request *http.Request - pathParameters map[string]string - attributes map[string]interface{} // for storing request-scoped values - selectedRoute *Route // is nil when no route was matched -} - -func NewRequest(httpRequest *http.Request) *Request { - return &Request{ - Request: httpRequest, - pathParameters: map[string]string{}, - attributes: map[string]interface{}{}, - } // empty parameters, attributes -} - -// If ContentType is missing or */* is given then fall back to this type, otherwise -// a "Unable to unmarshal content of type:" response is returned. -// Valid values are restful.MIME_JSON and restful.MIME_XML -// Example: -// restful.DefaultRequestContentType(restful.MIME_JSON) -func DefaultRequestContentType(mime string) { - defaultRequestContentType = mime -} - -// PathParameter accesses the Path parameter value by its name -func (r *Request) PathParameter(name string) string { - return r.pathParameters[name] -} - -// PathParameters accesses the Path parameter values -func (r *Request) PathParameters() map[string]string { - return r.pathParameters -} - -// QueryParameter returns the (first) Query parameter value by its name -func (r *Request) QueryParameter(name string) string { - return r.Request.FormValue(name) -} - -// QueryParameters returns the all the query parameters values by name -func (r *Request) QueryParameters(name string) []string { - return r.Request.URL.Query()[name] -} - -// BodyParameter parses the body of the request (once for typically a POST or a PUT) and returns the value of the given name or an error. -func (r *Request) BodyParameter(name string) (string, error) { - err := r.Request.ParseForm() - if err != nil { - return "", err - } - return r.Request.PostFormValue(name), nil -} - -// HeaderParameter returns the HTTP Header value of a Header name or empty if missing -func (r *Request) HeaderParameter(name string) string { - return r.Request.Header.Get(name) -} - -// ReadEntity checks the Accept header and reads the content into the entityPointer. -func (r *Request) ReadEntity(entityPointer interface{}) (err error) { - contentType := r.Request.Header.Get(HEADER_ContentType) - contentEncoding := r.Request.Header.Get(HEADER_ContentEncoding) - - // check if the request body needs decompression - if ENCODING_GZIP == contentEncoding { - gzipReader := currentCompressorProvider.AcquireGzipReader() - defer currentCompressorProvider.ReleaseGzipReader(gzipReader) - gzipReader.Reset(r.Request.Body) - r.Request.Body = gzipReader - } else if ENCODING_DEFLATE == contentEncoding { - zlibReader, err := zlib.NewReader(r.Request.Body) - if err != nil { - return err - } - r.Request.Body = zlibReader - } - - // lookup the EntityReader, use defaultRequestContentType if needed and provided - entityReader, ok := entityAccessRegistry.accessorAt(contentType) - if !ok { - if len(defaultRequestContentType) != 0 { - entityReader, ok = entityAccessRegistry.accessorAt(defaultRequestContentType) - } - if !ok { - return NewError(http.StatusBadRequest, "Unable to unmarshal content of type:"+contentType) - } - } - return entityReader.Read(r, entityPointer) -} - -// SetAttribute adds or replaces the attribute with the given value. -func (r *Request) SetAttribute(name string, value interface{}) { - r.attributes[name] = value -} - -// Attribute returns the value associated to the given name. Returns nil if absent. -func (r Request) Attribute(name string) interface{} { - return r.attributes[name] -} - -// SelectedRoutePath root path + route path that matched the request, e.g. /meetings/{id}/attendees -// If no route was matched then return an empty string. -func (r Request) SelectedRoutePath() string { - if r.selectedRoute == nil { - return "" - } - // skip creating an accessor - return r.selectedRoute.Path -} - -// SelectedRoute returns a reader to access the selected Route by the container -// Returns nil if no route was matched. -func (r Request) SelectedRoute() RouteReader { - if r.selectedRoute == nil { - return nil - } - return routeAccessor{route: r.selectedRoute} -} diff --git a/vendor/github.com/emicklei/go-restful/v3/response.go b/vendor/github.com/emicklei/go-restful/v3/response.go deleted file mode 100644 index 8f0b56aa..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/response.go +++ /dev/null @@ -1,256 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "bufio" - "errors" - "net" - "net/http" -) - -// DefaultResponseMimeType is DEPRECATED, use DefaultResponseContentType(mime) -var DefaultResponseMimeType string - -//PrettyPrintResponses controls the indentation feature of XML and JSON serialization -var PrettyPrintResponses = true - -// Response is a wrapper on the actual http ResponseWriter -// It provides several convenience methods to prepare and write response content. -type Response struct { - http.ResponseWriter - requestAccept string // mime-type what the Http Request says it wants to receive - routeProduces []string // mime-types what the Route says it can produce - statusCode int // HTTP status code that has been written explicitly (if zero then net/http has written 200) - contentLength int // number of bytes written for the response body - prettyPrint bool // controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses. - err error // err property is kept when WriteError is called - hijacker http.Hijacker // if underlying ResponseWriter supports it -} - -// NewResponse creates a new response based on a http ResponseWriter. -func NewResponse(httpWriter http.ResponseWriter) *Response { - hijacker, _ := httpWriter.(http.Hijacker) - return &Response{ResponseWriter: httpWriter, routeProduces: []string{}, statusCode: http.StatusOK, prettyPrint: PrettyPrintResponses, hijacker: hijacker} -} - -// DefaultResponseContentType set a default. -// If Accept header matching fails, fall back to this type. -// Valid values are restful.MIME_JSON and restful.MIME_XML -// Example: -// restful.DefaultResponseContentType(restful.MIME_JSON) -func DefaultResponseContentType(mime string) { - DefaultResponseMimeType = mime -} - -// InternalServerError writes the StatusInternalServerError header. -// DEPRECATED, use WriteErrorString(http.StatusInternalServerError,reason) -func (r Response) InternalServerError() Response { - r.WriteHeader(http.StatusInternalServerError) - return r -} - -// Hijack implements the http.Hijacker interface. This expands -// the Response to fulfill http.Hijacker if the underlying -// http.ResponseWriter supports it. -func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) { - if r.hijacker == nil { - return nil, nil, errors.New("http.Hijacker not implemented by underlying http.ResponseWriter") - } - return r.hijacker.Hijack() -} - -// PrettyPrint changes whether this response must produce pretty (line-by-line, indented) JSON or XML output. -func (r *Response) PrettyPrint(bePretty bool) { - r.prettyPrint = bePretty -} - -// AddHeader is a shortcut for .Header().Add(header,value) -func (r Response) AddHeader(header string, value string) Response { - r.Header().Add(header, value) - return r -} - -// SetRequestAccepts tells the response what Mime-type(s) the HTTP request said it wants to accept. Exposed for testing. -func (r *Response) SetRequestAccepts(mime string) { - r.requestAccept = mime -} - -// EntityWriter returns the registered EntityWriter that the entity (requested resource) -// can write according to what the request wants (Accept) and what the Route can produce or what the restful defaults say. -// If called before WriteEntity and WriteHeader then a false return value can be used to write a 406: Not Acceptable. -func (r *Response) EntityWriter() (EntityReaderWriter, bool) { - sorted := sortedMimes(r.requestAccept) - for _, eachAccept := range sorted { - for _, eachProduce := range r.routeProduces { - if eachProduce == eachAccept.media { - if w, ok := entityAccessRegistry.accessorAt(eachAccept.media); ok { - return w, true - } - } - } - if eachAccept.media == "*/*" { - for _, each := range r.routeProduces { - if w, ok := entityAccessRegistry.accessorAt(each); ok { - return w, true - } - } - } - } - // if requestAccept is empty - writer, ok := entityAccessRegistry.accessorAt(r.requestAccept) - if !ok { - // if not registered then fallback to the defaults (if set) - if DefaultResponseMimeType == MIME_JSON { - return entityAccessRegistry.accessorAt(MIME_JSON) - } - if DefaultResponseMimeType == MIME_XML { - return entityAccessRegistry.accessorAt(MIME_XML) - } - // Fallback to whatever the route says it can produce. - // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - for _, each := range r.routeProduces { - if w, ok := entityAccessRegistry.accessorAt(each); ok { - return w, true - } - } - if trace { - traceLogger.Printf("no registered EntityReaderWriter found for %s", r.requestAccept) - } - } - return writer, ok -} - -// WriteEntity calls WriteHeaderAndEntity with Http Status OK (200) -func (r *Response) WriteEntity(value interface{}) error { - return r.WriteHeaderAndEntity(http.StatusOK, value) -} - -// WriteHeaderAndEntity marshals the value using the representation denoted by the Accept Header and the registered EntityWriters. -// If no Accept header is specified (or */*) then respond with the Content-Type as specified by the first in the Route.Produces. -// If an Accept header is specified then respond with the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header. -// If the value is nil then no response is send except for the Http status. You may want to call WriteHeader(http.StatusNotFound) instead. -// If there is no writer available that can represent the value in the requested MIME type then Http Status NotAcceptable is written. -// Current implementation ignores any q-parameters in the Accept Header. -// Returns an error if the value could not be written on the response. -func (r *Response) WriteHeaderAndEntity(status int, value interface{}) error { - writer, ok := r.EntityWriter() - if !ok { - r.WriteHeader(http.StatusNotAcceptable) - return nil - } - return writer.Write(r, status, value) -} - -// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value) -// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteAsXml(value interface{}) error { - return writeXML(r, http.StatusOK, MIME_XML, value) -} - -// WriteHeaderAndXml is a convenience method for writing a status and value in xml (requires Xml tags on the value) -// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteHeaderAndXml(status int, value interface{}) error { - return writeXML(r, status, MIME_XML, value) -} - -// WriteAsJson is a convenience method for writing a value in json. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteAsJson(value interface{}) error { - return writeJSON(r, http.StatusOK, MIME_JSON, value) -} - -// WriteJson is a convenience method for writing a value in Json with a given Content-Type. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteJson(value interface{}, contentType string) error { - return writeJSON(r, http.StatusOK, contentType, value) -} - -// WriteHeaderAndJson is a convenience method for writing the status and a value in Json with a given Content-Type. -// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter. -func (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType string) error { - return writeJSON(r, status, contentType, value) -} - -// WriteError writes the http status and the error string on the response. err can be nil. -// Return an error if writing was not successful. -func (r *Response) WriteError(httpStatus int, err error) (writeErr error) { - r.err = err - if err == nil { - writeErr = r.WriteErrorString(httpStatus, "") - } else { - writeErr = r.WriteErrorString(httpStatus, err.Error()) - } - return writeErr -} - -// WriteServiceError is a convenience method for a responding with a status and a ServiceError -func (r *Response) WriteServiceError(httpStatus int, err ServiceError) error { - r.err = err - return r.WriteHeaderAndEntity(httpStatus, err) -} - -// WriteErrorString is a convenience method for an error status with the actual error -func (r *Response) WriteErrorString(httpStatus int, errorReason string) error { - if r.err == nil { - // if not called from WriteError - r.err = errors.New(errorReason) - } - r.WriteHeader(httpStatus) - if _, err := r.Write([]byte(errorReason)); err != nil { - return err - } - return nil -} - -// Flush implements http.Flusher interface, which sends any buffered data to the client. -func (r *Response) Flush() { - if f, ok := r.ResponseWriter.(http.Flusher); ok { - f.Flush() - } else if trace { - traceLogger.Printf("ResponseWriter %v doesn't support Flush", r) - } -} - -// WriteHeader is overridden to remember the Status Code that has been written. -// Changes to the Header of the response have no effect after this. -func (r *Response) WriteHeader(httpStatus int) { - r.statusCode = httpStatus - r.ResponseWriter.WriteHeader(httpStatus) -} - -// StatusCode returns the code that has been written using WriteHeader. -func (r Response) StatusCode() int { - if 0 == r.statusCode { - // no status code has been written yet; assume OK - return http.StatusOK - } - return r.statusCode -} - -// Write writes the data to the connection as part of an HTTP reply. -// Write is part of http.ResponseWriter interface. -func (r *Response) Write(bytes []byte) (int, error) { - written, err := r.ResponseWriter.Write(bytes) - r.contentLength += written - return written, err -} - -// ContentLength returns the number of bytes written for the response content. -// Note that this value is only correct if all data is written through the Response using its Write* methods. -// Data written directly using the underlying http.ResponseWriter is not accounted for. -func (r Response) ContentLength() int { - return r.contentLength -} - -// CloseNotify is part of http.CloseNotifier interface -func (r Response) CloseNotify() <-chan bool { - return r.ResponseWriter.(http.CloseNotifier).CloseNotify() -} - -// Error returns the err created by WriteError -func (r Response) Error() error { - return r.err -} diff --git a/vendor/github.com/emicklei/go-restful/v3/route.go b/vendor/github.com/emicklei/go-restful/v3/route.go deleted file mode 100644 index 193f4a6b..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/route.go +++ /dev/null @@ -1,178 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "net/http" - "strings" -) - -// RouteFunction declares the signature of a function that can be bound to a Route. -type RouteFunction func(*Request, *Response) - -// RouteSelectionConditionFunction declares the signature of a function that -// can be used to add extra conditional logic when selecting whether the route -// matches the HTTP request. -type RouteSelectionConditionFunction func(httpRequest *http.Request) bool - -// Route binds a HTTP Method,Path,Consumes combination to a RouteFunction. -type Route struct { - ExtensionProperties - Method string - Produces []string - Consumes []string - Path string // webservice root path + described path - Function RouteFunction - Filters []FilterFunction - If []RouteSelectionConditionFunction - - // cached values for dispatching - relativePath string - pathParts []string - pathExpr *pathExpression // cached compilation of relativePath as RegExp - - // documentation - Doc string - Notes string - Operation string - ParameterDocs []*Parameter - ResponseErrors map[int]ResponseError - DefaultResponse *ResponseError - ReadSample, WriteSample interface{} // structs that model an example request or response payload - - // Extra information used to store custom information about the route. - Metadata map[string]interface{} - - // marks a route as deprecated - Deprecated bool - - //Overrides the container.contentEncodingEnabled - contentEncodingEnabled *bool - - // indicate route path has custom verb - hasCustomVerb bool - - // if a request does not include a content-type header then - // depending on the method, it may return a 415 Unsupported Media - // Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,... - allowedMethodsWithoutContentType []string -} - -// Initialize for Route -func (r *Route) postBuild() { - r.pathParts = tokenizePath(r.Path) - r.hasCustomVerb = hasCustomVerb(r.Path) -} - -// Create Request and Response from their http versions -func (r *Route) wrapRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request, pathParams map[string]string) (*Request, *Response) { - wrappedRequest := NewRequest(httpRequest) - wrappedRequest.pathParameters = pathParams - wrappedRequest.selectedRoute = r - wrappedResponse := NewResponse(httpWriter) - wrappedResponse.requestAccept = httpRequest.Header.Get(HEADER_Accept) - wrappedResponse.routeProduces = r.Produces - return wrappedRequest, wrappedResponse -} - -func stringTrimSpaceCutset(r rune) bool { - return r == ' ' -} - -// Return whether the mimeType matches to what this Route can produce. -func (r Route) matchesAccept(mimeTypesWithQuality string) bool { - remaining := mimeTypesWithQuality - for { - var mimeType string - if end := strings.Index(remaining, ","); end == -1 { - mimeType, remaining = remaining, "" - } else { - mimeType, remaining = remaining[:end], remaining[end+1:] - } - if quality := strings.Index(mimeType, ";"); quality != -1 { - mimeType = mimeType[:quality] - } - mimeType = strings.TrimFunc(mimeType, stringTrimSpaceCutset) - if mimeType == "*/*" { - return true - } - for _, producibleType := range r.Produces { - if producibleType == "*/*" || producibleType == mimeType { - return true - } - } - if len(remaining) == 0 { - return false - } - } -} - -// Return whether this Route can consume content with a type specified by mimeTypes (can be empty). -func (r Route) matchesContentType(mimeTypes string) bool { - - if len(r.Consumes) == 0 { - // did not specify what it can consume ; any media type (“*/*”) is assumed - return true - } - - if len(mimeTypes) == 0 { - // idempotent methods with (most-likely or guaranteed) empty content match missing Content-Type - m := r.Method - // if route specifies less or non-idempotent methods then use that - if len(r.allowedMethodsWithoutContentType) > 0 { - for _, each := range r.allowedMethodsWithoutContentType { - if m == each { - return true - } - } - } else { - if m == "GET" || m == "HEAD" || m == "OPTIONS" || m == "DELETE" || m == "TRACE" { - return true - } - } - // proceed with default - mimeTypes = MIME_OCTET - } - - remaining := mimeTypes - for { - var mimeType string - if end := strings.Index(remaining, ","); end == -1 { - mimeType, remaining = remaining, "" - } else { - mimeType, remaining = remaining[:end], remaining[end+1:] - } - if quality := strings.Index(mimeType, ";"); quality != -1 { - mimeType = mimeType[:quality] - } - mimeType = strings.TrimFunc(mimeType, stringTrimSpaceCutset) - for _, consumeableType := range r.Consumes { - if consumeableType == "*/*" || consumeableType == mimeType { - return true - } - } - if len(remaining) == 0 { - return false - } - } -} - -// Tokenize an URL path using the slash separator ; the result does not have empty tokens -func tokenizePath(path string) []string { - if "/" == path { - return nil - } - return strings.Split(strings.Trim(path, "/"), "/") -} - -// for debugging -func (r *Route) String() string { - return r.Method + " " + r.Path -} - -// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses. Overrides the container.contentEncodingEnabled value. -func (r *Route) EnableContentEncoding(enabled bool) { - r.contentEncodingEnabled = &enabled -} diff --git a/vendor/github.com/emicklei/go-restful/v3/route_builder.go b/vendor/github.com/emicklei/go-restful/v3/route_builder.go deleted file mode 100644 index 23641b6d..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/route_builder.go +++ /dev/null @@ -1,376 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "fmt" - "os" - "reflect" - "runtime" - "strings" - "sync/atomic" - - "github.com/emicklei/go-restful/v3/log" -) - -// RouteBuilder is a helper to construct Routes. -type RouteBuilder struct { - rootPath string - currentPath string - produces []string - consumes []string - httpMethod string // required - function RouteFunction // required - filters []FilterFunction - conditions []RouteSelectionConditionFunction - allowedMethodsWithoutContentType []string // see Route - - typeNameHandleFunc TypeNameHandleFunction // required - - // documentation - doc string - notes string - operation string - readSample, writeSample interface{} - parameters []*Parameter - errorMap map[int]ResponseError - defaultResponse *ResponseError - metadata map[string]interface{} - extensions map[string]interface{} - deprecated bool - contentEncodingEnabled *bool -} - -// Do evaluates each argument with the RouteBuilder itself. -// This allows you to follow DRY principles without breaking the fluent programming style. -// Example: -// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500)) -// -// func Returns500(b *RouteBuilder) { -// b.Returns(500, "Internal Server Error", restful.ServiceError{}) -// } -func (b *RouteBuilder) Do(oneArgBlocks ...func(*RouteBuilder)) *RouteBuilder { - for _, each := range oneArgBlocks { - each(b) - } - return b -} - -// To bind the route to a function. -// If this route is matched with the incoming Http Request then call this function with the *Request,*Response pair. Required. -func (b *RouteBuilder) To(function RouteFunction) *RouteBuilder { - b.function = function - return b -} - -// Method specifies what HTTP method to match. Required. -func (b *RouteBuilder) Method(method string) *RouteBuilder { - b.httpMethod = method - return b -} - -// Produces specifies what MIME types can be produced ; the matched one will appear in the Content-Type Http header. -func (b *RouteBuilder) Produces(mimeTypes ...string) *RouteBuilder { - b.produces = mimeTypes - return b -} - -// Consumes specifies what MIME types can be consumes ; the Accept Http header must matched any of these -func (b *RouteBuilder) Consumes(mimeTypes ...string) *RouteBuilder { - b.consumes = mimeTypes - return b -} - -// Path specifies the relative (w.r.t WebService root path) URL path to match. Default is "/". -func (b *RouteBuilder) Path(subPath string) *RouteBuilder { - b.currentPath = subPath - return b -} - -// Doc tells what this route is all about. Optional. -func (b *RouteBuilder) Doc(documentation string) *RouteBuilder { - b.doc = documentation - return b -} - -// Notes is a verbose explanation of the operation behavior. Optional. -func (b *RouteBuilder) Notes(notes string) *RouteBuilder { - b.notes = notes - return b -} - -// Reads tells what resource type will be read from the request payload. Optional. -// A parameter of type "body" is added ,required is set to true and the dataType is set to the qualified name of the sample's type. -func (b *RouteBuilder) Reads(sample interface{}, optionalDescription ...string) *RouteBuilder { - fn := b.typeNameHandleFunc - if fn == nil { - fn = reflectTypeName - } - typeAsName := fn(sample) - description := "" - if len(optionalDescription) > 0 { - description = optionalDescription[0] - } - b.readSample = sample - bodyParameter := &Parameter{&ParameterData{Name: "body", Description: description}} - bodyParameter.beBody() - bodyParameter.Required(true) - bodyParameter.DataType(typeAsName) - b.Param(bodyParameter) - return b -} - -// ParameterNamed returns a Parameter already known to the RouteBuilder. Returns nil if not. -// Use this to modify or extend information for the Parameter (through its Data()). -func (b RouteBuilder) ParameterNamed(name string) (p *Parameter) { - for _, each := range b.parameters { - if each.Data().Name == name { - return each - } - } - return p -} - -// Writes tells what resource type will be written as the response payload. Optional. -func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder { - b.writeSample = sample - return b -} - -// Param allows you to document the parameters of the Route. It adds a new Parameter (does not check for duplicates). -func (b *RouteBuilder) Param(parameter *Parameter) *RouteBuilder { - if b.parameters == nil { - b.parameters = []*Parameter{} - } - b.parameters = append(b.parameters, parameter) - return b -} - -// Operation allows you to document what the actual method/function call is of the Route. -// Unless called, the operation name is derived from the RouteFunction set using To(..). -func (b *RouteBuilder) Operation(name string) *RouteBuilder { - b.operation = name - return b -} - -// ReturnsError is deprecated, use Returns instead. -func (b *RouteBuilder) ReturnsError(code int, message string, model interface{}) *RouteBuilder { - log.Print("ReturnsError is deprecated, use Returns instead.") - return b.Returns(code, message, model) -} - -// Returns allows you to document what responses (errors or regular) can be expected. -// The model parameter is optional ; either pass a struct instance or use nil if not applicable. -func (b *RouteBuilder) Returns(code int, message string, model interface{}) *RouteBuilder { - err := ResponseError{ - Code: code, - Message: message, - Model: model, - IsDefault: false, // this field is deprecated, use default response instead. - } - // lazy init because there is no NewRouteBuilder (yet) - if b.errorMap == nil { - b.errorMap = map[int]ResponseError{} - } - b.errorMap[code] = err - return b -} - -// ReturnsWithHeaders is similar to Returns, but can specify response headers -func (b *RouteBuilder) ReturnsWithHeaders(code int, message string, model interface{}, headers map[string]Header) *RouteBuilder { - b.Returns(code, message, model) - err := b.errorMap[code] - err.Headers = headers - b.errorMap[code] = err - return b -} - -// DefaultReturns is a special Returns call that sets the default of the response. -func (b *RouteBuilder) DefaultReturns(message string, model interface{}) *RouteBuilder { - b.defaultResponse = &ResponseError{ - Message: message, - Model: model, - } - return b -} - -// Metadata adds or updates a key=value pair to the metadata map. -func (b *RouteBuilder) Metadata(key string, value interface{}) *RouteBuilder { - if b.metadata == nil { - b.metadata = map[string]interface{}{} - } - b.metadata[key] = value - return b -} - -// AddExtension adds or updates a key=value pair to the extensions map. -func (b *RouteBuilder) AddExtension(key string, value interface{}) *RouteBuilder { - if b.extensions == nil { - b.extensions = map[string]interface{}{} - } - b.extensions[key] = value - return b -} - -// Deprecate sets the value of deprecated to true. Deprecated routes have a special UI treatment to warn against use -func (b *RouteBuilder) Deprecate() *RouteBuilder { - b.deprecated = true - return b -} - -// AllowedMethodsWithoutContentType overrides the default list GET,HEAD,OPTIONS,DELETE,TRACE -// If a request does not include a content-type header then -// depending on the method, it may return a 415 Unsupported Media. -// Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,... -func (b *RouteBuilder) AllowedMethodsWithoutContentType(methods []string) *RouteBuilder { - b.allowedMethodsWithoutContentType = methods - return b -} - -// ResponseError represents a response; not necessarily an error. -type ResponseError struct { - ExtensionProperties - Code int - Message string - Model interface{} - Headers map[string]Header - IsDefault bool -} - -// Header describes a header for a response of the API -// -// For more information: http://goo.gl/8us55a#headerObject -type Header struct { - *Items - Description string -} - -// Items describe swagger simple schemas for headers -type Items struct { - Type string - Format string - Items *Items - CollectionFormat string - Default interface{} -} - -func (b *RouteBuilder) servicePath(path string) *RouteBuilder { - b.rootPath = path - return b -} - -// Filter appends a FilterFunction to the end of filters for this Route to build. -func (b *RouteBuilder) Filter(filter FilterFunction) *RouteBuilder { - b.filters = append(b.filters, filter) - return b -} - -// If sets a condition function that controls matching the Route based on custom logic. -// The condition function is provided the HTTP request and should return true if the route -// should be considered. -// -// Efficiency note: the condition function is called before checking the method, produces, and -// consumes criteria, so that the correct HTTP status code can be returned. -// -// Lifecycle note: no filter functions have been called prior to calling the condition function, -// so the condition function should not depend on any context that might be set up by container -// or route filters. -func (b *RouteBuilder) If(condition RouteSelectionConditionFunction) *RouteBuilder { - b.conditions = append(b.conditions, condition) - return b -} - -// ContentEncodingEnabled allows you to override the Containers value for auto-compressing this route response. -func (b *RouteBuilder) ContentEncodingEnabled(enabled bool) *RouteBuilder { - b.contentEncodingEnabled = &enabled - return b -} - -// If no specific Route path then set to rootPath -// If no specific Produces then set to rootProduces -// If no specific Consumes then set to rootConsumes -func (b *RouteBuilder) copyDefaults(rootProduces, rootConsumes []string) { - if len(b.produces) == 0 { - b.produces = rootProduces - } - if len(b.consumes) == 0 { - b.consumes = rootConsumes - } -} - -// typeNameHandler sets the function that will convert types to strings in the parameter -// and model definitions. -func (b *RouteBuilder) typeNameHandler(handler TypeNameHandleFunction) *RouteBuilder { - b.typeNameHandleFunc = handler - return b -} - -// Build creates a new Route using the specification details collected by the RouteBuilder -func (b *RouteBuilder) Build() Route { - pathExpr, err := newPathExpression(b.currentPath) - if err != nil { - log.Printf("Invalid path:%s because:%v", b.currentPath, err) - os.Exit(1) - } - if b.function == nil { - log.Printf("No function specified for route:" + b.currentPath) - os.Exit(1) - } - operationName := b.operation - if len(operationName) == 0 && b.function != nil { - // extract from definition - operationName = nameOfFunction(b.function) - } - route := Route{ - Method: b.httpMethod, - Path: concatPath(b.rootPath, b.currentPath), - Produces: b.produces, - Consumes: b.consumes, - Function: b.function, - Filters: b.filters, - If: b.conditions, - relativePath: b.currentPath, - pathExpr: pathExpr, - Doc: b.doc, - Notes: b.notes, - Operation: operationName, - ParameterDocs: b.parameters, - ResponseErrors: b.errorMap, - DefaultResponse: b.defaultResponse, - ReadSample: b.readSample, - WriteSample: b.writeSample, - Metadata: b.metadata, - Deprecated: b.deprecated, - contentEncodingEnabled: b.contentEncodingEnabled, - allowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType, - } - route.Extensions = b.extensions - route.postBuild() - return route -} - -func concatPath(path1, path2 string) string { - return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/") -} - -var anonymousFuncCount int32 - -// nameOfFunction returns the short name of the function f for documentation. -// It uses a runtime feature for debugging ; its value may change for later Go versions. -func nameOfFunction(f interface{}) string { - fun := runtime.FuncForPC(reflect.ValueOf(f).Pointer()) - tokenized := strings.Split(fun.Name(), ".") - last := tokenized[len(tokenized)-1] - last = strings.TrimSuffix(last, ")·fm") // < Go 1.5 - last = strings.TrimSuffix(last, ")-fm") // Go 1.5 - last = strings.TrimSuffix(last, "·fm") // < Go 1.5 - last = strings.TrimSuffix(last, "-fm") // Go 1.5 - if last == "func1" { // this could mean conflicts in API docs - val := atomic.AddInt32(&anonymousFuncCount, 1) - last = "func" + fmt.Sprintf("%d", val) - atomic.StoreInt32(&anonymousFuncCount, val) - } - return last -} diff --git a/vendor/github.com/emicklei/go-restful/v3/route_reader.go b/vendor/github.com/emicklei/go-restful/v3/route_reader.go deleted file mode 100644 index c9f4ee75..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/route_reader.go +++ /dev/null @@ -1,66 +0,0 @@ -package restful - -// Copyright 2021 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -type RouteReader interface { - Method() string - Consumes() []string - Path() string - Doc() string - Notes() string - Operation() string - ParameterDocs() []*Parameter - // Returns a copy - Metadata() map[string]interface{} - Deprecated() bool -} - -type routeAccessor struct { - route *Route -} - -func (r routeAccessor) Method() string { - return r.route.Method -} -func (r routeAccessor) Consumes() []string { - return r.route.Consumes[:] -} -func (r routeAccessor) Path() string { - return r.route.Path -} -func (r routeAccessor) Doc() string { - return r.route.Doc -} -func (r routeAccessor) Notes() string { - return r.route.Notes -} -func (r routeAccessor) Operation() string { - return r.route.Operation -} -func (r routeAccessor) ParameterDocs() []*Parameter { - return r.route.ParameterDocs[:] -} - -// Returns a copy -func (r routeAccessor) Metadata() map[string]interface{} { - return copyMap(r.route.Metadata) -} -func (r routeAccessor) Deprecated() bool { - return r.route.Deprecated -} - -// https://stackoverflow.com/questions/23057785/how-to-copy-a-map -func copyMap(m map[string]interface{}) map[string]interface{} { - cp := make(map[string]interface{}) - for k, v := range m { - vm, ok := v.(map[string]interface{}) - if ok { - cp[k] = copyMap(vm) - } else { - cp[k] = v - } - } - return cp -} diff --git a/vendor/github.com/emicklei/go-restful/v3/router.go b/vendor/github.com/emicklei/go-restful/v3/router.go deleted file mode 100644 index 19078af1..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/router.go +++ /dev/null @@ -1,20 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import "net/http" - -// A RouteSelector finds the best matching Route given the input HTTP Request -// RouteSelectors can optionally also implement the PathProcessor interface to also calculate the -// path parameters after the route has been selected. -type RouteSelector interface { - - // SelectRoute finds a Route given the input HTTP Request and a list of WebServices. - // It returns a selected Route and its containing WebService or an error indicating - // a problem. - SelectRoute( - webServices []*WebService, - httpRequest *http.Request) (selectedService *WebService, selected *Route, err error) -} diff --git a/vendor/github.com/emicklei/go-restful/v3/service_error.go b/vendor/github.com/emicklei/go-restful/v3/service_error.go deleted file mode 100644 index a4157546..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/service_error.go +++ /dev/null @@ -1,32 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "fmt" - "net/http" -) - -// ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request. -type ServiceError struct { - Code int - Message string - Header http.Header -} - -// NewError returns a ServiceError using the code and reason -func NewError(code int, message string) ServiceError { - return ServiceError{Code: code, Message: message} -} - -// NewErrorWithHeader returns a ServiceError using the code, reason and header -func NewErrorWithHeader(code int, message string, header http.Header) ServiceError { - return ServiceError{Code: code, Message: message, Header: header} -} - -// Error returns a text representation of the service error -func (s ServiceError) Error() string { - return fmt.Sprintf("[ServiceError:%v] %v", s.Code, s.Message) -} diff --git a/vendor/github.com/emicklei/go-restful/v3/web_service.go b/vendor/github.com/emicklei/go-restful/v3/web_service.go deleted file mode 100644 index 0bf5d1e5..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/web_service.go +++ /dev/null @@ -1,293 +0,0 @@ -package restful - -import ( - "errors" - "os" - "reflect" - "sync" - - "github.com/emicklei/go-restful/v3/log" -) - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -// WebService holds a collection of Route values that bind a Http Method + URL Path to a function. -type WebService struct { - rootPath string - pathExpr *pathExpression // cached compilation of rootPath as RegExp - routes []Route - produces []string - consumes []string - pathParameters []*Parameter - filters []FilterFunction - documentation string - apiVersion string - - typeNameHandleFunc TypeNameHandleFunction - - dynamicRoutes bool - - // protects 'routes' if dynamic routes are enabled - routesLock sync.RWMutex -} - -func (w *WebService) SetDynamicRoutes(enable bool) { - w.dynamicRoutes = enable -} - -// TypeNameHandleFunction declares functions that can handle translating the name of a sample object -// into the restful documentation for the service. -type TypeNameHandleFunction func(sample interface{}) string - -// TypeNameHandler sets the function that will convert types to strings in the parameter -// and model definitions. If not set, the web service will invoke -// reflect.TypeOf(object).String(). -func (w *WebService) TypeNameHandler(handler TypeNameHandleFunction) *WebService { - w.typeNameHandleFunc = handler - return w -} - -// reflectTypeName is the default TypeNameHandleFunction and for a given object -// returns the name that Go identifies it with (e.g. "string" or "v1.Object") via -// the reflection API. -func reflectTypeName(sample interface{}) string { - return reflect.TypeOf(sample).String() -} - -// compilePathExpression ensures that the path is compiled into a RegEx for those routers that need it. -func (w *WebService) compilePathExpression() { - compiled, err := newPathExpression(w.rootPath) - if err != nil { - log.Printf("invalid path:%s because:%v", w.rootPath, err) - os.Exit(1) - } - w.pathExpr = compiled -} - -// ApiVersion sets the API version for documentation purposes. -func (w *WebService) ApiVersion(apiVersion string) *WebService { - w.apiVersion = apiVersion - return w -} - -// Version returns the API version for documentation purposes. -func (w *WebService) Version() string { return w.apiVersion } - -// Path specifies the root URL template path of the WebService. -// All Routes will be relative to this path. -func (w *WebService) Path(root string) *WebService { - w.rootPath = root - if len(w.rootPath) == 0 { - w.rootPath = "/" - } - w.compilePathExpression() - return w -} - -// Param adds a PathParameter to document parameters used in the root path. -func (w *WebService) Param(parameter *Parameter) *WebService { - if w.pathParameters == nil { - w.pathParameters = []*Parameter{} - } - w.pathParameters = append(w.pathParameters, parameter) - return w -} - -// PathParameter creates a new Parameter of kind Path for documentation purposes. -// It is initialized as required with string as its DataType. -func (w *WebService) PathParameter(name, description string) *Parameter { - return PathParameter(name, description) -} - -// PathParameter creates a new Parameter of kind Path for documentation purposes. -// It is initialized as required with string as its DataType. -func PathParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: true, DataType: "string"}} - p.bePath() - return p -} - -// QueryParameter creates a new Parameter of kind Query for documentation purposes. -// It is initialized as not required with string as its DataType. -func (w *WebService) QueryParameter(name, description string) *Parameter { - return QueryParameter(name, description) -} - -// QueryParameter creates a new Parameter of kind Query for documentation purposes. -// It is initialized as not required with string as its DataType. -func QueryParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string", CollectionFormat: CollectionFormatCSV.String()}} - p.beQuery() - return p -} - -// BodyParameter creates a new Parameter of kind Body for documentation purposes. -// It is initialized as required without a DataType. -func (w *WebService) BodyParameter(name, description string) *Parameter { - return BodyParameter(name, description) -} - -// BodyParameter creates a new Parameter of kind Body for documentation purposes. -// It is initialized as required without a DataType. -func BodyParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: true}} - p.beBody() - return p -} - -// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes. -// It is initialized as not required with string as its DataType. -func (w *WebService) HeaderParameter(name, description string) *Parameter { - return HeaderParameter(name, description) -} - -// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes. -// It is initialized as not required with string as its DataType. -func HeaderParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}} - p.beHeader() - return p -} - -// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes. -// It is initialized as required with string as its DataType. -func (w *WebService) FormParameter(name, description string) *Parameter { - return FormParameter(name, description) -} - -// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes. -// It is initialized as required with string as its DataType. -func FormParameter(name, description string) *Parameter { - p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}} - p.beForm() - return p -} - -// Route creates a new Route using the RouteBuilder and add to the ordered list of Routes. -func (w *WebService) Route(builder *RouteBuilder) *WebService { - w.routesLock.Lock() - defer w.routesLock.Unlock() - builder.copyDefaults(w.produces, w.consumes) - w.routes = append(w.routes, builder.Build()) - return w -} - -// RemoveRoute removes the specified route, looks for something that matches 'path' and 'method' -func (w *WebService) RemoveRoute(path, method string) error { - if !w.dynamicRoutes { - return errors.New("dynamic routes are not enabled.") - } - w.routesLock.Lock() - defer w.routesLock.Unlock() - newRoutes := []Route{} - for _, route := range w.routes { - if route.Method == method && route.Path == path { - continue - } - newRoutes = append(newRoutes, route) - } - w.routes = newRoutes - return nil -} - -// Method creates a new RouteBuilder and initialize its http method -func (w *WebService) Method(httpMethod string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(httpMethod) -} - -// Produces specifies that this WebService can produce one or more MIME types. -// Http requests must have one of these values set for the Accept header. -func (w *WebService) Produces(contentTypes ...string) *WebService { - w.produces = contentTypes - return w -} - -// Consumes specifies that this WebService can consume one or more MIME types. -// Http requests must have one of these values set for the Content-Type header. -func (w *WebService) Consumes(accepts ...string) *WebService { - w.consumes = accepts - return w -} - -// Routes returns the Routes associated with this WebService -func (w *WebService) Routes() []Route { - if !w.dynamicRoutes { - return w.routes - } - // Make a copy of the array to prevent concurrency problems - w.routesLock.RLock() - defer w.routesLock.RUnlock() - result := make([]Route, len(w.routes)) - for ix := range w.routes { - result[ix] = w.routes[ix] - } - return result -} - -// RootPath returns the RootPath associated with this WebService. Default "/" -func (w *WebService) RootPath() string { - return w.rootPath -} - -// PathParameters return the path parameter names for (shared among its Routes) -func (w *WebService) PathParameters() []*Parameter { - return w.pathParameters -} - -// Filter adds a filter function to the chain of filters applicable to all its Routes -func (w *WebService) Filter(filter FilterFunction) *WebService { - w.filters = append(w.filters, filter) - return w -} - -// Doc is used to set the documentation of this service. -func (w *WebService) Doc(plainText string) *WebService { - w.documentation = plainText - return w -} - -// Documentation returns it. -func (w *WebService) Documentation() string { - return w.documentation -} - -/* - Convenience methods -*/ - -// HEAD is a shortcut for .Method("HEAD").Path(subPath) -func (w *WebService) HEAD(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("HEAD").Path(subPath) -} - -// GET is a shortcut for .Method("GET").Path(subPath) -func (w *WebService) GET(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("GET").Path(subPath) -} - -// POST is a shortcut for .Method("POST").Path(subPath) -func (w *WebService) POST(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("POST").Path(subPath) -} - -// PUT is a shortcut for .Method("PUT").Path(subPath) -func (w *WebService) PUT(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("PUT").Path(subPath) -} - -// PATCH is a shortcut for .Method("PATCH").Path(subPath) -func (w *WebService) PATCH(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("PATCH").Path(subPath) -} - -// DELETE is a shortcut for .Method("DELETE").Path(subPath) -func (w *WebService) DELETE(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("DELETE").Path(subPath) -} - -// OPTIONS is a shortcut for .Method("OPTIONS").Path(subPath) -func (w *WebService) OPTIONS(subPath string) *RouteBuilder { - return new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method("OPTIONS").Path(subPath) -} diff --git a/vendor/github.com/emicklei/go-restful/v3/web_service_container.go b/vendor/github.com/emicklei/go-restful/v3/web_service_container.go deleted file mode 100644 index c9d31b06..00000000 --- a/vendor/github.com/emicklei/go-restful/v3/web_service_container.go +++ /dev/null @@ -1,39 +0,0 @@ -package restful - -// Copyright 2013 Ernest Micklei. All rights reserved. -// Use of this source code is governed by a license -// that can be found in the LICENSE file. - -import ( - "net/http" -) - -// DefaultContainer is a restful.Container that uses http.DefaultServeMux -var DefaultContainer *Container - -func init() { - DefaultContainer = NewContainer() - DefaultContainer.ServeMux = http.DefaultServeMux -} - -// If set the true then panics will not be caught to return HTTP 500. -// In that case, Route functions are responsible for handling any error situation. -// Default value is false = recover from panics. This has performance implications. -// OBSOLETE ; use restful.DefaultContainer.DoNotRecover(true) -var DoNotRecover = false - -// Add registers a new WebService add it to the DefaultContainer. -func Add(service *WebService) { - DefaultContainer.Add(service) -} - -// Filter appends a container FilterFunction from the DefaultContainer. -// These are called before dispatching a http.Request to a WebService. -func Filter(filter FilterFunction) { - DefaultContainer.Filter(filter) -} - -// RegisteredWebServices returns the collections of WebServices from the DefaultContainer -func RegisteredWebServices() []*WebService { - return DefaultContainer.RegisteredWebServices() -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/LICENSE b/vendor/github.com/falcosecurity/plugin-sdk-go/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/LICENSE +++ /dev/null @@ -1,201 +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/falcosecurity/plugin-sdk-go/pkg/cgo/handle.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/cgo/handle.go deleted file mode 100644 index 580f955c..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/cgo/handle.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cgo - -// Handle is an alternative implementation of cgo.Handle introduced by -// Go 1.17, see https://pkg.go.dev/runtime/cgo. This implementation -// optimizes performance in use cases related to plugins. It is intended -// to be used both as a replacement and as a polyfill for Go versions -// that miss it. -// -// As the original implementation, this provides a way to pass values that -// contain Go pointers between Go and C without breaking the cgo pointer -// passing rules. The underlying type of Handle is guaranteed to fit in -// an integer type that is large enough to hold the bit pattern of any pointer. -// The zero value of a Handle is not valid and thus is safe to use as -// a sentinel in C APIs. -// -// The performance optimization comes with a limitation: the maximum number -// of valid handles is capped to a fixed value (see MaxHandle). -// However, since the intended usage is to pass opaque pointers holding the -// plugin states (usually at most two pointers per one instance of a plugin), -// this hard limit is considered acceptable. -// -// The thread-safety guarantees have been dropped for further -// performance improvements. The current version of the Plugin API does not -// require thread safety. -// -// The usage in other contexts is discuraged. -type Handle uintptr - -// MaxHandle is the largest value that an Handle can hold -const MaxHandle = 32 - 1 - -var ( - handles [MaxHandle + 1]interface{} // [int]interface{} - noHandle int = 0 -) - -func init() { - resetHandles() -} - -// NewHandle returns a handle for a given value. -// -// The handle is valid until the program calls Delete on it. The handle -// uses resources, and this package assumes that C code may hold on to -// the handle, so a program must explicitly call Delete when the handle -// is no longer needed. Programs must not retain deleted handles. -// -// The intended use is to pass the returned handle to C code, which -// passes it back to Go, which calls Value. -// -// The simultaneous number of the valid handles cannot exceed MaxHandle. -// This function panics if there are no more handles available. -// Previously created handles may be made available again when -// invalidated with Delete. -// -// This function is not thread-safe. -func NewHandle(v interface{}) Handle { - for i := 1; i <= MaxHandle; i++ { - if handles[i] == &noHandle { - handles[i] = v - return Handle(i) - } - } - panic("plugin-sdk-go/cgo: ran out of handle space") -} - -// Value returns the associated Go value for a valid handle. -// -// The method panics if the handle is invalid. -// This function is not thread-safe. -func (h Handle) Value() interface{} { - if h > MaxHandle || handles[h] == &noHandle { - panic("plugin-sdk-go/cgo: misuse of an invalid Handle") - } - return handles[h] -} - -// Delete invalidates a handle. This method should only be called once -// the program no longer needs to pass the handle to C and the C code -// no longer has a copy of the handle value. -// -// The method panics if the handle is invalid. -// This function is not thread-safe. -func (h Handle) Delete() { - if h > MaxHandle || handles[h] == &noHandle { - panic("plugin-sdk-go/cgo: misuse of an invalid Handle") - } - handles[h] = &noHandle -} - -func resetHandles() { - for i := 0; i <= MaxHandle; i++ { - handles[i] = &noHandle - } -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/ptr/bytes.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/ptr/bytes.go deleted file mode 100644 index 225af3fa..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/ptr/bytes.go +++ /dev/null @@ -1,189 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ptr - -/* -#include -#include -*/ -import "C" -import ( - "fmt" - "io" - "reflect" - "unsafe" -) - -const ( - offsetErrorFmt = "invalid offset value %d" - lengthErrorFmt = "invalid length value %d" - capacityErrorFmt = "invalid capacity value %d" - whenceErrorFmt = "invalid whence value %d" - bufferErrorFmt = "invalid buffer value" -) - -// Integer limit values. -// todo: math.MaxInt was introduced by golang 1.17 (see https://golang.org/doc/go1.17) -const ( - intSize = 32 << (^uint(0) >> 63) // 32 or 64 - maxInt = 1<<(intSize-1) - 1 -) - -// BytesReadWriter is an opaque wrapper for fixed-size memory buffers, that can safely be -// used in the plugin framework in a Go-friendly way. The purpose is to allow safe memory -// access through the read/write interface primitives, regardless of how the buffer is -// physically allocated under the hood. For instance, this can be used to wrap C-allocated -// buffers to hide both the type conversion magic and prevent illegal memory operations. -// -// The io.ReadWriteSeeker interface is leveraged to implement the safe random memory -// access semantic. Note, read-only or write-only access to the memory buffer -// can easily be accomplished by casting instances of this interface to either a io.Reader -// or a io.Writer. -type BytesReadWriter interface { - io.ReadWriteSeeker - // - // BufferPtr returns an unsafe.Pointer that points to the underlying memory buffer. - BufferPtr() unsafe.Pointer - // - // Len returns the total number of accessible bytes for reading and writing. - Len() int64 - // - // SetLen sets the total number of accessible bytes for reading and writing. - // The new length value should not be larger than the underlying memory buffer capacity. - // If a greater value is given, the length is set to be equal to the capacity. - // If a value less than zero is given, the length is set to be zero. - SetLen(len int64) - // - // Offset returns the current cursor position relatively to the underlying buffer. - // The cursor position represents the index of the next byte in the buffer that will - // be available for read\write operations. This value is altered through the usage of - // Seek, Read, and Write. By definition, we have that 0 <= Offset() <= Len(). - Offset() int64 -} - -// NewBytesReadWriter creates a new instance of BytesReadWriter by wrapping the memory pointed -// by the buffer argument. The length argument is the total number of accessible bytes -// for reading and writing. The capacity argument is the number of bytes in the given buffer. -// -// Note that the capacity cannot be changed after creation, and that the length cannot ever exceed -// the capacity. -func NewBytesReadWriter(buffer unsafe.Pointer, length, capacity int64) (BytesReadWriter, error) { - if buffer == nil { - return nil, fmt.Errorf(bufferErrorFmt) - } - if capacity < 0 || capacity > maxInt { - return nil, fmt.Errorf(capacityErrorFmt, capacity) - } - if length < 0 || length > capacity { - return nil, fmt.Errorf(lengthErrorFmt, length) - } - // Inspired by: https://stackoverflow.com/a/66218124 - var bytes []byte - (*reflect.SliceHeader)(unsafe.Pointer(&bytes)).Data = uintptr(buffer) - (*reflect.SliceHeader)(unsafe.Pointer(&bytes)).Len = int(capacity) - (*reflect.SliceHeader)(unsafe.Pointer(&bytes)).Cap = int(capacity) - return &bytesReadWriter{ - buffer: buffer, - bytesAlias: bytes, - offset: 0, - len: length, - }, nil -} - -type bytesReadWriter struct { - offset int64 - len int64 - buffer unsafe.Pointer - bytesAlias []byte -} - -func (b *bytesReadWriter) Read(p []byte) (n int, err error) { - n = 0 - pLen := len(p) - for i := 0; i < pLen; i++ { - if b.offset >= b.len { - err = io.EOF - return - } - p[i] = b.bytesAlias[b.offset] - b.offset++ - n++ - } - return -} - -func (b *bytesReadWriter) Write(p []byte) (n int, err error) { - n = 0 - for _, v := range p { - if b.offset >= b.len { - err = io.ErrShortWrite - return - } - b.bytesAlias[b.offset] = v - b.offset++ - n++ - } - return -} - -func (b *bytesReadWriter) Len() int64 { - return b.len -} - -func (b *bytesReadWriter) SetLen(len int64) { - if len < 0 { - b.len = 0 - } else if len > int64(cap(b.bytesAlias)) { - b.len = int64(cap(b.bytesAlias)) - } else { - b.len = len - } -} - -func (b *bytesReadWriter) Offset() int64 { - return b.offset -} - -func (b *bytesReadWriter) Seek(offset int64, whence int) (int64, error) { - if offset < 0 { - return b.offset, fmt.Errorf(offsetErrorFmt, offset) - } - switch whence { - case io.SeekStart: - b.offset = offset - if offset > b.len { - return b.offset, fmt.Errorf(offsetErrorFmt, offset) - } - case io.SeekCurrent: - if offset > b.len-b.offset { - return b.offset, fmt.Errorf(offsetErrorFmt, offset) - } - b.offset = b.offset + offset - case io.SeekEnd: - if offset > b.len { - return b.offset, fmt.Errorf(offsetErrorFmt, offset) - } - b.offset = b.len - offset - default: - return b.offset, fmt.Errorf(whenceErrorFmt, whence) - } - return b.offset, nil -} - -func (b *bytesReadWriter) BufferPtr() unsafe.Pointer { - return b.buffer -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/ptr/string.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/ptr/string.go deleted file mode 100644 index 8077d08a..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/ptr/string.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ptr - -/* -#include -*/ -import "C" -import ( - "reflect" - "unsafe" -) - -const ( - cStringNullTerminator = byte(0) -) - -// GoString converts a C string to a Go string. This is analoguous -// to C.GoString, but avoids unnecessary memory allcations and copies. -// The string length is determined by invoking strlen on the passed -// memory pointer. -// Note that the returned string is an aliased view of the underlying -// C-allocated memory. As such, writing inside the memory will cause -// the string contents to change. Accordingly, unsafe memory management, -// such as unexpectedly free-ing the underlying C memory, can cause -// non-deterministic behavior on the Go routines using the returned string. -func GoString(charPtr unsafe.Pointer) string { - if charPtr == nil { - return "" - } - - // We manually implement strlen to avoid an unnecessary Go -> C call. - // See: https://github.com/torvalds/linux/blob/f6274b06e326d8471cdfb52595f989a90f5e888f/lib/string.c#L558 - var len int - for len = 0; *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(charPtr)) + uintptr(len))) != cStringNullTerminator; len++ { - // nothing - } - - var res string - (*reflect.StringHeader)(unsafe.Pointer(&res)).Data = uintptr(charPtr) - (*reflect.StringHeader)(unsafe.Pointer(&res)).Len = len - return res -} - -// StringBuffer represents a buffer for C-allocated null-terminated strings -// in a Go-friendly way. This is an implementation of the sdk.StringBuffer -// interface. The underlying memory buffer is allocated and resized -// automatically. The buffer allocation happens lazily at the first call -// to Write. If during a call to Write the converted string is too large -// to fit in the buffer, it gets resized automatically to a proper size. -type StringBuffer struct { - cPtr *C.char - len int -} - -func (s *StringBuffer) Write(str string) { - if s.cPtr == nil || len(str) > s.len { - if s.cPtr != nil { - C.free(unsafe.Pointer(s.cPtr)) - } - s.cPtr = (*C.char)(C.malloc((C.size_t)(len(str) + 1))) - } - - p := (*[1 << 30]byte)(unsafe.Pointer(s.cPtr)) - copy(p[:], str) - p[len(str)] = cStringNullTerminator - s.len = len(str) -} - -func (s *StringBuffer) CharPtr() unsafe.Pointer { - return unsafe.Pointer(s.cPtr) -} - -func (s *StringBuffer) String() string { - return GoString(unsafe.Pointer(s.cPtr)) -} - -func (s *StringBuffer) Free() { - if s.cPtr != nil { - C.free(unsafe.Pointer(s.cPtr)) - s.cPtr = nil - } -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/buffers.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/buffers.go deleted file mode 100644 index 0998ad9b..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/buffers.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sdk - -import "unsafe" - -// StringBuffer represents a buffer for C-allocated null-terminated strings -// in a Go-friendly way. Unlike the C.CString function, this interface helps -// convert a Go string in a C-like one by always reusing the same buffer. -// Implementations of this interface must take care of allocating the -// underlying C buffer. -type StringBuffer interface { - // Write writes a Go string inside the buffer, converting it to a C-like - // null-terminated string. Implementations of this interface must handle - // the case in which the buffer is not large enough to host the converted - // string. - Write(string) - // - // String returns a Go string obtained by converting the C-like string - // currently stored in the buffer. If the buffer is empty, an empty string - // is returned. - String() string - // - // CharPtr returns an unsafe pointer to the underlying C-allocated - // char* buffer. Freeing the returned pointer by any sort of deallocator - // (C.free or similars) can lead to undefined behavior. - CharPtr() unsafe.Pointer - // - // Free deallocates the underlying C-allocated buffer. - Free() -} - -// LastErrorBuffer is an interface wrapping the basic LastErrorBuffer method. -// LastErrorBuffer returns a StringBuffer meant to be used as buffer for -// plugin_get_last_error(). -type LastErrorBuffer interface { - LastErrorBuffer() StringBuffer -} - -// StringerBuffer is an interface wrapping the basic StringerBuffer method. -// StringerBuffer returns a StringBuffer meant to be used as buffer for -// plugin_event_to_string(). -type StringerBuffer interface { - StringerBuffer() StringBuffer -} - -// ProgressBuffer is an interface wrapping the basic ProgressBuffer method. -// ProgressBuffer returns a StringBuffer meant to be used as buffer for -// plugin_get_progress(). -type ProgressBuffer interface { - ProgressBuffer() StringBuffer -} - -// OpenParamsBuffer is an interface wrapping the basic OpenParamsBuffer method. -// OpenParamsBuffer returns a StringBuffer meant to be used as buffer for -// plugin_list_open_params(). -type OpenParamsBuffer interface { - OpenParamsBuffer() StringBuffer -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/doc.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/doc.go deleted file mode 100644 index eaec75e5..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/doc.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package sdk provides definitions and constructs for developers that -// would like to write Falcosecurity Plugins (https://falco.org/docs/plugins/) -// in Go. -// -// Before using this package, review the developer's guide -// (https://falco.org/docs/plugins/developers_guide/) which fully documents -// the API and provides best practices for writing plugins. -// The developer's guide includes a walkthrough -// (https://falco.org/docs/plugins/developers_guide/#example-go-plugin-dummy) -// of a plugin written in Go that uses this package. -// -// For a quick start, you can refer to the provided examples of plugins with -// field extraction capability -// (https://github.com/falcosecurity/plugin-sdk-go/tree/main/examples/extractor), -// with event sourcing capability, -// (https://github.com/falcosecurity/plugin-sdk-go/tree/main/examples/source), -// and with both -// (https://github.com/falcosecurity/plugin-sdk-go/tree/main/examples/full). -// -// This SDK is designed to be layered with different levels of abstraction: -// -// 1. The "sdk/plugins" package provide high-level constructs to easily develop -// plugins in a Go-friendly way, by abstracting all the low-level details -// of the plugin framework and by avoiding the need of useless boilerplate code. -// This package is the way to go for developers to start building plugins. -// -// 2. The "sdk/symbols" package provide prebuilt implementations for all the C -// symbols that need to be exported by the plugin in order to be accepted by the -// framework. The prebuilt symbols handle all the complexity of bridging the C -// symbols and the Go runtime. Each subpackage is not internal, and can be used -// by advanced plugin developers to achieve a custom usage of the SDK symbols. -// This option is a strongly discouraged, as plugins must generally be -// developed using the more high-level constructs of the "sdk/plugins" package. -// This package is also used internally, and may be subject to more frequent -// breaking changes. -// -// 3. The "sdk" package provides basic definitions and constructs necessary to develop -// plugins. The SDK describes the behavior of plugins as a set of minimal and -// composable interfaces, to be used flexibly in other packages. -// -package sdk diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/event.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/event.go deleted file mode 100644 index 713debaa..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/event.go +++ /dev/null @@ -1,234 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sdk - -/* -#include -#include "plugin_info.h" -*/ -import "C" -import ( - "fmt" - "io" - "unsafe" - - "github.com/falcosecurity/plugin-sdk-go/pkg/ptr" -) - -// EventWriter can be used to represent events produced by a plugin. -// This interface is meant to be used in the next/next_batch. -// -// Data inside an event can only be accessed in write-only mode -// through the io.Writer interface returned by the Writer method. -// -// Instances of this interface should be retrieved through the Get -// method of sdk.EventWriters. -type EventWriter interface { - // Writer returns an instance of io.Writer that points to the - // event data. This is the only way to write inside the event data. - // - // Each invocation of Writer clears the event data and sets its - // size to zero. As such, consequent invocations of Writer can - // potentially return two distinct instances of io.Writer, and - // any data written inside the event would be erased. - Writer() io.Writer - // - // SetTimestamp sets the timestamp of the event. - SetTimestamp(value uint64) -} - -// EventReader can be used to represent events passed by the framework -// to the plugin. This interface is meant to be used during extraction. -// -// Data inside an event can only be accessed in read-only mode -// through the io.Reader interface returned by the Reader method. -type EventReader interface { - // EventNum returns the number assigned to the event by the framework. - EventNum() uint64 - // - // Timestamp returns the timestamp of the event. - Timestamp() uint64 - // - // Reader returns an instance of io.ReadSeeker that points to the - // event data. This is the only way to read from the event data. - // - // This method returns an instance of io.ReadSeeker to leave the door - // open for seek-related optimizations, which could be useful in the - // field extraction use case. - Reader() io.ReadSeeker -} - -// EventWriters represent a list of sdk.EventWriter to be used inside -// plugins. This interface hides the complexities related to the internal -// representation of C strutures and to the optimized memory management. -// Internally, this wraps an array of ss_plugin_event C structs that are -// compliant with the symbols and APIs of the plugin framework. -// The underlying C array can be accessed through the ArrayPtr method as -// an unsafe.Pointer. Manually writing inside the C array might break the -// internal logic of sdk.EventWriters and lead to undefined behavior. -// -// This is intended to be used as a slab memory allocator. EventWriters -// are supposed to be stored inside the plugin instance state to avoid -// useless reallocations, and should be used to create plugin events and -// write their data. Unlike slices, the events contained in the list -// can only be accessed by using the Get and Len methods to enforce safe -// memory accesses. Ideally, the list is meant to be large enough to contain -// the maximum number of events that the plugin is capable of producing with -// plugin_next_batch. -type EventWriters interface { - // Get returns an instance of sdk.EventWriter at the eventIndex - // position inside the list. - Get(eventIndex int) EventWriter - // - // Len returns the size of the list, namely the number of events - // it contains. Using Len coupled with Get allows iterating over - // all the events of the list. - Len() int - // - // ArrayPtr return an unsafe pointer to the underlying C array of - // ss_plugin_event. The returned pointer should only be used for - // read tasks or for being passed to the plugin framework. - // Writing in the memory pointed by this pointer is unsafe and might - // lead to non-deterministic behavior. - ArrayPtr() unsafe.Pointer - // - // Free deallocates any memory used by the list that can't be disposed - // through garbage collection. The behavior of Free after the first call - // is undefined. - Free() -} - -type eventWriters struct { - evts []*eventWriter -} - -// NewEventWriters creates a new instance of sdk.EventWriters. -// The size argument indicates the length of the list, which is the amount -// of events contained. Then dataSize argument indicates the maximum data -// size of each event. -func NewEventWriters(size, dataSize int64) (EventWriters, error) { - if size < 1 { - return nil, fmt.Errorf("invalid size: %d", size) - } - if dataSize < 0 || dataSize > C.UINT32_MAX { - return nil, fmt.Errorf("invalid dataSize: %d", dataSize) - } - - ret := &eventWriters{ - evts: make([]*eventWriter, size), - } - pluginEvtArray := (*C.ss_plugin_event)(C.malloc((C.size_t)(size * C.sizeof_ss_plugin_event))) - var err error - for i := range ret.evts { - // get i-th element of pluginEvtArray - evtPtr := unsafe.Pointer(uintptr(unsafe.Pointer(pluginEvtArray)) + uintptr(i*C.sizeof_ss_plugin_event)) - if ret.evts[i], err = newEventWriter(evtPtr, dataSize); err != nil { - return nil, err - } - } - return ret, nil -} - -func (p *eventWriters) Get(eventIndex int) EventWriter { - return p.evts[eventIndex] -} - -func (p *eventWriters) Len() int { - return len(p.evts) -} - -func (p *eventWriters) Free() { - for _, pe := range p.evts { - pe.free() - } - C.free( /*(*C.ss_plugin_event)*/ p.ArrayPtr()) -} - -func (p *eventWriters) ArrayPtr() unsafe.Pointer { - return p.evts[0].ssPluginEvt -} - -type eventWriter struct { - data ptr.BytesReadWriter - dataSize int64 - ssPluginEvt unsafe.Pointer -} - -func newEventWriter(evtPtr unsafe.Pointer, dataSize int64) (*eventWriter, error) { - evt := (*C.ss_plugin_event)(evtPtr) - evt.ts = C.uint64_t(C.UINT64_MAX) - evt.data = (*C.uint8_t)(C.malloc(C.size_t(dataSize))) - evt.datalen = 0 - brw, err := ptr.NewBytesReadWriter(unsafe.Pointer(evt.data), int64(dataSize), int64(dataSize)) - - if err != nil { - return nil, err - } - - return &eventWriter{ - ssPluginEvt: evtPtr, - data: brw, - dataSize: dataSize, - }, nil -} - -func (p *eventWriter) Writer() io.Writer { - p.data.SetLen(p.dataSize) - p.data.Seek(0, io.SeekStart) - (*C.ss_plugin_event)(p.ssPluginEvt).datalen = 0 - return p -} - -func (p *eventWriter) Write(data []byte) (n int, err error) { - n, err = p.data.Write(data) - if err != nil { - return - } - (*C.ss_plugin_event)(p.ssPluginEvt).datalen += C.uint32_t(n) - return -} - -func (p *eventWriter) SetTimestamp(value uint64) { - (*C.ss_plugin_event)(p.ssPluginEvt).ts = C.uint64_t(value) -} - -func (p *eventWriter) free() { - C.free(unsafe.Pointer((*C.ss_plugin_event)(p.ssPluginEvt).data)) - p.data = nil -} - -type eventReader C.ss_plugin_event - -// NewEventReader wraps a pointer to a ss_plugin_event C structure to create -// a new instance of EventReader. It's not possible to check that the pointer is valid. -// Passing an invalid pointer may cause undefined behavior. -func NewEventReader(ssPluginEvt unsafe.Pointer) EventReader { - return (*eventReader)(ssPluginEvt) -} - -func (e *eventReader) Reader() io.ReadSeeker { - brw, _ := ptr.NewBytesReadWriter(unsafe.Pointer(e.data), int64(e.datalen), int64(e.datalen)) - return brw -} - -func (e *eventReader) Timestamp() uint64 { - return uint64(e.ts) -} - -func (e *eventReader) EventNum() uint64 { - return uint64(e.evtnum) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/extract.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/extract.go deleted file mode 100644 index 82fe48a7..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/extract.go +++ /dev/null @@ -1,221 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sdk - -/* -#include "plugin_info.h" -#include -#include - -// NOTE: This is just an replica of the anonymous union nested inside -// ss_plugin_extract_field. The only difference is that each union field has -// one pointer level less than its equivalent of ss_plugin_extract_field. -// Keep this in sync with plugin_info.h in case new types will be supported. -typedef union { - const char* str; - uint64_t u64; -} field_result_t; - -*/ -import "C" -import ( - "unsafe" - - "github.com/falcosecurity/plugin-sdk-go/pkg/ptr" -) - -const ( - // Initial and minimum length with which the array of results is allocated - // for a each extractRequest struct. - minResultBufferLen = 512 -) - -// ExtractRequest represents an high-level abstraction that wraps a pointer to -// a ss_plugin_extract_field C structure, providing methods for accessing its -// fields in a go-friendly way. -type ExtractRequest interface { - // FieldID returns id of the field, as of its index in the list of fields - // returned by plugin_get_fields - FieldID() uint64 - // - // FieldType returns the type of the field for which the value extraction - // is requested. For now, only sdk.FieldTypeUint64 and - // sdk.FieldTypeCharBuf are supported. - FieldType() uint32 - // - // Field returns the name of the field for which the value extraction - // is requested. - Field() string - // - // ArgKey must be used when the field arg is a generic string (like a key - // in a lookup operation). This field must have the `isKey` flag enabled. - ArgKey() string - // - // ArgIndex must be used when the field arg is an index (0<=index<=2^64-1). - // This field must have the `isIndex` flag enabled. - ArgIndex() uint64 - // - // ArgPresent clearly defines when an argument is valid or not. - ArgPresent() bool - // - // IsList returns true if the field extracts lists of values. - IsList() bool - // - // SetValue sets the extracted value for the requested field. - // - // The underlying type of v must be compatible with the field type - // associated to this extract request (as the returned by FieldType()), - // otherwise SetValue will panic. - SetValue(v interface{}) - // - // SetPtr sets a pointer to a ss_plugin_extract_field C structure to - // be wrapped in this instance of ExtractRequest. - SetPtr(unsafe.Pointer) -} - -// ExtractRequestPool represents a pool of reusable ExtractRequest objects. -// Each ExtractRequest can be reused by calling its SetPtr method to wrap -// a new ss_plugin_extract_field C structure pointer. -type ExtractRequestPool interface { - // Get returns an instance of ExtractRequest at the requestIndex - // position inside the pool. Indexes can be non-contiguous. - Get(requestIndex int) ExtractRequest - // - // Free deallocates any memory used by the pool that can't be disposed - // through garbage collection. The behavior of Free after the first call - // is undefined. - Free() -} - -type extractRequestPool struct { - reqs map[uint]*extractRequest -} - -func (e *extractRequestPool) Get(requestIndex int) ExtractRequest { - r, ok := e.reqs[uint(requestIndex)] - if !ok && requestIndex >= 0 { - r = &extractRequest{ - resBuf: (*C.field_result_t)(C.malloc((C.size_t)(minResultBufferLen * C.sizeof_field_result_t))), - resBufLen: minResultBufferLen, - resStrBufs: []StringBuffer{&ptr.StringBuffer{}}, - } - e.reqs[uint(requestIndex)] = r - } - return r -} - -func (e *extractRequestPool) Free() { - for _, v := range e.reqs { - for _, b := range v.resStrBufs { - b.Free() - } - C.free(unsafe.Pointer(v.resBuf)) - } -} - -// NewExtractRequestPool returns a new empty ExtractRequestPool. -func NewExtractRequestPool() ExtractRequestPool { - pool := &extractRequestPool{ - reqs: make(map[uint]*extractRequest), - } - return pool -} - -type extractRequest struct { - req *C.ss_plugin_extract_field - // Pointer to a C-allocated array of field_result_t - resBuf *C.field_result_t - // Length of the array pointed by resBuf - resBufLen uint32 - // List of StringBuffer to return string results - resStrBufs []StringBuffer -} - -func (e *extractRequest) SetPtr(pef unsafe.Pointer) { - e.req = (*C.ss_plugin_extract_field)(pef) -} - -func (e *extractRequest) FieldID() uint64 { - return uint64(e.req.field_id) -} - -func (e *extractRequest) FieldType() uint32 { - return uint32(e.req.ftype) -} - -func (e *extractRequest) Field() string { - return ptr.GoString(unsafe.Pointer(e.req.field)) -} - -func (e *extractRequest) ArgKey() string { - return ptr.GoString(unsafe.Pointer(e.req.arg_key)) -} - -func (e *extractRequest) ArgIndex() uint64 { - return uint64(e.req.arg_index) -} - -func (e *extractRequest) ArgPresent() bool { - return bool(e.req.arg_present) -} - -func (e *extractRequest) IsList() bool { - return bool(e.req.flist) -} - -func (e *extractRequest) SetValue(v interface{}) { - switch e.FieldType() { - case FieldTypeUint64: - if e.req.flist { - if e.resBufLen < uint32(len(v.([]uint64))) { - C.free(unsafe.Pointer(e.resBuf)) - e.resBufLen = uint32(len(v.([]uint64))) - e.resBuf = (*C.field_result_t)(C.malloc((C.size_t)(e.resBufLen * C.sizeof_field_result_t))) - } - for i, val := range v.([]uint64) { - *((*C.uint64_t)(unsafe.Pointer(uintptr(unsafe.Pointer(e.resBuf)) + uintptr(i*C.sizeof_field_result_t)))) = (C.uint64_t)(val) - } - e.req.res_len = (C.uint64_t)(len(v.([]uint64))) - } else { - *((*C.uint64_t)(unsafe.Pointer(e.resBuf))) = (C.uint64_t)(v.(uint64)) - e.req.res_len = (C.uint64_t)(1) - } - case FieldTypeCharBuf: - if e.req.flist { - if e.resBufLen < uint32(len(v.([]string))) { - C.free(unsafe.Pointer(e.resBuf)) - e.resBufLen = uint32(len(v.([]string))) - e.resBuf = (*C.field_result_t)(C.malloc((C.size_t)(e.resBufLen * C.sizeof_field_result_t))) - } - for i, val := range v.([]string) { - if len(e.resStrBufs) <= i { - e.resStrBufs = append(e.resStrBufs, &ptr.StringBuffer{}) - } - e.resStrBufs[i].Write(val) - *((**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(e.resBuf)) + uintptr(i*C.sizeof_field_result_t)))) = (*C.char)(e.resStrBufs[i].CharPtr()) - } - e.req.res_len = (C.uint64_t)(len(v.([]string))) - } else { - e.resStrBufs[0].Write(v.(string)) - *((**C.char)(unsafe.Pointer(e.resBuf))) = (*C.char)(e.resStrBufs[0].CharPtr()) - e.req.res_len = (C.uint64_t)(1) - } - default: - panic("plugin-sdk-go/sdk: called SetValue with unsupported field type") - } - *((*C.uintptr_t)(unsafe.Pointer(&e.req.res))) = *(*C.uintptr_t)(unsafe.Pointer(&e.resBuf)) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/instance.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/instance.go deleted file mode 100644 index cb6de131..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/instance.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sdk - -// InstanceState represents the state of a plugin instance created -// with plugin_open(). -type InstanceState interface { -} - -// Closer is an interface wrapping the basic Destroy method. -// Close deinitializes the resources opened or allocated by a plugin instance. -// This is meant to be used in plugin_close() to release the resources owned -// by a plugin instance. The behavior of Close after the first call -// is undefined. -type Closer interface { - Close() -} - -// Events is an interface wrapping the basic Events and SetEvents -// methods. This is meant to be used as a standard container for a resusable -// list of EventWriters to be used in plugin_next_batch(). -type Events interface { - // Events returns the list of reusable EventWriters. - Events() EventWriters - // - // SetEvents sets the list of reusable EventWriters. - SetEvents(events EventWriters) -} - -// NextBatcher is an interface wrapping the basic NextBatch method. -// NextBatch is meant to be used in plugin_next_batch() to create a batch of -// new events altogether. -// -// The pState argument represents the plugin state, whereas the evt argument -// is an EventWriters representing list the to-be created events. -// The size of the event list dictates the expected size of the batch. -// -// NextBatch can set a timestamp for the to-be created events with the -// SetTimestamp method of the EventWriter interface. -// If not set manually, the framework will set a timestamp automatically. -// NextBatch must be consistent in setting timestamps: either it sets it -// for every event, or for none. -// -// NextBatch returns the number of events created in the batch, which is -// always <= evts.Len(), and a nil error if the call is successful. -// ErrTimeout can be returned to indicate that no new events are currently -// available for the current batch, but that they can be available in future -// calls to NextBatch. ErrEOF can be returned to indicate that no new events -// will be available. After returning ErrEOF once, subsequent calls to -// NextBatch must be idempotent and must keep returning ErrEOF. -// If the returned error is non-nil, the batch of events is discarded. -type NextBatcher interface { - NextBatch(pState PluginState, evts EventWriters) (int, error) -} - -// Progresser is an interface wrapping the basic Progress method. -// Progress is meant to be used in plugin_get_progress() to optionally notify -// the framework about the current event creation progress. -// Progress returns a float64 representing the normalized progress percentage -// such that 0 <= percentage <= 1, and a string representation of the same -// percentage value. -type Progresser interface { - Progress(pState PluginState) (float64, string) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/internal/hooks/hooks.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/internal/hooks/hooks.go deleted file mode 100644 index 51af8787..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/internal/hooks/hooks.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package hooks contains a set of hooks to be used internally in the SDK. -package hooks - -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" -) - -type OnBeforeDestroyFn func(handle cgo.Handle) -type OnAfterInitFn func(handle cgo.Handle) - -var ( - onBeforeDestroy OnBeforeDestroyFn = func(cgo.Handle) {} - onAfterInit OnAfterInitFn = func(cgo.Handle) {} -) - -// SetOnBeforeDestroy sets a callback that is invoked before the Destroy() method. -func SetOnBeforeDestroy(fn OnBeforeDestroyFn) { - if fn == nil { - panic("plugin-sdk-go/sdk/symbols/initialize.SetOnBeforeDestroy: fn must not be nil") - } - onBeforeDestroy = fn -} - -// OnBeforeDestroy returns a callback that is invoked before the Destroy() method. -func OnBeforeDestroy() OnBeforeDestroyFn { - return onBeforeDestroy -} - -// SetOnAfterInit sets a callback that is invoked after the Init() method. -func SetOnAfterInit(fn OnAfterInitFn) { - if fn == nil { - panic("plugin-sdk-go/sdk/symbols/initialize.SetOnAfterInit: fn must not be nil") - } - onAfterInit = fn -} - -// OnAfterInit returns a callback that is invoked after the Init() method. -func OnAfterInit() OnAfterInitFn { - return onAfterInit -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugin.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugin.go deleted file mode 100644 index c674bb4e..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugin.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sdk - -// PluginState represents the state of a plugin returned by plugin_init(). -type PluginState interface { -} - -type ExtractRequests interface { - ExtractRequests() ExtractRequestPool - SetExtractRequests(ExtractRequestPool) -} - -// LastError is a compasable interface wrapping the basic LastError and -// SetLastError methods. This is meant to be used as a standard -// container for the last error catched during the execution of a plugin. -type LastError interface { - // LastError returns the last error occurred in the plugin. - LastError() error - // - // SetLastError sets the last error occurred in the plugin. - SetLastError(err error) -} - -// Destroyer is an interface wrapping the basic Destroy method. -// Destroy deinitializes the resources opened or allocated by a plugin. -// This is meant to be used in plugin_destroy() to release the plugin's -// resources. The behavior of Destroy after the first call is undefined. -type Destroyer interface { - Destroy() -} - -// Stringer is an interface wrapping the basic String method. -// String takes an EventReader and produces a string representation -// describing its internal data. This is meant to be used in -// plugin_event_to_string(), where the event is provided by the framework -// and previouly produced by an invocation of plugin_next_batch() of this -// plugin. -type Stringer interface { - String(evt EventReader) (string, error) -} - -// Extractor is an interface wrapping the basic Extract method. -// Extract is meant to be used in plugin_extract_fields() to extract the value -// of a single field from a given event data. -type Extractor interface { - Extract(req ExtractRequest, evt EventReader) error -} - -// OpenParams is an interface wrapping the basic OpenParams method. -// OpenParams is meant to be used in plugin_list_open_params() to return a list -// of suggested parameters that would be accepted as valid arguments -// for plugin_open(). -type OpenParams interface { - OpenParams() ([]OpenParam, error) -} - -// InitSchema is an interface wrapping the basic InitSchema method. -// InitSchema is meant to be used in plugin_get_init_schema() to return a -// schema describing the data expected to be passed as a configuration -// during the plugin initialization. The schema must follow the JSON Schema -// specific: https://json-schema.org/. A nil return value is interpreted -// as the absence of a schema, and the init configuration will not be -// pre-validated by the framework. If JSON Schema is returned, the -// init configuration will be expected to be a json-formatted string. -// If so, the init() function can assume the configuration to be well-formed -// according to the returned schema, as the framework will perform a -// pre-validation before initializing the plugin. -type InitSchema interface { - InitSchema() *SchemaInfo -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugin_info.h b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugin_info.h deleted file mode 100644 index 53892437..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugin_info.h +++ /dev/null @@ -1,494 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*/ - -#pragma once - -#include -#include - -// -// This file contains the prototype and type definitions of sinsp/scap plugins -// - -// -// API versions of this plugin engine -// -#define PLUGIN_API_VERSION_MAJOR 1 -#define PLUGIN_API_VERSION_MINOR 0 -#define PLUGIN_API_VERSION_PATCH 0 - -// -// Just some not so smart defines to retrieve plugin api version as string -// -#define QUOTE(str) #str -#define EXPAND_AND_QUOTE(str) QUOTE(str) -#define PLUGIN_API_VERSION PLUGIN_API_VERSION_MAJOR.PLUGIN_API_VERSION_MINOR.PLUGIN_API_VERSION_PATCH -#define PLUGIN_API_VERSION_STR EXPAND_AND_QUOTE(PLUGIN_API_VERSION) - -// The noncontinguous numbers are to maintain equality with underlying -// falcosecurity libs types. -typedef enum ss_plugin_field_type -{ - FTYPE_UINT64 = 8, - FTYPE_STRING = 9 -}ss_plugin_field_type; - -// Values to return from init() / open() / next_batch() / -// extract_fields(). -typedef enum ss_plugin_rc -{ - SS_PLUGIN_SUCCESS = 0, - SS_PLUGIN_FAILURE = 1, - SS_PLUGIN_TIMEOUT = -1, - SS_PLUGIN_EOF = 2, - SS_PLUGIN_NOT_SUPPORTED = 3, -} ss_plugin_rc; - -// The supported schema formats for the init configuration. -typedef enum ss_plugin_schema_type -{ - // The schema is undefined and the init configuration - // is an opaque string. - SS_PLUGIN_SCHEMA_NONE = 0, - // - // The schema follows the JSON Schema specific, and the - // init configuration must be represented as a json. - // see: https://json-schema.org/ - SS_PLUGIN_SCHEMA_JSON = 1, -} ss_plugin_schema_type; - -// This struct represents an event returned by the plugin, and is used -// below in next_batch(). -// - evtnum: incremented for each event returned. Might not be contiguous. -// - data: pointer to a memory buffer pointer. The plugin will set it -// to point to the memory containing the next event. -// - datalen: pointer to a 32bit integer. The plugin will set it the size of the -// buffer pointed by data. -// - ts: the event timestamp, in nanoseconds since the epoch. -// Can be (uint64_t)-1, in which case the engine will automatically -// fill the event time with the current time. -// -// Note: event numbers are assigned by the plugin -// framework. Therefore, there isn't any need to fill in evtnum when -// returning an event via plugin_next_batch. It will be ignored. -typedef struct ss_plugin_event -{ - uint64_t evtnum; - const uint8_t *data; - uint32_t datalen; - uint64_t ts; -} ss_plugin_event; - -// Used in extract_fields functions below to receive a field/arg -// pair and return an extracted value. -// field_id: id of the field, as of its index in the list of -// fields specified by the plugin. -// field: the field name. -// arg_key: the field argument, if a 'key' argument has been specified -// for the field (isKey=true), otherwise it's NULL. -// For example: -// * if the field specified by the user is foo.bar[pippo], arg_key -// will be the string "pippo" -// * if the field specified by the user is foo.bar, arg will be NULL -// arg_index: the field argument, if a 'index' argument has been specified -// for the field (isIndex=true), otherwise it's 0. -// For example: -// * if the field specified by the user is foo.bar[1], arg_index -// will be the uint64_t '1'. -// Please note the ambiguity with a 0 -// argument which could be a real argument of just the default -// value to point out the absence. The `arg_present` field resolves -// this ambiguity. -// arg_present: helps to understand if the arg is there since arg_index is -// 0-based. -// ftype: the type of the field. Could be derived from the field name alone, -// but including here can prevent a second lookup of field names. -// flist: whether the field can extract lists of values or not. -// Could be derived from the field name alone, but including it -// here can prevent a second lookup of field names. -// The following should be filled in by the extraction function: -// - res: this union should be filled with a pointer to an array of values. -// The array represent the list of extracted values for this field from a given event. -// Each array element should be filled with a char* string if the corresponding -// field was type==string, and with a uint64 value if the corresponding field was -// type==uint64. -// - res_len: the length of the array of pointed by res. -// If the field is not a list type, then res_len must be either 0 or 1. -// If the field is a list type, then res_len can must be any value from 0 to N, depending -// on how many values can be extracted from a given event. -// Setting res_len to 0 means that no value of this field can be extracted from a given event. -typedef struct ss_plugin_extract_field -{ - // NOTE: For a given architecture, this has always the same size which - // is sizeof(uintptr_t). Adding new value types will not create breaking - // changes in the plugin API. However, we must make sure that each added - // type is always a pointer. - union { - const char** str; - uint64_t* u64; - } res; - uint64_t res_len; - - // NOTE: When/if adding new input fields, make sure of appending them - // at the end of the struct to avoid introducing breaking changes in the - // plugin API. - uint32_t field_id; - const char* field; - const char* arg_key; - uint64_t arg_index; - bool arg_present; - uint32_t ftype; - bool flist; -} ss_plugin_extract_field; - -// -// This is the opaque pointer to the state of a plugin. -// It points to any data that might be needed plugin-wise. It is -// allocated by init() and must be destroyed by destroy(). -// It is defined as void because the engine doesn't care what it is -// and it treats is as opaque. -// -typedef void ss_plugin_t; - -// -// This is the opaque pointer to the state of an open instance of the source -// plugin. -// It points to any data that is needed while a capture is running. It is -// allocated by open() and must be destroyed by close(). -// It is defined as void because the engine doesn't care what it is -// and it treats is as opaque. -// -typedef void ss_instance_t; - -// -// The structs below define the functions and arguments for plugins capabilities: -// * event sourcing -// * extractor -// The structs are used by the plugin framework to load and interface with plugins. -// -// From the perspective of the plugin, each function below should be -// exported from the dynamic library as a C calling convention -// function, adding a prefix "plugin_" to the function name -// (e.g. plugin_get_required_api_version, plugin_init, etc.) -// -// Plugins are totally responsible of both allocating and deallocating memory. -// Plugins have the guarantee that they can safely deallocate memory in -// these cases: -// - During close(), for all the memory allocated in the context of a plugin -// instance after open(). -// - During destroy(), for all the memory allocated by the plugin, as it stops -// being executed. -// - During subsequent calls to the same function, for all the exported -// functions returning memory pointers. -// -// Plugins must not free memory passed in by the framework (i.e. function input -// parameters) if not corresponding to plugin-allocated memory in the -// cases above. Plugins can safely use the passed memory during the execution -// of the exported functions. - -// -// Plugins vtable -// -typedef struct -{ - // - // Return the version of the plugin API used by this plugin. - // Required: yes - // Return value: the API version string, in the following format: - // "..", e.g. "1.2.3". - // NOTE: to ensure correct interoperability between the engine and the plugins, - // we use a semver approach. Plugins are required to specify the version - // of the API they run against, and the engine will take care of checking - // and enforcing compatibility. - // - const char *(*get_required_api_version)(); - - // - // Return a string representation of a schema describing the data expected - // to be passed as a configuration during the plugin initialization. - // Required: no - // Arguments: - // - schema_type: The schema format type of the returned value among the - // list of the supported ones according to the ss_plugin_config_schema - // enumeration. - // Return value: a string representation of the schema for the config - // to be passed to init(). - // - // Plugins can optionally export this symbol to specify the expected - // format for the configuration string passed to init(). If specified, - // the init() function can assume the config string to always be - // well-formed. The framework will take care of automatically parsing it - // against the provided schema and generating ad-hoc errors accordingly. - // This also serves as a piece of documentation for users about how the - // plugin needs to be configured. - // - const char *(*get_init_schema)(ss_plugin_schema_type *schema_type); - - // - // Initialize the plugin and allocate its non-NULL state. - // Required: yes - // Arguments: - // - config: a string with the plugin configuration. The format of the - // string is chosen by the plugin itself. - // - rc: pointer to a ss_plugin_rc that will contain the initialization result - // Return value: pointer to the plugin state that will be treated as opaque - // by the engine and passed to the other plugin functions. - // If rc is SS_PLUGIN_FAILURE, this function may return NULL or a state to later retrieve the error string. - // - ss_plugin_t *(*init)(const char *config, ss_plugin_rc *rc); - - // - // Destroy the plugin and, if plugin state was allocated, free it. - // Required: yes - // - void (*destroy)(ss_plugin_t *s); - - // - // Return a string with the error that was last generated by - // the plugin. - // Required: yes - // - // In cases where any other api function returns an error, the - // plugin should be prepared to return a human-readable error - // string with more context for the error. The plugin manager - // calls get_last_error() to access that string. - // - const char *(*get_last_error)(ss_plugin_t *s); - - // - // Return the name of the plugin, which will be printed when displaying - // information about the plugin. - // Required: yes - // - const char *(*get_name)(); - - // - // Return the descriptions of the plugin, which will be printed when displaying - // information about the plugin or its events. - // Required: yes - // - const char *(*get_description)(); - - // - // Return a string containing contact info (url, email, twitter, etc) for - // the plugin authors. - // Required: yes - // - const char *(*get_contact)(); - - // - // Return the version of this plugin itself - // Required: yes - // Return value: a string with a version identifier, in the following format: - // "..", e.g. "1.2.3". - // This differs from the api version in that this versions the - // plugin itself, as compared to the plugin interface. When - // reading capture files, the major version of the plugin that - // generated events must match the major version of the plugin - // used to read events. - // - const char *(*get_version)(); - - // Sourcing capabilities related - struct { - // - // Return the unique ID of the plugin. - // Required: yes - // EVERY PLUGIN WITH EVENT SOURCING CAPABILITIES MUST OBTAIN AN OFFICIAL ID FROM THE - // FALCOSECURITY ORGANIZATION, OTHERWISE IT WON'T PROPERLY COEXIST WITH OTHER PLUGINS. - // - uint32_t (*get_id)(); - // - // Return a string describing the events generated by this plugin with event sourcing capabilities. - // Required: yes - // Example event sources would be strings like "syscall", - // "k8s_audit", etc. The source can be used by extractor - // plugins to filter the events they receive. - // - const char* (*get_event_source)(); - // - // Open the source and start a capture (e.g. stream of events) - // Required: yes - // Arguments: - // - s: the plugin state returned by init() - // - params: the open parameters, as a string. The format is defined by the plugin - // itsef - // - rc: pointer to a ss_plugin_rc that will contain the open result - // Return value: a pointer to the open context that will be passed to next_batch(), - // close(), event_to_string() and extract_fields. - // - ss_instance_t* (*open)(ss_plugin_t* s, const char* params, ss_plugin_rc* rc); - // - // Close a capture. - // Required: yes - // Arguments: - // - s: the plugin context, returned by init(). Can be NULL. - // - h: the capture context, returned by open(). Can be NULL. - // - void (*close)(ss_plugin_t* s, ss_instance_t* h); - // - // Return a list of suggested open parameters supported by this plugin. - // Any of the values in the returned list are valid parameters for open(). - // Required: no - // Return value: a string with the list of open params encoded as - // a json array. - // Each field entry is a json object with the following properties: - // "value": a string usable as an open() parameter. - // "desc": (optional) a string with a description of the parameter. - // Example return value: - // [ - // {"value": "resource1", "desc": "An example of openable resource"}, - // {"value": "resource2", "desc": "Another example of openable resource"} - // ] - const char* (*list_open_params)(ss_plugin_t* s, ss_plugin_rc* rc); - // - // Return the read progress. - // Required: no - // Arguments: - // - progress_pct: the read progress, as a number between 0 (no data has been read) - // and 10000 (100% of the data has been read). This encoding allows the engine to - // print progress decimals without requiring to deal with floating point numbers - // (which could cause incompatibility problems with some languages). - // Return value: a string representation of the read - // progress. This might include the progress percentage - // combined with additional context added by the plugin. If - // NULL, progress_pct should be used. - // The returned memory pointer must be allocated by the plugin - // and must not be deallocated or modified until the next call to - // get_progress(). - // NOTE: reporting progress is optional and in some case could be impossible. However, - // when possible, it's recommended as it provides valuable information to the - // user. - // - const char* (*get_progress)(ss_plugin_t* s, ss_instance_t* h, uint32_t* progress_pct); - // - // Return a text representation of an event generated by this plugin with event sourcing capabilities. - // Required: no - // Arguments: - // - evt: an event struct produced by a call to next_batch(). - // This is allocated by the framework, and it is not guaranteed - // that the event struct pointer is the same returned by the last - // next_batch() call. - // Return value: the text representation of the event. This is used, for example, - // to print a line for the given event. - // The returned memory pointer must be allocated by the plugin - // and must not be deallocated or modified until the next call to - // event_to_string(). - // - const char* (*event_to_string)(ss_plugin_t *s, const ss_plugin_event *evt); - // - // Return the next batch of events. - // On success: - // - nevts will be filled in with the number of events. - // - evts: pointer to an ss_plugin_event pointer. The plugin must - // allocate an array of contiguous ss_plugin_event structs - // and each data buffer within each ss_plugin_event struct. - // Memory pointers set as output must be allocated by the plugin - // and must not be deallocated or modified until the next call to - // next_batch() or close(). - // Required: yes - // - ss_plugin_rc (*next_batch)(ss_plugin_t* s, ss_instance_t* h, uint32_t *nevts, ss_plugin_event **evts); - }; - - // Extraction capability related - struct { - // - // Return a string describing the event sources that this - // plugin can consume. - // Required: no - // Return value: a json array of strings containing event - // sources returned by a plugin with event sourcing capabilities get_event_source() - // function. - // This function is optional--if NULL or an empty array, then if plugin has sourcing capability - // it will only receive events matching its event source, - // otherwise it will receive every event for extraction. - // - const char* (*get_extract_event_sources)(); - // - // Return the list of extractor fields exported by this plugin. Extractor - // fields can be used in Falco rule conditions. - // Required: yes - // Return value: a string with the list of fields encoded as a json - // array. - // Each field entry is a json object with the following properties: - // "name": a string with a name for the field - // "type": one of "string", "uint64" - // "isList: (optional) If present and set to true, notes - // that the field extracts a list of values. - // "argRequired": [DEPRECATED, use "arg" property instead] - // (optional) If present and set to true, notes - // that the field requires an argument e.g. field[arg]. - // "arg": (optional) if present, notes that the field can accept - // an argument e.g. field[arg]. More precisely, the following - // flags could be specified: - // "isRequired": if true, the argument is required. - // "isIndex": if true, the field is numeric. - // "isKey": if true, the field is a string. - // If "isRequired" is true, one between "isIndex" and - // "isKey" must be true, to specify the argument type. - // If "isRequired" is false, but one between "isIndex" - // and "isKey" is true, the argument is allowed but - // not required. - // "display": (optional) If present, a string that will be used to - // display the field instead of the name. Used in tools - // like wireshark. - // "desc": a string with a description of the field - // Example return value: - // [ - // {"type": "string", "name": "field1", "argRequired": true, "desc": "Describing field 1"}, [DEPRECATED 'argRequired' property] - // {"type": "uint64", "name": "field2", "desc": "Describing field 2"}, - // {"type": "string", "name": "field3", "arg": {"isRequired": true, "isIndex": true,}, "desc": "Describing field 3"}, - // ] - const char* (*get_fields)(); - // - // Extract one or more a filter field values from an event. - // Required: yes - // Arguments: - // - evt: an event struct produced by a call to next_batch(). - // This is allocated by the framework, and it is not guaranteed - // that the event struct pointer is the same returned by the last - // next_batch() call. - // - num_fields: the length of the fields array. - // - fields: an array of ss_plugin_extract_field structs. Each entry - // contains a single field + optional argument as input, and the corresponding - // extracted value as output. Memory pointers set as output must be allocated - // by the plugin and must not be deallocated or modified until the next - // extract_fields() call. - // - // Return value: A ss_plugin_rc with values SS_PLUGIN_SUCCESS or SS_PLUGIN_FAILURE. - // - ss_plugin_rc (*extract_fields)(ss_plugin_t *s, const ss_plugin_event *evt, uint32_t num_fields, ss_plugin_extract_field *fields); - }; -} plugin_api; - -// -// Small C interface that is passed down to libscap -// and is used as event source. -// -typedef struct -{ - uint32_t id; - const char *name; - ss_plugin_t *state; - ss_instance_t *handle; - - ss_instance_t* (*open)(ss_plugin_t* s, const char* params, ss_plugin_rc* rc); - void (*close)(ss_plugin_t* s, ss_instance_t* h); - ss_plugin_rc (*next_batch)(ss_plugin_t* s, ss_instance_t* h, uint32_t *nevts, ss_plugin_event **evts); - const char *(*get_last_error)(ss_plugin_t *s); -} scap_source_plugin; \ No newline at end of file diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/doc.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/doc.go deleted file mode 100644 index 5bd1c327..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/doc.go +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package plugins and its subpackages provide high-level constructs -// to easily develop plugins, abstracting all the low-level -// details of the plugin framework. This bundles the main plugin developer -// tools provided by the SDK. Plugin developers are encouraged to use the -// constructs of the plugins package for their plugins. -// -// This packages depends on the lower-level prebuilt C symbols implementations -// of the sdk/symbols package. For some use cases, developers can consider -// using the the sdk/symbols package to customize their usage of the SDK. -// This is meaningful only if developers wish to manually write part of the -// low-level C details of the plugin framework, but still want to use some -// parts of the SDK. This is discouraged if not for advanced use cases only, -// and developers are instead encouraged to rely on the plugins package to -// build their plugins. -// -// Most of the time, a plugin author only needs to import the following packages, -// which provide the "default" streamlined interfaces to implementing plugins: -// "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -// "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins" -// "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/{source,extractor}" -// -package plugins diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/extractor/extractor.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/extractor/extractor.go deleted file mode 100644 index 1ab27089..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/extractor/extractor.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (C) 2022 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package extractor provides high-level constructs to easily build -// plugins with field extraction capability. -package extractor - -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/internal/hooks" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/fields" - _ "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/lasterr" -) - -// Plugin is an interface representing a plugin with field extraction capability. -type Plugin interface { - plugins.Plugin - sdk.Extractor - sdk.ExtractRequests - // - // Fields return the list of extractor fields exported by this plugin. - Fields() []sdk.FieldEntry -} - -func enableAsync(handle cgo.Handle) { - extract.StartAsync() - hooks.SetOnBeforeDestroy(func(handle cgo.Handle) { - extract.StopAsync() - }) -} - -// Register registers the field extraction capability in the framework for the given Plugin. -// -// This function should be called from the provided plugins.FactoryFunc implementation. -// See the parent package for more detail. This function is idempotent. -func Register(p Plugin) { - - fields.SetFields(p.Fields()) - - // setup hooks for automatically start/stop async extraction - hooks.SetOnAfterInit(enableAsync) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/plugins.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/plugins.go deleted file mode 100644 index a5ef6d67..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/plugins.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright (C) 2022 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package plugins - -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/ptr" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initialize" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initschema" -) - -// Info is a struct containing the general information about a plugin. -type Info struct { - ID uint32 - Name string - Description string - EventSource string - Contact string - Version string - RequiredAPIVersion string - ExtractEventSources []string -} - -// Plugin is an interface representing a plugin. -// Implementations of this interface can optionally implement the sdk.Destroy -// interface to specify a Destroy method will be called during the -// plugin deinitialization. -type Plugin interface { - // (optional): sdk.Destroyer - // (optional): sdk.InitSchema - sdk.LastError - sdk.LastErrorBuffer - // - // Info returns a pointer to a Info struct, containing - // all the general information about this plugin. - Info() *Info - // - // Init initializes this plugin with a given config string. - // A successful call to init returns a nil error. - Init(config string) error -} - -// BaseEvents is a base implementation of the sdk.Events interface. -type BaseEvents struct { - events sdk.EventWriters -} - -func (b *BaseEvents) Events() sdk.EventWriters { - return b.events -} - -func (b *BaseEvents) SetEvents(events sdk.EventWriters) { - b.events = events -} - -// BaseExtractRequests is a base implementation of the sdk.ExtractRequests -// interface. -type BaseExtractRequests struct { - extrReqPool sdk.ExtractRequestPool -} - -func (b *BaseExtractRequests) ExtractRequests() sdk.ExtractRequestPool { - return b.extrReqPool -} - -func (b *BaseExtractRequests) SetExtractRequests(pool sdk.ExtractRequestPool) { - b.extrReqPool = pool -} - -// BaseLastError is a base implementation of the sdk.LastError interface. -type BaseLastError struct { - lastErr error - lastErrBuf ptr.StringBuffer -} - -func (b *BaseLastError) LastError() error { - return b.lastErr -} - -func (b *BaseLastError) SetLastError(err error) { - b.lastErr = err -} - -func (b *BaseLastError) LastErrorBuffer() sdk.StringBuffer { - return &b.lastErrBuf -} - -// BaseStringer is a base implementation of the sdk.StringerBuffer interface. -type BaseStringer struct { - stringerBuf ptr.StringBuffer -} - -func (b *BaseStringer) StringerBuffer() sdk.StringBuffer { - return &b.stringerBuf -} - -// BaseProgress is a base implementation of the sdk.ProgressBuffer interface. -type BaseProgress struct { - progressBuf ptr.StringBuffer -} - -func (b *BaseProgress) ProgressBuffer() sdk.StringBuffer { - return &b.progressBuf -} - -// BaseOpenParams is a base implementation of the sdk.OpenParamsBuffer interface. -type BaseOpenParams struct { - openParamsBuf ptr.StringBuffer -} - -func (b *BaseOpenParams) OpenParamsBuffer() sdk.StringBuffer { - return &b.openParamsBuf -} - -// BasePlugin is a base implementation of the Plugin interface. -// Developer-defined Plugin implementations should be composed with BasePlugin -// to have out-of-the-box compliance with all the required interfaces. -type BasePlugin struct { - BaseLastError - BaseStringer - BaseExtractRequests - BaseOpenParams -} - -// FactoryFunc creates a new Plugin -type FactoryFunc func() Plugin - -// SetFactory sets the FactoryFunc to be used by the SDK when creating a new Plugin -// -// SetFactory should be called in the Go init() function of the plugin main package. -// It hooks the plugin framework initialization stage to create a new Plugin and -// to set up common facilities provided by this SDK. The given FactoryFunc must create -// a Plugin and can optionally enable plugin capabilities by using the Register functions -// provided by sub-packages. This function is idempotent. -// -// Usage example: -// -// package main -// -// import ( -// "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins" -// "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/extractor" -// "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/source" -// ) -// -// func init() { -// plugins.SetFactory(func() plugins.Plugin { -// p := &MyPlugin{} // create a new Plugin -// source.Register(p) // enable event sourcing capability -// extractor.Register(p) // enable field extraction capability -// return p -// }) -// } -// -func SetFactory(f FactoryFunc) { - - // Create a new plugin instance to get static plugin info - p := f() - - // Set up plugin info - i := p.Info() - info.SetId(i.ID) - info.SetName(i.Name) - info.SetDescription(i.Description) - info.SetEventSource(i.EventSource) - info.SetExtractEventSources(i.ExtractEventSources) - info.SetContact(i.Contact) - info.SetVersion(i.Version) - info.SetRequiredAPIVersion(i.RequiredAPIVersion) - - // Set up plugin init schema, if any - if initSchema, ok := p.(sdk.InitSchema); ok { - initschema.SetInitSchema(initSchema.InitSchema()) - } - - initialize.SetOnInit(func(c string) (sdk.PluginState, error) { - // Create a new plugin instance - p := f() - err := p.Init(c) - return p, err - }) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/source/source.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/source/source.go deleted file mode 100644 index 155344be..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/source/source.go +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright (C) 2022 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package source provides high-level constructs to easily build -// plugins with event sourcing capability. -package source - -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins" - _ "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/evtstr" - _ "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/lasterr" - _ "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/listopen" - _ "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/nextbatch" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/open" - _ "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/progress" -) - -// Plugin is an interface representing a plugin with event sourcing capability -type Plugin interface { - plugins.Plugin - sdk.StringerBuffer - sdk.OpenParamsBuffer - // (optional) sdk.OpenParams - // (optional) sdk.Stringer - - // - // Open opens the source and starts a capture (e.g. stream of events). - // - // The argument string represents the user-defined parameters and - // can be used to customize how the source is opened. - // The return value is an Instance representing the source capture session. - // There can be multiple instances of the same source open. - // A successfull call to Open returns a nil error. - // - // The sdk.EventWriters event buffer, that is reused during each cycle - // of new event creation, is initialized in automatic after the execution - // of Open with the SetEvents method of the Instance interface. - // Developers may override the default sdk.EventWriters by setting it - // on the returned Instance with SetEvents, before returning from Open. - // This can help specifying the data event size, the size of each - // event batch, or just to use an implementation of the - // sdk.EventWriters interface different from the SDK default one. - Open(params string) (Instance, error) -} - -// Instance is an interface representing a source capture session instance -// returned by a call to Open of a plugin with event sourcing capability. -// -// Implementations of this interface must implement sdk.NextBatcher, and can -// optionally implement sdk.Closer and sdk.Progresser. -// If sdk.Closer is implemented, the Close method will be called while closing -// the source capture session. -type Instance interface { - // (optional) sdk.Closer - // (optional) sdk.Progresser - sdk.Events - sdk.NextBatcher - sdk.ProgressBuffer -} - -// BaseInstance is a base implementation of the Instance interface. -// Developer-defined Instance implementations should be composed with BaseInstance -// to have out-of-the-box compliance with all the required interfaces. -type BaseInstance struct { - plugins.BaseEvents - plugins.BaseProgress -} - -// Register registers the event sourcing capability in the framework for the given Plugin. -// -// This function should be called from the provided plugins.FactoryFunc implementation. -// See the parent package for more detail. This function is idempotent. -func Register(p Plugin) { - open.SetOnOpen(func(c string) (sdk.InstanceState, error) { - return p.Open(c) - }) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/sdk.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/sdk.go deleted file mode 100644 index 7700b9f1..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/sdk.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sdk - -import ( - "errors" -) - -// ErrEOF is the error returned by next_batch when no new events -// are available. -var ErrEOF = errors.New("eof") - -// ErrTimeout is the error returned by next_batch when no new events -// are available for the current batch, but may be available in the -// next one. -var ErrTimeout = errors.New("timeout") - -// Functions that return or update a rc (e.g. plugin_init, -// plugin_open) should return one of these values. -const ( - SSPluginSuccess int32 = 0 - SSPluginFailure int32 = 1 - SSPluginTimeout int32 = -1 - SSPluginEOF int32 = 2 - SSPluginNotSupported int32 = 3 -) - -// DefaultEvtSize is the default size for the data payload allocated -// for each event in the EventWriters interface used by the SDK. -const DefaultEvtSize uint32 = 256 * 1024 - -// DefaultBatchSize is the default number of events in the EventWriters -// interface used by the SDK. -const DefaultBatchSize = 128 - -// The full set of values that can be returned in the ftype -// member of ss_plugin_extract_field structs. -const ( - FieldTypeUint64 uint32 = 8 - FieldTypeCharBuf uint32 = 9 // A printable buffer of bytes, NULL terminated -) - -// FieldEntry represents a single field entry that a plugin with field extraction -// capability can expose. -// Should be used when implementing plugin_get_fields(). -type FieldEntry struct { - Name string `json:"name"` - Type string `json:"type"` - IsList bool `json:"isList"` - Arg FieldEntryArg `json:"arg"` - Display string `json:"display"` - Desc string `json:"desc"` - Properties []string `json:"properties"` -} - -// FieldEntryArg describes the argument of a single field entry that -// an plugin with field extraction capability can expose. -// Should be used when implementing plugin_get_fields(). -type FieldEntryArg struct { - IsRequired bool `json:"isRequired"` - IsIndex bool `json:"isIndex"` - IsKey bool `json:"isKey"` -} - -// OpenParam represents a valid parameter for plugin_open(). -type OpenParam struct { - Value string `json:"value"` - Desc string `json:"desc"` - Separator string `json:"separator"` -} - -// SchemaInfo represent a schema describing a structured data type. -// Should be used when implementing plugin_get_init_schema(). -type SchemaInfo struct { - Schema string -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/evtstr/evtstr.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/evtstr/evtstr.go deleted file mode 100644 index 5485af09..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/evtstr/evtstr.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - char* plugin_event_to_string(ss_plugin_t *s, const ss_plugin_event *evt) -// -// The exported plugin_event_to_string requires that s to be a handle -// of cgo.Handle from this SDK. The value of the s handle must implement -// the sdk.Stringer and sdk.StringerBuffer interfaces. -// -// This function is part of the source_plugin_info interface as defined in -// plugin_info.h. In almost all cases, your plugin should import this module, -// unless your plugin exports those symbols by other means. -package evtstr - -/* -#include "../../plugin_info.h" -*/ -import "C" -import ( - "unsafe" - - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -//export plugin_event_to_string -func plugin_event_to_string(pState C.uintptr_t, evt *C.ss_plugin_event) *C.char { - buf := cgo.Handle(pState).Value().(sdk.StringerBuffer).StringerBuffer() - stringer, ok := cgo.Handle(pState).Value().(sdk.Stringer) - if ok { - if str, err := stringer.String(sdk.NewEventReader(unsafe.Pointer(evt))); err == nil { - buf.Write(str) - } else { - buf.Write(err.Error()) - } - } else { - buf.Write("") - } - return (*C.char)(buf.CharPtr()) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/async.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/async.go deleted file mode 100644 index f7b480b8..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/async.go +++ /dev/null @@ -1,158 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package extract - -/* -#include "extract.h" -*/ -import "C" -import ( - "runtime" - "sync" - "sync/atomic" - "time" -) - -const ( - state_wait = iota - state_data_req - state_exit_req - state_exit_ack -) - -const ( - starvationThresholdNs = 1e6 - sleepTimeNs = 1e4 * time.Nanosecond -) - -var ( - asyncCtx *C.async_extractor_info - asyncMutex sync.Mutex - asyncEnabled bool = true - asyncCount int32 = 0 -) - -func asyncAvailable() bool { - return runtime.NumCPU() > 1 -} - -func SetAsync(enable bool) { - asyncEnabled = enable -} - -func Async() bool { - return asyncEnabled -} - -// StartAsync initializes and starts the asynchronous extraction mode. -// Once StartAsync has been called, StopAsync must be called before terminating -// the program. The number of calls to StartAsync and StopAsync must be equal -// in the program. Independently by the number of StartAsync/StopAsync calls, -// there will never be more than one async worker activated at the same time. -// -// This is a way to optimize field extraction for use cases in which the rate -// of calls to plugin_extract_fields() is considerably high, so that the -// overhead of the C -> Go calls may become unacceptable for performance. -// Asynchronous extraction solves this problem by launching a worker -// goroutine and by synchronizing with it through a spinlock. -// The worker implements a busy wait, in order to ensure that the scheduler -// sleeps it from its execution as less as possible. This is only suitable -// for multi-core architectures, and has a significant impact on CPU usage, -// so it should be carefully used only if the rate of C -> Go calls makes -// the tradeoff worth it. -// -// After calling StartAsync, the framework automatically shift the extraction -// strategy from the regular C -> Go call one to the alternative worker -// synchronization one. -func StartAsync() { - asyncMutex.Lock() - defer asyncMutex.Unlock() - - asyncCount += 1 - if !asyncAvailable() || !asyncEnabled || asyncCount > 1 { - return - } - - asyncCtx = C.async_init() - atomic.StoreInt32((*int32)(&asyncCtx.lock), state_wait) - go func() { - lock := (*int32)(&asyncCtx.lock) - waitStartTime := time.Now().Nanosecond() - - for { - // Check for incoming request, if any, otherwise busy waits - switch atomic.LoadInt32(lock) { - - case state_data_req: - // Incoming data request. Process it... - asyncCtx.rc = C.int32_t( - plugin_extract_fields_sync( - C.uintptr_t(uintptr(asyncCtx.s)), - asyncCtx.evt, - uint32(asyncCtx.num_fields), - asyncCtx.fields, - ), - ) - // Processing done, return back to waiting state - atomic.StoreInt32(lock, state_wait) - // Reset waiting start time - waitStartTime = 0 - - case state_exit_req: - // Incoming exit request. Send ack and exit. - atomic.StoreInt32(lock, state_exit_ack) - return - - default: - // busy wait, then sleep after 1ms - if waitStartTime == 0 { - waitStartTime = time.Now().Nanosecond() - } else if time.Now().Nanosecond()-waitStartTime > starvationThresholdNs { - time.Sleep(sleepTimeNs) - } - } - } - }() -} - -// StopAsync deinitializes and stops the asynchronous extraction mode, and -// undoes a single StartAsync call. It is a run-time error if StartAsync was -// not called before calling StopAsync. -func StopAsync() { - asyncMutex.Lock() - defer asyncMutex.Unlock() - - asyncCount -= 1 - if asyncCount < 0 { - panic("plugin-sdk-go/sdk/symbols/extract: async worker stopped without being started") - } - - if asyncCount == 0 && asyncCtx != nil { - lock := (*int32)(&asyncCtx.lock) - - for !atomic.CompareAndSwapInt32(lock, state_wait, state_exit_req) { - // spin - } - - // state_exit_req acquired, wait for worker exiting - for atomic.LoadInt32(lock) != state_exit_ack { - // spin - } - asyncCtx = nil - C.async_deinit() - } -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.c b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.c deleted file mode 100644 index 88127618..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include "extract.h" - -// Possibly oversimplified version of https://gcc.gnu.org/wiki/Visibility -#if defined _WIN32 || defined __CYGWIN__ -#define FALCO_PLUGIN_SDK_PUBLIC __declspec(dllexport) -#else -#define FALCO_PLUGIN_SDK_PUBLIC -#endif - -enum worker_state -{ - WAIT = 0, - DATA_REQ = 1, - EXIT_REQ = 2, - EXIT_ACK = 3, -}; - -static async_extractor_info *s_async_extractor_ctx = NULL; - -async_extractor_info *async_init() -{ - s_async_extractor_ctx = (async_extractor_info *)malloc(sizeof(async_extractor_info)); - return s_async_extractor_ctx; -} - -void async_deinit() -{ - free(s_async_extractor_ctx); - s_async_extractor_ctx = NULL; -} - -// Defined in extract.go -extern int32_t plugin_extract_fields_sync(ss_plugin_t *s, - const ss_plugin_event *evt, - uint32_t num_fields, - ss_plugin_extract_field *fields); - -static inline int32_t async_extract_request(ss_plugin_t *s, - const ss_plugin_event *evt, - uint32_t num_fields, - ss_plugin_extract_field *fields) -{ - // Since no concurrent requests are supported, - // we assume worker is already in WAIT state - - // Set input data - s_async_extractor_ctx->s = s; - s_async_extractor_ctx->evt = evt; - s_async_extractor_ctx->num_fields = num_fields; - s_async_extractor_ctx->fields = fields; - - // notify data request - atomic_store_explicit(&s_async_extractor_ctx->lock, DATA_REQ, memory_order_seq_cst); - - // busy-wait until worker completation - while (atomic_load_explicit(&s_async_extractor_ctx->lock, memory_order_seq_cst) != WAIT); - - return s_async_extractor_ctx->rc; -} - -// This is the plugin API function. If s_async_extractor_ctx is -// non-NULL, it calls the async extractor function. Otherwise, it -// calls the synchronous extractor function. -FALCO_PLUGIN_SDK_PUBLIC int32_t plugin_extract_fields(ss_plugin_t *s, - const ss_plugin_event *evt, - uint32_t num_fields, - ss_plugin_extract_field *fields) -{ - if (s_async_extractor_ctx != NULL) - { - return async_extract_request(s, evt, num_fields, fields); - } - - return plugin_extract_fields_sync(s, evt, num_fields, fields); -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.go deleted file mode 100644 index 8393f8a4..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - ss_plugin_rc plugin_extract_fields(ss_plugin_t *s, const ss_plugin_event *evt, uint32_t num_fields, ss_plugin_extract_field *fields) -// -// The exported plugin_extract_fields requires s to be a handle -// of cgo.Handle from this SDK. The value of the s handle must implement -// the sdk.Extractor and sdk.ExtractRequests interfaces. -// -// This function is part of the source_plugin_info and extractor_plugin_info -// interfaces as defined in plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package extract - -/* -#include "extract.h" -*/ -import "C" -import ( - "unsafe" - - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -//export plugin_extract_fields_sync -func plugin_extract_fields_sync(plgState C.uintptr_t, evt *C.ss_plugin_event, numFields uint32, fields *C.ss_plugin_extract_field) int32 { - pHandle := cgo.Handle(plgState) - extract := pHandle.Value().(sdk.Extractor) - extrReqs := pHandle.Value().(sdk.ExtractRequests) - - // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices - flds := (*[1 << 28]C.struct_ss_plugin_extract_field)(unsafe.Pointer(fields))[:numFields:numFields] - var i uint32 - var extrReq sdk.ExtractRequest - for i = 0; i < numFields; i++ { - flds[i].res_len = (C.uint64_t)(0) - extrReq = extrReqs.ExtractRequests().Get(int(flds[i].field_id)) - extrReq.SetPtr(unsafe.Pointer(&flds[i])) - - err := extract.Extract(extrReq, sdk.NewEventReader(unsafe.Pointer(evt))) - if err != nil { - pHandle.Value().(sdk.LastError).SetLastError(err) - return sdk.SSPluginFailure - } - } - - return sdk.SSPluginSuccess -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.h b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.h deleted file mode 100644 index 34970f50..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/extract/extract.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#pragma once - -#include -#include "../../plugin_info.h" - -typedef struct async_extractor_info -{ - // lock - atomic_int_least32_t lock; - - // input data - ss_plugin_t *s; - const ss_plugin_event *evt; - uint32_t num_fields; - ss_plugin_extract_field *fields; - - // output data - int32_t rc; -} async_extractor_info; - -async_extractor_info *async_init(); -void async_deinit(); diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/fields/fields.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/fields/fields.go deleted file mode 100644 index f657512c..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/fields/fields.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - char* plugin_get_fields() -// -// This function is part of the source_plugin_info and extractor_plugin_info -// interfaces as defined in plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package fields - -import "C" -import ( - "encoding/json" - - "github.com/falcosecurity/plugin-sdk-go/pkg/ptr" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -var ( - fields []sdk.FieldEntry - buf ptr.StringBuffer -) - -// SetFields sets a slice of sdk.FieldEntry representing the list of extractor -// fields exported by this plugin. -func SetFields(f []sdk.FieldEntry) { - fields = f -} - -// Fields returns the slice of sdk.FieldEntry set with SetFields(). -func Fields() []sdk.FieldEntry { - return fields -} - -//export plugin_get_fields -func plugin_get_fields() *C.char { - b, err := json.Marshal(&fields) - if err != nil { - return nil - } - buf.Write(string(b)) - return (*C.char)(buf.CharPtr()) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.c b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.c deleted file mode 100644 index ad21b8af..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.c +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright (C) 2022 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "info.h" -#include "../../plugin_info.h" - -const char* get_default_required_api_version() -{ - return PLUGIN_API_VERSION_STR; -} \ No newline at end of file diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.go deleted file mode 100644 index 30d9c720..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports a set of C functions that provide general -// information about the plugin. The exported functions are: -// uint32_t get_type(); -// uint32_t get_id(); -// char* get_name(); -// char* get_description(); -// char* get_contact(); -// char* get_version(); -// char* get_required_api_version(); -// char* get_event_source(); -// char* get_extract_event_sources(); -// -// In almost all cases, your plugin should import this module, unless -// your plugin exports those symbols by other means. -package info - -/* -#include "info.h" -*/ -import "C" -import ( - "encoding/json" - - "github.com/falcosecurity/plugin-sdk-go/pkg/ptr" -) - -var ( - pType uint32 - pId uint32 - pName ptr.StringBuffer - pDescription ptr.StringBuffer - pContact ptr.StringBuffer - pVersion ptr.StringBuffer - pRequiredAPIVersion ptr.StringBuffer - pEventSource ptr.StringBuffer - pExtractEventSources ptr.StringBuffer -) - -//export plugin_get_id -func plugin_get_id() uint32 { - return pId -} - -func SetId(id uint32) { - pId = id -} - -//export plugin_get_name -func plugin_get_name() *C.char { - return (*C.char)(pName.CharPtr()) -} - -func SetName(name string) { - pName.Write(name) -} - -//export plugin_get_description -func plugin_get_description() *C.char { - return (*C.char)(pDescription.CharPtr()) -} - -func SetDescription(desc string) { - pDescription.Write(desc) -} - -//export plugin_get_contact -func plugin_get_contact() *C.char { - return (*C.char)(pContact.CharPtr()) -} - -func SetContact(contact string) { - pContact.Write(contact) -} - -//export plugin_get_version -func plugin_get_version() *C.char { - return (*C.char)(pVersion.CharPtr()) -} - -func SetVersion(version string) { - pVersion.Write(version) -} - -//export plugin_get_required_api_version -func plugin_get_required_api_version() *C.char { - if pRequiredAPIVersion.String() == "" { - return C.get_default_required_api_version() - } - return (*C.char)(pRequiredAPIVersion.CharPtr()) -} - -func SetRequiredAPIVersion(apiVer string) { - pRequiredAPIVersion.Write(apiVer) -} - -//export plugin_get_event_source -func plugin_get_event_source() *C.char { - return (*C.char)(pEventSource.CharPtr()) -} - -func SetEventSource(source string) { - pEventSource.Write(source) -} - -//export plugin_get_extract_event_sources -func plugin_get_extract_event_sources() *C.char { - if pExtractEventSources.String() == "" { - pExtractEventSources.Write("[]") - } - return (*C.char)(pExtractEventSources.CharPtr()) -} - -func SetExtractEventSources(sources []string) { - if len(sources) == 0 { - pExtractEventSources.Write("[]") - } else if b, err := json.Marshal(sources); err != nil { - panic(err) - } else { - pExtractEventSources.Write(string(b)) - } -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.h b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.h deleted file mode 100644 index 9b50570b..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/info/info.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright (C) 2022 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#pragma once - -const char* get_default_required_api_version(); diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initialize/initialize.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initialize/initialize.go deleted file mode 100644 index a91a2b05..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initialize/initialize.go +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C functions: -// - ss_plugin_t* plugin_init(char* config, int32_t* rc) -// - void* plugin_destroy(ss_plugin_t* s) -// -// The exported plugin_init calls the function set with SetOnInit, which -// returns a sdk.PluginState interface. If the return value implements the -// sdk.ExtractRequests interface, the function checks if an instance of -// sdk.ExtractRequestPool has already been set. If not, a default -// one is created on the fly and set with the SetExtractRequests method. -// -// The exported plugin_destroy requires s to be a handle -// of cgo.Handle from this SDK. If the value of the s handle implements -// the sdk.Destroyer interface, the function calls its Destroy method. -// If any of sdk.ExtractRequests, sdk.LastErrorBuffer, sdk.StringerBuffer, -// or sdk.ProgresserBuffer, are implemented, the function calls the Free method -// on the returned sdk.StringBuffer. Finally, the function deletes the -// s cgo.Handle. -// -// This function is part of the source_plugin_info and extractor_plugin_info -// interfaces as defined in plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package initialize - -/* -#include -*/ -import "C" -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/ptr" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/internal/hooks" -) - -type baseInit struct { - lastErr error - lastErrBuf ptr.StringBuffer -} - -func (b *baseInit) LastError() error { - return b.lastErr -} - -func (b *baseInit) SetLastError(err error) { - b.lastErr = err -} - -func (b *baseInit) LastErrorBuffer() sdk.StringBuffer { - return &b.lastErrBuf -} - -// OnInitFn is a callback used in plugin_init. -type OnInitFn func(config string) (sdk.PluginState, error) - -var ( - onInitFn OnInitFn = func(config string) (sdk.PluginState, error) { return &baseInit{}, nil } -) - -// SetOnInit sets an initialization callback to be called in plugin_init to -// create the plugin state. If never set, a default one is provided internally. -func SetOnInit(fn OnInitFn) { - if fn == nil { - panic("plugin-sdk-go/sdk/symbols/initialize.SetOnInit: fn must not be nil") - } - onInitFn = fn -} - -//export plugin_init -func plugin_init(config *C.char, rc *int32) C.uintptr_t { - var state sdk.PluginState - var err error - - state, err = onInitFn(C.GoString(config)) - if err != nil { - state = &baseInit{} - state.(sdk.LastError).SetLastError(err) - *rc = sdk.SSPluginFailure - } else { - // this allows a nil state - extrReqs, ok := state.(sdk.ExtractRequests) - if ok && extrReqs.ExtractRequests() == nil { - extrReqs.SetExtractRequests(sdk.NewExtractRequestPool()) - } - *rc = sdk.SSPluginSuccess - } - - handle := cgo.NewHandle(state) - if *rc == sdk.SSPluginSuccess { - hooks.OnAfterInit()(handle) - } - - return (C.uintptr_t)(handle) -} - -//export plugin_destroy -func plugin_destroy(pState C.uintptr_t) { - if pState != 0 { - handle := cgo.Handle(pState) - hooks.OnBeforeDestroy()(handle) - if state, ok := handle.Value().(sdk.Destroyer); ok { - state.Destroy() - } - if state, ok := handle.Value().(sdk.ExtractRequests); ok { - state.ExtractRequests().Free() - state.SetExtractRequests(nil) - } - if state, ok := handle.Value().(sdk.LastErrorBuffer); ok { - state.LastErrorBuffer().Free() - } - if state, ok := handle.Value().(sdk.StringerBuffer); ok { - state.StringerBuffer().Free() - } - if state, ok := handle.Value().(sdk.ProgressBuffer); ok { - state.ProgressBuffer().Free() - } - handle.Delete() - } -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initschema/initschema.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initschema/initschema.go deleted file mode 100644 index ef10d64a..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/initschema/initschema.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - const char* get_init_schema(ss_plugin_schema_type* schema_type) -// -// This function is part of the source_plugin_info and extractor_plugin_info -// interfaces as defined in plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package initschema - -/* -#include "../../plugin_info.h" -*/ -import "C" -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/ptr" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -var ( - schema *sdk.SchemaInfo - buf ptr.StringBuffer -) - -// SetInitSchema sets a pointer to sdk.SchemaInfo representing the schema -// of the configuration expected by the plugin during initialization. -func SetInitSchema(s *sdk.SchemaInfo) { - schema = s -} - -// InitSchema returns the pointer to sdk.SchemaInfo set with SetInitSchema(). -func InitSchema() *sdk.SchemaInfo { - return schema -} - -//export plugin_get_init_schema -func plugin_get_init_schema(schema_type *C.ss_plugin_schema_type) *C.char { - str := "" - *schema_type = C.SS_PLUGIN_SCHEMA_NONE - if schema != nil { - str = schema.Schema - *schema_type = C.SS_PLUGIN_SCHEMA_JSON - } - buf.Write(str) - return (*C.char)(buf.CharPtr()) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/lasterr/lasterr.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/lasterr/lasterr.go deleted file mode 100644 index fb5cfbda..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/lasterr/lasterr.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - char* plugin_get_last_error(ss_plugin_t* s) -// -// The exported plugin_get_last_error requires s to be a handle -// of cgo.Handle from this SDK. The value of the s handle must implement -// the sdk.LastErrorBuffer interface, and either the error or the sdk.LastError -// interfaces. -// -// This function is part of the source_plugin_info and extractor_plugin_info -// interfaces as defined in plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package lasterr - -/* -#include // for uintptr_t -*/ -import "C" -import ( - "errors" - - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -var ( - errNoErrorInterface = errors.New(`cannot get error message: plugin instance does not implement "error" interface`) -) - -//export plugin_get_last_error -func plugin_get_last_error(pInstance C.uintptr_t) *C.char { - buf := cgo.Handle(pInstance).Value().(sdk.LastErrorBuffer).LastErrorBuffer() - err, ok := cgo.Handle(pInstance).Value().(error) - if !ok { - lastErr, ok := cgo.Handle(pInstance).Value().(sdk.LastError) - if !ok { - err = errNoErrorInterface - } else { - err = lastErr.LastError() - } - } - buf.Write(err.Error()) - return (*C.char)(buf.CharPtr()) -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/listopen/listopen.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/listopen/listopen.go deleted file mode 100644 index b8d0e32f..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/listopen/listopen.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - char* plugin_list_open_params() -// -// This function is part of the source_plugin_info and capture_plugin_info -// interfaces as defined in plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package listopen - -/* -#include -*/ -import "C" -import ( - "encoding/json" - - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -//export plugin_list_open_params -func plugin_list_open_params(pState C.uintptr_t, rc *int32) *C.char { - *rc = sdk.SSPluginSuccess - if openParams, ok := cgo.Handle(pState).Value().(sdk.OpenParams); ok { - if buf, ok := cgo.Handle(pState).Value().(sdk.OpenParamsBuffer); ok { - list, err := openParams.OpenParams() - if err != nil { - cgo.Handle(pState).Value().(sdk.LastError).SetLastError(err) - *rc = sdk.SSPluginFailure - return nil - } - b, err := json.Marshal(&list) - if err != nil { - cgo.Handle(pState).Value().(sdk.LastError).SetLastError(err) - *rc = sdk.SSPluginFailure - return nil - } - buf.OpenParamsBuffer().Write(string(b)) - return (*C.char)(buf.OpenParamsBuffer().CharPtr()) - } - } - return nil -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/nextbatch/nextbatch.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/nextbatch/nextbatch.go deleted file mode 100644 index fbd48412..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/nextbatch/nextbatch.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - ss_plugin_rc plugin_next_batch(ss_plugin_t* s, ss_instance_t* h, uint32_t *nevts, ss_plugin_event **evts) -// -// The exported plugin_next_batch requires s and h to be a handles -// of cgo.Handle from this SDK. The value of the s handle must implement -// the sdk.PluginState interface. The value of the h handle must implement -// the sdk.Events and the sdk.NextBatcher interfaces. -// -// This function is part of the source_plugin_info interface as defined in -// plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package nextbatch - -/* -#include "../../plugin_info.h" -*/ -import "C" -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -//export plugin_next_batch -func plugin_next_batch(pState C.uintptr_t, iState C.uintptr_t, nevts *uint32, retEvts **C.ss_plugin_event) int32 { - events := cgo.Handle(iState).Value().(sdk.Events).Events() - n, err := cgo.Handle(iState).Value().(sdk.NextBatcher).NextBatch(cgo.Handle(pState).Value().(sdk.PluginState), events) - - *nevts = uint32(n) - *retEvts = (*C.ss_plugin_event)(events.ArrayPtr()) - switch err { - case nil: - return sdk.SSPluginSuccess - case sdk.ErrEOF: - return sdk.SSPluginEOF - case sdk.ErrTimeout: - return sdk.SSPluginTimeout - default: - *nevts = uint32(0) - *retEvts = nil - cgo.Handle(pState).Value().(sdk.LastError).SetLastError(err) - return sdk.SSPluginFailure - } -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/open/open.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/open/open.go deleted file mode 100644 index 1283da4b..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/open/open.go +++ /dev/null @@ -1,108 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C functions: -// - ss_instance_t* plugin_open(ss_plugin_t* s, char* params, ss_plugin_rc* rc) -// - void plugin_close(ss_plugin_t* s, ss_instance_t* h) -// -// The exported plugin_open requires s to be a handle -// of cgo.Handle from this SDK. The value of the s handle must implement -// the sdk.LastError interface. plugin_open calls the function set with -// SetOnOpen, which returns a sdk.InstanceState interface. If the return -// value implements the sdk.Events interface, the function checks if an -// instance of sdk.EventWriters has already been set. If not, a default -// one is created on the fly and set with the SetEvents method. -// -// The exported plugin_close requires h to be a handle -// of cgo.Handle from this SDK. If the value of the h handle implements -// the sdk.Closer interface, the function calls its Close method. -// If sdk.Events is implemented the function calls the Free method -// on the returned sdk.EventWriters. Finally, the function deletes the -// h cgo.Handle. -// -// This function is part of the source_plugin_info interface as defined -// in plugin_info.h. -// In almost all cases, your plugin should import this module, unless your -// plugin exports those symbols by other means. -package open - -/* -#include -*/ -import "C" -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -var ( - onOpenFn OnOpenFn -) - -// OnOpenFn is a callback used in plugin_open. -type OnOpenFn func(config string) (sdk.InstanceState, error) - -// SetOnInit sets an initialization callback to be called in plugin_open to -// create the plugin instance state. If never set, plugin_open will panic. -func SetOnOpen(fn OnOpenFn) { - if fn == nil { - panic("plugin-sdk-go/sdk/symbols/open.SetOnOpen: fn must not be nil") - } - onOpenFn = fn -} - -//export plugin_open -func plugin_open(plgState C.uintptr_t, params *C.char, rc *int32) C.uintptr_t { - if onOpenFn == nil { - panic("plugin-sdk-go/sdk/symbols/open: SetOnOpen must be called") - } - - iState, err := onOpenFn(C.GoString(params)) - if err == nil { - // this allows a nil iState - iEvents, ok := iState.(sdk.Events) - if ok && iEvents.Events() == nil { - var events sdk.EventWriters - events, err = sdk.NewEventWriters(int64(sdk.DefaultBatchSize), int64(sdk.DefaultEvtSize)) - if err == nil { - iEvents.SetEvents(events) - } - } - } - - if err != nil { - cgo.Handle(plgState).Value().(sdk.LastError).SetLastError(err) - *rc = sdk.SSPluginFailure - return 0 - } - *rc = sdk.SSPluginSuccess - return (C.uintptr_t)(cgo.NewHandle(iState)) -} - -//export plugin_close -func plugin_close(plgState C.uintptr_t, instanceState C.uintptr_t) { - if instanceState != 0 { - handle := cgo.Handle(instanceState) - if state, ok := handle.Value().(sdk.Closer); ok { - state.Close() - } - if state, ok := handle.Value().(sdk.Events); ok { - state.Events().Free() - state.SetEvents(nil) - } - handle.Delete() - } -} diff --git a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/progress/progress.go b/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/progress/progress.go deleted file mode 100644 index e6be80b0..00000000 --- a/vendor/github.com/falcosecurity/plugin-sdk-go/pkg/sdk/symbols/progress/progress.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright (C) 2021 The Falco Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This package exports the following C function: -// - char* plugin_get_progress(ss_plugin_t* s, ss_instance_t* h, uint32_t* progress_pct) -// -// The exported plugin_get_progress requires that both s and h are handles -// of cgo.Handle from this SDK. The value of the s handle must implement -// the sdk.PluginState interface. The value of the h handle must implement -// the sdk.Progresser and sdk.ProgressBuffer interfaces. -// -// This function is part of the source_plugin_info interface as defined in -// plugin_info.h. In almost all cases, your plugin should import this module, -// unless your plugin exports those symbols by other means. -package progress - -/* -#include -*/ -import "C" -import ( - "github.com/falcosecurity/plugin-sdk-go/pkg/cgo" - "github.com/falcosecurity/plugin-sdk-go/pkg/sdk" -) - -//export plugin_get_progress -func plugin_get_progress(pState C.uintptr_t, iState C.uintptr_t, progress_pct *uint32) *C.char { - buf := cgo.Handle(iState).Value().(sdk.ProgressBuffer).ProgressBuffer() - progresser, ok := cgo.Handle(iState).Value().(sdk.Progresser) - if ok { - pct, str := progresser.Progress(cgo.Handle(pState).Value().(sdk.PluginState)) - *progress_pct = uint32(pct * 10000) - buf.Write(str) - return (*C.char)(buf.CharPtr()) - } - *progress_pct = 0 - return (*C.char)(nil) -} diff --git a/vendor/github.com/go-logr/logr/.golangci.yaml b/vendor/github.com/go-logr/logr/.golangci.yaml deleted file mode 100644 index 94ff801d..00000000 --- a/vendor/github.com/go-logr/logr/.golangci.yaml +++ /dev/null @@ -1,29 +0,0 @@ -run: - timeout: 1m - tests: true - -linters: - disable-all: true - enable: - - asciicheck - - deadcode - - errcheck - - forcetypeassert - - gocritic - - gofmt - - goimports - - gosimple - - govet - - ineffassign - - misspell - - revive - - staticcheck - - structcheck - - typecheck - - unused - - varcheck - -issues: - exclude-use-default: false - max-issues-per-linter: 0 - max-same-issues: 10 diff --git a/vendor/github.com/go-logr/logr/CHANGELOG.md b/vendor/github.com/go-logr/logr/CHANGELOG.md deleted file mode 100644 index c3569600..00000000 --- a/vendor/github.com/go-logr/logr/CHANGELOG.md +++ /dev/null @@ -1,6 +0,0 @@ -# CHANGELOG - -## v1.0.0-rc1 - -This is the first logged release. Major changes (including breaking changes) -have occurred since earlier tags. diff --git a/vendor/github.com/go-logr/logr/CONTRIBUTING.md b/vendor/github.com/go-logr/logr/CONTRIBUTING.md deleted file mode 100644 index 5d37e294..00000000 --- a/vendor/github.com/go-logr/logr/CONTRIBUTING.md +++ /dev/null @@ -1,17 +0,0 @@ -# Contributing - -Logr is open to pull-requests, provided they fit within the intended scope of -the project. Specifically, this library aims to be VERY small and minimalist, -with no external dependencies. - -## Compatibility - -This project intends to follow [semantic versioning](http://semver.org) and -is very strict about compatibility. Any proposed changes MUST follow those -rules. - -## Performance - -As a logging library, logr must be as light-weight as possible. Any proposed -code change must include results of running the [benchmark](./benchmark) -before and after the change. diff --git a/vendor/github.com/go-logr/logr/LICENSE b/vendor/github.com/go-logr/logr/LICENSE deleted file mode 100644 index 8dada3ed..00000000 --- a/vendor/github.com/go-logr/logr/LICENSE +++ /dev/null @@ -1,201 +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/go-logr/logr/README.md b/vendor/github.com/go-logr/logr/README.md deleted file mode 100644 index ab593118..00000000 --- a/vendor/github.com/go-logr/logr/README.md +++ /dev/null @@ -1,282 +0,0 @@ -# A minimal logging API for Go - -[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr) - -logr offers an(other) opinion on how Go programs and libraries can do logging -without becoming coupled to a particular logging implementation. This is not -an implementation of logging - it is an API. In fact it is two APIs with two -different sets of users. - -The `Logger` type is intended for application and library authors. It provides -a relatively small API which can be used everywhere you want to emit logs. It -defers the actual act of writing logs (to files, to stdout, or whatever) to the -`LogSink` interface. - -The `LogSink` interface is intended for logging library implementers. It is a -pure interface which can be implemented by logging frameworks to provide the actual logging -functionality. - -This decoupling allows application and library developers to write code in -terms of `logr.Logger` (which has very low dependency fan-out) while the -implementation of logging is managed "up stack" (e.g. in or near `main()`.) -Application developers can then switch out implementations as necessary. - -Many people assert that libraries should not be logging, and as such efforts -like this are pointless. Those people are welcome to convince the authors of -the tens-of-thousands of libraries that *DO* write logs that they are all -wrong. In the meantime, logr takes a more practical approach. - -## Typical usage - -Somewhere, early in an application's life, it will make a decision about which -logging library (implementation) it actually wants to use. Something like: - -``` - func main() { - // ... other setup code ... - - // Create the "root" logger. We have chosen the "logimpl" implementation, - // which takes some initial parameters and returns a logr.Logger. - logger := logimpl.New(param1, param2) - - // ... other setup code ... -``` - -Most apps will call into other libraries, create structures to govern the flow, -etc. The `logr.Logger` object can be passed to these other libraries, stored -in structs, or even used as a package-global variable, if needed. For example: - -``` - app := createTheAppObject(logger) - app.Run() -``` - -Outside of this early setup, no other packages need to know about the choice of -implementation. They write logs in terms of the `logr.Logger` that they -received: - -``` - type appObject struct { - // ... other fields ... - logger logr.Logger - // ... other fields ... - } - - func (app *appObject) Run() { - app.logger.Info("starting up", "timestamp", time.Now()) - - // ... app code ... -``` - -## Background - -If the Go standard library had defined an interface for logging, this project -probably would not be needed. Alas, here we are. - -### Inspiration - -Before you consider this package, please read [this blog post by the -inimitable Dave Cheney][warning-makes-no-sense]. We really appreciate what -he has to say, and it largely aligns with our own experiences. - -### Differences from Dave's ideas - -The main differences are: - -1. Dave basically proposes doing away with the notion of a logging API in favor -of `fmt.Printf()`. We disagree, especially when you consider things like output -locations, timestamps, file and line decorations, and structured logging. This -package restricts the logging API to just 2 types of logs: info and error. - -Info logs are things you want to tell the user which are not errors. Error -logs are, well, errors. If your code receives an `error` from a subordinate -function call and is logging that `error` *and not returning it*, use error -logs. - -2. Verbosity-levels on info logs. This gives developers a chance to indicate -arbitrary grades of importance for info logs, without assigning names with -semantic meaning such as "warning", "trace", and "debug." Superficially this -may feel very similar, but the primary difference is the lack of semantics. -Because verbosity is a numerical value, it's safe to assume that an app running -with higher verbosity means more (and less important) logs will be generated. - -## Implementations (non-exhaustive) - -There are implementations for the following logging libraries: - -- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr) -- **a testing.T** (for use in Go tests, with JSON-like output): [testr](https://github.com/go-logr/logr/tree/master/testr) -- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr) -- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr) -- **a testing.T** (with klog-like text output): [ktesting](https://git.k8s.io/klog/ktesting) -- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr) -- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr) -- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr) -- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend) -- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr) -- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr) -- **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0) -- **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing) - -## FAQ - -### Conceptual - -#### Why structured logging? - -- **Structured logs are more easily queryable**: Since you've got - key-value pairs, it's much easier to query your structured logs for - particular values by filtering on the contents of a particular key -- - think searching request logs for error codes, Kubernetes reconcilers for - the name and namespace of the reconciled object, etc. - -- **Structured logging makes it easier to have cross-referenceable logs**: - Similarly to searchability, if you maintain conventions around your - keys, it becomes easy to gather all log lines related to a particular - concept. - -- **Structured logs allow better dimensions of filtering**: if you have - structure to your logs, you've got more precise control over how much - information is logged -- you might choose in a particular configuration - to log certain keys but not others, only log lines where a certain key - matches a certain value, etc., instead of just having v-levels and names - to key off of. - -- **Structured logs better represent structured data**: sometimes, the - data that you want to log is inherently structured (think tuple-link - objects.) Structured logs allow you to preserve that structure when - outputting. - -#### Why V-levels? - -**V-levels give operators an easy way to control the chattiness of log -operations**. V-levels provide a way for a given package to distinguish -the relative importance or verbosity of a given log message. Then, if -a particular logger or package is logging too many messages, the user -of the package can simply change the v-levels for that library. - -#### Why not named levels, like Info/Warning/Error? - -Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences -from Dave's ideas](#differences-from-daves-ideas). - -#### Why not allow format strings, too? - -**Format strings negate many of the benefits of structured logs**: - -- They're not easily searchable without resorting to fuzzy searching, - regular expressions, etc. - -- They don't store structured data well, since contents are flattened into - a string. - -- They're not cross-referenceable. - -- They don't compress easily, since the message is not constant. - -(Unless you turn positional parameters into key-value pairs with numerical -keys, at which point you've gotten key-value logging with meaningless -keys.) - -### Practical - -#### Why key-value pairs, and not a map? - -Key-value pairs are *much* easier to optimize, especially around -allocations. Zap (a structured logger that inspired logr's interface) has -[performance measurements](https://github.com/uber-go/zap#performance) -that show this quite nicely. - -While the interface ends up being a little less obvious, you get -potentially better performance, plus avoid making users type -`map[string]string{}` every time they want to log. - -#### What if my V-levels differ between libraries? - -That's fine. Control your V-levels on a per-logger basis, and use the -`WithName` method to pass different loggers to different libraries. - -Generally, you should take care to ensure that you have relatively -consistent V-levels within a given logger, however, as this makes deciding -on what verbosity of logs to request easier. - -#### But I really want to use a format string! - -That's not actually a question. Assuming your question is "how do -I convert my mental model of logging with format strings to logging with -constant messages": - -1. Figure out what the error actually is, as you'd write in a TL;DR style, - and use that as a message. - -2. For every place you'd write a format specifier, look to the word before - it, and add that as a key value pair. - -For instance, consider the following examples (all taken from spots in the -Kubernetes codebase): - -- `klog.V(4).Infof("Client is returning errors: code %v, error %v", - responseCode, err)` becomes `logger.Error(err, "client returned an - error", "code", responseCode)` - -- `klog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v", - seconds, retries, url)` becomes `logger.V(4).Info("got a retry-after - response when requesting url", "attempt", retries, "after - seconds", seconds, "url", url)` - -If you *really* must use a format string, use it in a key's value, and -call `fmt.Sprintf` yourself. For instance: `log.Printf("unable to -reflect over type %T")` becomes `logger.Info("unable to reflect over -type", "type", fmt.Sprintf("%T"))`. In general though, the cases where -this is necessary should be few and far between. - -#### How do I choose my V-levels? - -This is basically the only hard constraint: increase V-levels to denote -more verbose or more debug-y logs. - -Otherwise, you can start out with `0` as "you always want to see this", -`1` as "common logging that you might *possibly* want to turn off", and -`10` as "I would like to performance-test your log collection stack." - -Then gradually choose levels in between as you need them, working your way -down from 10 (for debug and trace style logs) and up from 1 (for chattier -info-type logs.) - -#### How do I choose my keys? - -Keys are fairly flexible, and can hold more or less any string -value. For best compatibility with implementations and consistency -with existing code in other projects, there are a few conventions you -should consider. - -- Make your keys human-readable. -- Constant keys are generally a good idea. -- Be consistent across your codebase. -- Keys should naturally match parts of the message string. -- Use lower case for simple keys and - [lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for - more complex ones. Kubernetes is one example of a project that has - [adopted that - convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments). - -While key names are mostly unrestricted (and spaces are acceptable), -it's generally a good idea to stick to printable ascii characters, or at -least match the general character set of your log lines. - -#### Why should keys be constant values? - -The point of structured logging is to make later log processing easier. Your -keys are, effectively, the schema of each log message. If you use different -keys across instances of the same log line, you will make your structured logs -much harder to use. `Sprintf()` is for values, not for keys! - -#### Why is this not a pure interface? - -The Logger type is implemented as a struct in order to allow the Go compiler to -optimize things like high-V `Info` logs that are not triggered. Not all of -these implementations are implemented yet, but this structure was suggested as -a way to ensure they *can* be implemented. All of the real work is behind the -`LogSink` interface. - -[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging diff --git a/vendor/github.com/go-logr/logr/discard.go b/vendor/github.com/go-logr/logr/discard.go deleted file mode 100644 index 9d92a38f..00000000 --- a/vendor/github.com/go-logr/logr/discard.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2020 The logr Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package logr - -// Discard returns a Logger that discards all messages logged to it. It can be -// used whenever the caller is not interested in the logs. Logger instances -// produced by this function always compare as equal. -func Discard() Logger { - return Logger{ - level: 0, - sink: discardLogSink{}, - } -} - -// discardLogSink is a LogSink that discards all messages. -type discardLogSink struct{} - -// Verify that it actually implements the interface -var _ LogSink = discardLogSink{} - -func (l discardLogSink) Init(RuntimeInfo) { -} - -func (l discardLogSink) Enabled(int) bool { - return false -} - -func (l discardLogSink) Info(int, string, ...interface{}) { -} - -func (l discardLogSink) Error(error, string, ...interface{}) { -} - -func (l discardLogSink) WithValues(...interface{}) LogSink { - return l -} - -func (l discardLogSink) WithName(string) LogSink { - return l -} diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go deleted file mode 100644 index c3b56b3d..00000000 --- a/vendor/github.com/go-logr/logr/logr.go +++ /dev/null @@ -1,510 +0,0 @@ -/* -Copyright 2019 The logr Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This design derives from Dave Cheney's blog: -// http://dave.cheney.net/2015/11/05/lets-talk-about-logging - -// Package logr defines a general-purpose logging API and abstract interfaces -// to back that API. Packages in the Go ecosystem can depend on this package, -// while callers can implement logging with whatever backend is appropriate. -// -// Usage -// -// Logging is done using a Logger instance. Logger is a concrete type with -// methods, which defers the actual logging to a LogSink interface. The main -// methods of Logger are Info() and Error(). Arguments to Info() and Error() -// are key/value pairs rather than printf-style formatted strings, emphasizing -// "structured logging". -// -// With Go's standard log package, we might write: -// log.Printf("setting target value %s", targetValue) -// -// With logr's structured logging, we'd write: -// logger.Info("setting target", "value", targetValue) -// -// Errors are much the same. Instead of: -// log.Printf("failed to open the pod bay door for user %s: %v", user, err) -// -// We'd write: -// logger.Error(err, "failed to open the pod bay door", "user", user) -// -// Info() and Error() are very similar, but they are separate methods so that -// LogSink implementations can choose to do things like attach additional -// information (such as stack traces) on calls to Error(). Error() messages are -// always logged, regardless of the current verbosity. If there is no error -// instance available, passing nil is valid. -// -// Verbosity -// -// Often we want to log information only when the application in "verbose -// mode". To write log lines that are more verbose, Logger has a V() method. -// The higher the V-level of a log line, the less critical it is considered. -// Log-lines with V-levels that are not enabled (as per the LogSink) will not -// be written. Level V(0) is the default, and logger.V(0).Info() has the same -// meaning as logger.Info(). Negative V-levels have the same meaning as V(0). -// Error messages do not have a verbosity level and are always logged. -// -// Where we might have written: -// if flVerbose >= 2 { -// log.Printf("an unusual thing happened") -// } -// -// We can write: -// logger.V(2).Info("an unusual thing happened") -// -// Logger Names -// -// Logger instances can have name strings so that all messages logged through -// that instance have additional context. For example, you might want to add -// a subsystem name: -// -// logger.WithName("compactor").Info("started", "time", time.Now()) -// -// The WithName() method returns a new Logger, which can be passed to -// constructors or other functions for further use. Repeated use of WithName() -// will accumulate name "segments". These name segments will be joined in some -// way by the LogSink implementation. It is strongly recommended that name -// segments contain simple identifiers (letters, digits, and hyphen), and do -// not contain characters that could muddle the log output or confuse the -// joining operation (e.g. whitespace, commas, periods, slashes, brackets, -// quotes, etc). -// -// Saved Values -// -// Logger instances can store any number of key/value pairs, which will be -// logged alongside all messages logged through that instance. For example, -// you might want to create a Logger instance per managed object: -// -// With the standard log package, we might write: -// log.Printf("decided to set field foo to value %q for object %s/%s", -// targetValue, object.Namespace, object.Name) -// -// With logr we'd write: -// // Elsewhere: set up the logger to log the object name. -// obj.logger = mainLogger.WithValues( -// "name", obj.name, "namespace", obj.namespace) -// -// // later on... -// obj.logger.Info("setting foo", "value", targetValue) -// -// Best Practices -// -// Logger has very few hard rules, with the goal that LogSink implementations -// might have a lot of freedom to differentiate. There are, however, some -// things to consider. -// -// The log message consists of a constant message attached to the log line. -// This should generally be a simple description of what's occurring, and should -// never be a format string. Variable information can then be attached using -// named values. -// -// Keys are arbitrary strings, but should generally be constant values. Values -// may be any Go value, but how the value is formatted is determined by the -// LogSink implementation. -// -// Logger instances are meant to be passed around by value. Code that receives -// such a value can call its methods without having to check whether the -// instance is ready for use. -// -// Calling methods with the null logger (Logger{}) as instance will crash -// because it has no LogSink. Therefore this null logger should never be passed -// around. For cases where passing a logger is optional, a pointer to Logger -// should be used. -// -// Key Naming Conventions -// -// Keys are not strictly required to conform to any specification or regex, but -// it is recommended that they: -// * be human-readable and meaningful (not auto-generated or simple ordinals) -// * be constant (not dependent on input data) -// * contain only printable characters -// * not contain whitespace or punctuation -// * use lower case for simple keys and lowerCamelCase for more complex ones -// -// These guidelines help ensure that log data is processed properly regardless -// of the log implementation. For example, log implementations will try to -// output JSON data or will store data for later database (e.g. SQL) queries. -// -// While users are generally free to use key names of their choice, it's -// generally best to avoid using the following keys, as they're frequently used -// by implementations: -// * "caller": the calling information (file/line) of a particular log line -// * "error": the underlying error value in the `Error` method -// * "level": the log level -// * "logger": the name of the associated logger -// * "msg": the log message -// * "stacktrace": the stack trace associated with a particular log line or -// error (often from the `Error` message) -// * "ts": the timestamp for a log line -// -// Implementations are encouraged to make use of these keys to represent the -// above concepts, when necessary (for example, in a pure-JSON output form, it -// would be necessary to represent at least message and timestamp as ordinary -// named values). -// -// Break Glass -// -// Implementations may choose to give callers access to the underlying -// logging implementation. The recommended pattern for this is: -// // Underlier exposes access to the underlying logging implementation. -// // Since callers only have a logr.Logger, they have to know which -// // implementation is in use, so this interface is less of an abstraction -// // and more of way to test type conversion. -// type Underlier interface { -// GetUnderlying() -// } -// -// Logger grants access to the sink to enable type assertions like this: -// func DoSomethingWithImpl(log logr.Logger) { -// if underlier, ok := log.GetSink()(impl.Underlier) { -// implLogger := underlier.GetUnderlying() -// ... -// } -// } -// -// Custom `With*` functions can be implemented by copying the complete -// Logger struct and replacing the sink in the copy: -// // WithFooBar changes the foobar parameter in the log sink and returns a -// // new logger with that modified sink. It does nothing for loggers where -// // the sink doesn't support that parameter. -// func WithFoobar(log logr.Logger, foobar int) logr.Logger { -// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok { -// log = log.WithSink(foobarLogSink.WithFooBar(foobar)) -// } -// return log -// } -// -// Don't use New to construct a new Logger with a LogSink retrieved from an -// existing Logger. Source code attribution might not work correctly and -// unexported fields in Logger get lost. -// -// Beware that the same LogSink instance may be shared by different logger -// instances. Calling functions that modify the LogSink will affect all of -// those. -package logr - -import ( - "context" -) - -// New returns a new Logger instance. This is primarily used by libraries -// implementing LogSink, rather than end users. -func New(sink LogSink) Logger { - logger := Logger{} - logger.setSink(sink) - sink.Init(runtimeInfo) - return logger -} - -// setSink stores the sink and updates any related fields. It mutates the -// logger and thus is only safe to use for loggers that are not currently being -// used concurrently. -func (l *Logger) setSink(sink LogSink) { - l.sink = sink -} - -// GetSink returns the stored sink. -func (l Logger) GetSink() LogSink { - return l.sink -} - -// WithSink returns a copy of the logger with the new sink. -func (l Logger) WithSink(sink LogSink) Logger { - l.setSink(sink) - return l -} - -// Logger is an interface to an abstract logging implementation. This is a -// concrete type for performance reasons, but all the real work is passed on to -// a LogSink. Implementations of LogSink should provide their own constructors -// that return Logger, not LogSink. -// -// The underlying sink can be accessed through GetSink and be modified through -// WithSink. This enables the implementation of custom extensions (see "Break -// Glass" in the package documentation). Normally the sink should be used only -// indirectly. -type Logger struct { - sink LogSink - level int -} - -// Enabled tests whether this Logger is enabled. For example, commandline -// flags might be used to set the logging verbosity and disable some info logs. -func (l Logger) Enabled() bool { - return l.sink.Enabled(l.level) -} - -// Info logs a non-error message with the given key/value pairs as context. -// -// The msg argument should be used to add some constant description to the log -// line. The key/value pairs can then be used to add additional variable -// information. The key/value pairs must alternate string keys and arbitrary -// values. -func (l Logger) Info(msg string, keysAndValues ...interface{}) { - if l.Enabled() { - if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { - withHelper.GetCallStackHelper()() - } - l.sink.Info(l.level, msg, keysAndValues...) - } -} - -// Error logs an error, with the given message and key/value pairs as context. -// It functions similarly to Info, but may have unique behavior, and should be -// preferred for logging errors (see the package documentations for more -// information). The log message will always be emitted, regardless of -// verbosity level. -// -// The msg argument should be used to add context to any underlying error, -// while the err argument should be used to attach the actual error that -// triggered this log line, if present. The err parameter is optional -// and nil may be passed instead of an error instance. -func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { - if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { - withHelper.GetCallStackHelper()() - } - l.sink.Error(err, msg, keysAndValues...) -} - -// V returns a new Logger instance for a specific verbosity level, relative to -// this Logger. In other words, V-levels are additive. A higher verbosity -// level means a log message is less important. Negative V-levels are treated -// as 0. -func (l Logger) V(level int) Logger { - if level < 0 { - level = 0 - } - l.level += level - return l -} - -// WithValues returns a new Logger instance with additional key/value pairs. -// See Info for documentation on how key/value pairs work. -func (l Logger) WithValues(keysAndValues ...interface{}) Logger { - l.setSink(l.sink.WithValues(keysAndValues...)) - return l -} - -// WithName returns a new Logger instance with the specified name element added -// to the Logger's name. Successive calls with WithName append additional -// suffixes to the Logger's name. It's strongly recommended that name segments -// contain only letters, digits, and hyphens (see the package documentation for -// more information). -func (l Logger) WithName(name string) Logger { - l.setSink(l.sink.WithName(name)) - return l -} - -// WithCallDepth returns a Logger instance that offsets the call stack by the -// specified number of frames when logging call site information, if possible. -// This is useful for users who have helper functions between the "real" call -// site and the actual calls to Logger methods. If depth is 0 the attribution -// should be to the direct caller of this function. If depth is 1 the -// attribution should skip 1 call frame, and so on. Successive calls to this -// are additive. -// -// If the underlying log implementation supports a WithCallDepth(int) method, -// it will be called and the result returned. If the implementation does not -// support CallDepthLogSink, the original Logger will be returned. -// -// To skip one level, WithCallStackHelper() should be used instead of -// WithCallDepth(1) because it works with implementions that support the -// CallDepthLogSink and/or CallStackHelperLogSink interfaces. -func (l Logger) WithCallDepth(depth int) Logger { - if withCallDepth, ok := l.sink.(CallDepthLogSink); ok { - l.setSink(withCallDepth.WithCallDepth(depth)) - } - return l -} - -// WithCallStackHelper returns a new Logger instance that skips the direct -// caller when logging call site information, if possible. This is useful for -// users who have helper functions between the "real" call site and the actual -// calls to Logger methods and want to support loggers which depend on marking -// each individual helper function, like loggers based on testing.T. -// -// In addition to using that new logger instance, callers also must call the -// returned function. -// -// If the underlying log implementation supports a WithCallDepth(int) method, -// WithCallDepth(1) will be called to produce a new logger. If it supports a -// WithCallStackHelper() method, that will be also called. If the -// implementation does not support either of these, the original Logger will be -// returned. -func (l Logger) WithCallStackHelper() (func(), Logger) { - var helper func() - if withCallDepth, ok := l.sink.(CallDepthLogSink); ok { - l.setSink(withCallDepth.WithCallDepth(1)) - } - if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { - helper = withHelper.GetCallStackHelper() - } else { - helper = func() {} - } - return helper, l -} - -// contextKey is how we find Loggers in a context.Context. -type contextKey struct{} - -// FromContext returns a Logger from ctx or an error if no Logger is found. -func FromContext(ctx context.Context) (Logger, error) { - if v, ok := ctx.Value(contextKey{}).(Logger); ok { - return v, nil - } - - return Logger{}, notFoundError{} -} - -// notFoundError exists to carry an IsNotFound method. -type notFoundError struct{} - -func (notFoundError) Error() string { - return "no logr.Logger was present" -} - -func (notFoundError) IsNotFound() bool { - return true -} - -// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this -// returns a Logger that discards all log messages. -func FromContextOrDiscard(ctx context.Context) Logger { - if v, ok := ctx.Value(contextKey{}).(Logger); ok { - return v - } - - return Discard() -} - -// NewContext returns a new Context, derived from ctx, which carries the -// provided Logger. -func NewContext(ctx context.Context, logger Logger) context.Context { - return context.WithValue(ctx, contextKey{}, logger) -} - -// RuntimeInfo holds information that the logr "core" library knows which -// LogSinks might want to know. -type RuntimeInfo struct { - // CallDepth is the number of call frames the logr library adds between the - // end-user and the LogSink. LogSink implementations which choose to print - // the original logging site (e.g. file & line) should climb this many - // additional frames to find it. - CallDepth int -} - -// runtimeInfo is a static global. It must not be changed at run time. -var runtimeInfo = RuntimeInfo{ - CallDepth: 1, -} - -// LogSink represents a logging implementation. End-users will generally not -// interact with this type. -type LogSink interface { - // Init receives optional information about the logr library for LogSink - // implementations that need it. - Init(info RuntimeInfo) - - // Enabled tests whether this LogSink is enabled at the specified V-level. - // For example, commandline flags might be used to set the logging - // verbosity and disable some info logs. - Enabled(level int) bool - - // Info logs a non-error message with the given key/value pairs as context. - // The level argument is provided for optional logging. This method will - // only be called when Enabled(level) is true. See Logger.Info for more - // details. - Info(level int, msg string, keysAndValues ...interface{}) - - // Error logs an error, with the given message and key/value pairs as - // context. See Logger.Error for more details. - Error(err error, msg string, keysAndValues ...interface{}) - - // WithValues returns a new LogSink with additional key/value pairs. See - // Logger.WithValues for more details. - WithValues(keysAndValues ...interface{}) LogSink - - // WithName returns a new LogSink with the specified name appended. See - // Logger.WithName for more details. - WithName(name string) LogSink -} - -// CallDepthLogSink represents a Logger that knows how to climb the call stack -// to identify the original call site and can offset the depth by a specified -// number of frames. This is useful for users who have helper functions -// between the "real" call site and the actual calls to Logger methods. -// Implementations that log information about the call site (such as file, -// function, or line) would otherwise log information about the intermediate -// helper functions. -// -// This is an optional interface and implementations are not required to -// support it. -type CallDepthLogSink interface { - // WithCallDepth returns a LogSink that will offset the call - // stack by the specified number of frames when logging call - // site information. - // - // If depth is 0, the LogSink should skip exactly the number - // of call frames defined in RuntimeInfo.CallDepth when Info - // or Error are called, i.e. the attribution should be to the - // direct caller of Logger.Info or Logger.Error. - // - // If depth is 1 the attribution should skip 1 call frame, and so on. - // Successive calls to this are additive. - WithCallDepth(depth int) LogSink -} - -// CallStackHelperLogSink represents a Logger that knows how to climb -// the call stack to identify the original call site and can skip -// intermediate helper functions if they mark themselves as -// helper. Go's testing package uses that approach. -// -// This is useful for users who have helper functions between the -// "real" call site and the actual calls to Logger methods. -// Implementations that log information about the call site (such as -// file, function, or line) would otherwise log information about the -// intermediate helper functions. -// -// This is an optional interface and implementations are not required -// to support it. Implementations that choose to support this must not -// simply implement it as WithCallDepth(1), because -// Logger.WithCallStackHelper will call both methods if they are -// present. This should only be implemented for LogSinks that actually -// need it, as with testing.T. -type CallStackHelperLogSink interface { - // GetCallStackHelper returns a function that must be called - // to mark the direct caller as helper function when logging - // call site information. - GetCallStackHelper() func() -} - -// Marshaler is an optional interface that logged values may choose to -// implement. Loggers with structured output, such as JSON, should -// log the object return by the MarshalLog method instead of the -// original value. -type Marshaler interface { - // MarshalLog can be used to: - // - ensure that structs are not logged as strings when the original - // value has a String method: return a different type without a - // String method - // - select which fields of a complex type should get logged: - // return a simpler struct with fewer fields - // - log unexported fields: return a different struct - // with exported fields - // - // It may return any value of any type. - MarshalLog() interface{} -} diff --git a/vendor/github.com/go-openapi/jsonpointer/.editorconfig b/vendor/github.com/go-openapi/jsonpointer/.editorconfig deleted file mode 100644 index 3152da69..00000000 --- a/vendor/github.com/go-openapi/jsonpointer/.editorconfig +++ /dev/null @@ -1,26 +0,0 @@ -# top-most EditorConfig file -root = true - -# Unix-style newlines with a newline ending every file -[*] -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true - -# Set default charset -[*.{js,py,go,scala,rb,java,html,css,less,sass,md}] -charset = utf-8 - -# Tab indentation (no size specified) -[*.go] -indent_style = tab - -[*.md] -trim_trailing_whitespace = false - -# Matches the exact files either package.json or .travis.yml -[{package.json,.travis.yml}] -indent_style = space -indent_size = 2 diff --git a/vendor/github.com/go-openapi/jsonpointer/.gitignore b/vendor/github.com/go-openapi/jsonpointer/.gitignore deleted file mode 100644 index 769c2440..00000000 --- a/vendor/github.com/go-openapi/jsonpointer/.gitignore +++ /dev/null @@ -1 +0,0 @@ -secrets.yml diff --git a/vendor/github.com/go-openapi/jsonpointer/.travis.yml b/vendor/github.com/go-openapi/jsonpointer/.travis.yml deleted file mode 100644 index 03a22fe0..00000000 --- a/vendor/github.com/go-openapi/jsonpointer/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.15.x -install: -- GO111MODULE=off go get -u gotest.tools/gotestsum -env: -- GO111MODULE=on -language: go -notifications: - slack: - secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md b/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md deleted file mode 100644 index 9322b065..00000000 --- a/vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers 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, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at ivan+abuse@flanders.co.nz. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/go-openapi/jsonpointer/LICENSE b/vendor/github.com/go-openapi/jsonpointer/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/github.com/go-openapi/jsonpointer/LICENSE +++ /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/go-openapi/jsonpointer/README.md b/vendor/github.com/go-openapi/jsonpointer/README.md deleted file mode 100644 index 813788af..00000000 --- a/vendor/github.com/go-openapi/jsonpointer/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# gojsonpointer [![Build Status](https://travis-ci.org/go-openapi/jsonpointer.svg?branch=master)](https://travis-ci.org/go-openapi/jsonpointer) [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) - -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonpointer?status.svg)](http://godoc.org/github.com/go-openapi/jsonpointer) -An implementation of JSON Pointer - Go language - -## Status -Completed YES - -Tested YES - -## References -http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 - -### Note -The 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented. diff --git a/vendor/github.com/go-openapi/jsonpointer/pointer.go b/vendor/github.com/go-openapi/jsonpointer/pointer.go deleted file mode 100644 index 7df9853d..00000000 --- a/vendor/github.com/go-openapi/jsonpointer/pointer.go +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) -// -// 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. - -// author sigu-399 -// author-github https://github.com/sigu-399 -// author-mail sigu.399@gmail.com -// -// repository-name jsonpointer -// repository-desc An implementation of JSON Pointer - Go language -// -// description Main and unique file. -// -// created 25-02-2013 - -package jsonpointer - -import ( - "errors" - "fmt" - "reflect" - "strconv" - "strings" - - "github.com/go-openapi/swag" -) - -const ( - emptyPointer = `` - pointerSeparator = `/` - - invalidStart = `JSON pointer must be empty or start with a "` + pointerSeparator -) - -var jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem() -var jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem() - -// JSONPointable is an interface for structs to implement when they need to customize the -// json pointer process -type JSONPointable interface { - JSONLookup(string) (interface{}, error) -} - -// JSONSetable is an interface for structs to implement when they need to customize the -// json pointer process -type JSONSetable interface { - JSONSet(string, interface{}) error -} - -// New creates a new json pointer for the given string -func New(jsonPointerString string) (Pointer, error) { - - var p Pointer - err := p.parse(jsonPointerString) - return p, err - -} - -// Pointer the json pointer reprsentation -type Pointer struct { - referenceTokens []string -} - -// "Constructor", parses the given string JSON pointer -func (p *Pointer) parse(jsonPointerString string) error { - - var err error - - if jsonPointerString != emptyPointer { - if !strings.HasPrefix(jsonPointerString, pointerSeparator) { - err = errors.New(invalidStart) - } else { - referenceTokens := strings.Split(jsonPointerString, pointerSeparator) - for _, referenceToken := range referenceTokens[1:] { - p.referenceTokens = append(p.referenceTokens, referenceToken) - } - } - } - - return err -} - -// Get uses the pointer to retrieve a value from a JSON document -func (p *Pointer) Get(document interface{}) (interface{}, reflect.Kind, error) { - return p.get(document, swag.DefaultJSONNameProvider) -} - -// Set uses the pointer to set a value from a JSON document -func (p *Pointer) Set(document interface{}, value interface{}) (interface{}, error) { - return document, p.set(document, value, swag.DefaultJSONNameProvider) -} - -// GetForToken gets a value for a json pointer token 1 level deep -func GetForToken(document interface{}, decodedToken string) (interface{}, reflect.Kind, error) { - return getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider) -} - -// SetForToken gets a value for a json pointer token 1 level deep -func SetForToken(document interface{}, decodedToken string, value interface{}) (interface{}, error) { - return document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider) -} - -func getSingleImpl(node interface{}, decodedToken string, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { - rValue := reflect.Indirect(reflect.ValueOf(node)) - kind := rValue.Kind() - - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) - if err != nil { - return nil, kind, err - } - return r, kind, nil - } - - switch kind { - case reflect.Struct: - nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) - if !ok { - return nil, kind, fmt.Errorf("object has no field %q", decodedToken) - } - fld := rValue.FieldByName(nm) - return fld.Interface(), kind, nil - - case reflect.Map: - kv := reflect.ValueOf(decodedToken) - mv := rValue.MapIndex(kv) - - if mv.IsValid() { - return mv.Interface(), kind, nil - } - return nil, kind, fmt.Errorf("object has no key %q", decodedToken) - - case reflect.Slice: - tokenIndex, err := strconv.Atoi(decodedToken) - if err != nil { - return nil, kind, err - } - sLength := rValue.Len() - if tokenIndex < 0 || tokenIndex >= sLength { - return nil, kind, fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength-1, tokenIndex) - } - - elem := rValue.Index(tokenIndex) - return elem.Interface(), kind, nil - - default: - return nil, kind, fmt.Errorf("invalid token reference %q", decodedToken) - } - -} - -func setSingleImpl(node, data interface{}, decodedToken string, nameProvider *swag.NameProvider) error { - rValue := reflect.Indirect(reflect.ValueOf(node)) - - if ns, ok := node.(JSONSetable); ok { // pointer impl - return ns.JSONSet(decodedToken, data) - } - - if rValue.Type().Implements(jsonSetableType) { - return node.(JSONSetable).JSONSet(decodedToken, data) - } - - switch rValue.Kind() { - case reflect.Struct: - nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) - if !ok { - return fmt.Errorf("object has no field %q", decodedToken) - } - fld := rValue.FieldByName(nm) - if fld.IsValid() { - fld.Set(reflect.ValueOf(data)) - } - return nil - - case reflect.Map: - kv := reflect.ValueOf(decodedToken) - rValue.SetMapIndex(kv, reflect.ValueOf(data)) - return nil - - case reflect.Slice: - tokenIndex, err := strconv.Atoi(decodedToken) - if err != nil { - return err - } - sLength := rValue.Len() - if tokenIndex < 0 || tokenIndex >= sLength { - return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex) - } - - elem := rValue.Index(tokenIndex) - if !elem.CanSet() { - return fmt.Errorf("can't set slice index %s to %v", decodedToken, data) - } - elem.Set(reflect.ValueOf(data)) - return nil - - default: - return fmt.Errorf("invalid token reference %q", decodedToken) - } - -} - -func (p *Pointer) get(node interface{}, nameProvider *swag.NameProvider) (interface{}, reflect.Kind, error) { - - if nameProvider == nil { - nameProvider = swag.DefaultJSONNameProvider - } - - kind := reflect.Invalid - - // Full document when empty - if len(p.referenceTokens) == 0 { - return node, kind, nil - } - - for _, token := range p.referenceTokens { - - decodedToken := Unescape(token) - - r, knd, err := getSingleImpl(node, decodedToken, nameProvider) - if err != nil { - return nil, knd, err - } - node, kind = r, knd - - } - - rValue := reflect.ValueOf(node) - kind = rValue.Kind() - - return node, kind, nil -} - -func (p *Pointer) set(node, data interface{}, nameProvider *swag.NameProvider) error { - knd := reflect.ValueOf(node).Kind() - - if knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array { - return fmt.Errorf("only structs, pointers, maps and slices are supported for setting values") - } - - if nameProvider == nil { - nameProvider = swag.DefaultJSONNameProvider - } - - // Full document when empty - if len(p.referenceTokens) == 0 { - return nil - } - - lastI := len(p.referenceTokens) - 1 - for i, token := range p.referenceTokens { - isLastToken := i == lastI - decodedToken := Unescape(token) - - if isLastToken { - - return setSingleImpl(node, data, decodedToken, nameProvider) - } - - rValue := reflect.Indirect(reflect.ValueOf(node)) - kind := rValue.Kind() - - if rValue.Type().Implements(jsonPointableType) { - r, err := node.(JSONPointable).JSONLookup(decodedToken) - if err != nil { - return err - } - fld := reflect.ValueOf(r) - if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { - node = fld.Addr().Interface() - continue - } - node = r - continue - } - - switch kind { - case reflect.Struct: - nm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken) - if !ok { - return fmt.Errorf("object has no field %q", decodedToken) - } - fld := rValue.FieldByName(nm) - if fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr { - node = fld.Addr().Interface() - continue - } - node = fld.Interface() - - case reflect.Map: - kv := reflect.ValueOf(decodedToken) - mv := rValue.MapIndex(kv) - - if !mv.IsValid() { - return fmt.Errorf("object has no key %q", decodedToken) - } - if mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Ptr { - node = mv.Addr().Interface() - continue - } - node = mv.Interface() - - case reflect.Slice: - tokenIndex, err := strconv.Atoi(decodedToken) - if err != nil { - return err - } - sLength := rValue.Len() - if tokenIndex < 0 || tokenIndex >= sLength { - return fmt.Errorf("index out of bounds array[0,%d] index '%d'", sLength, tokenIndex) - } - - elem := rValue.Index(tokenIndex) - if elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Ptr { - node = elem.Addr().Interface() - continue - } - node = elem.Interface() - - default: - return fmt.Errorf("invalid token reference %q", decodedToken) - } - - } - - return nil -} - -// DecodedTokens returns the decoded tokens -func (p *Pointer) DecodedTokens() []string { - result := make([]string, 0, len(p.referenceTokens)) - for _, t := range p.referenceTokens { - result = append(result, Unescape(t)) - } - return result -} - -// IsEmpty returns true if this is an empty json pointer -// this indicates that it points to the root document -func (p *Pointer) IsEmpty() bool { - return len(p.referenceTokens) == 0 -} - -// Pointer to string representation function -func (p *Pointer) String() string { - - if len(p.referenceTokens) == 0 { - return emptyPointer - } - - pointerString := pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator) - - return pointerString -} - -// Specific JSON pointer encoding here -// ~0 => ~ -// ~1 => / -// ... and vice versa - -const ( - encRefTok0 = `~0` - encRefTok1 = `~1` - decRefTok0 = `~` - decRefTok1 = `/` -) - -// Unescape unescapes a json pointer reference token string to the original representation -func Unescape(token string) string { - step1 := strings.Replace(token, encRefTok1, decRefTok1, -1) - step2 := strings.Replace(step1, encRefTok0, decRefTok0, -1) - return step2 -} - -// Escape escapes a pointer reference token string -func Escape(token string) string { - step1 := strings.Replace(token, decRefTok0, encRefTok0, -1) - step2 := strings.Replace(step1, decRefTok1, encRefTok1, -1) - return step2 -} diff --git a/vendor/github.com/go-openapi/jsonreference/.gitignore b/vendor/github.com/go-openapi/jsonreference/.gitignore deleted file mode 100644 index 769c2440..00000000 --- a/vendor/github.com/go-openapi/jsonreference/.gitignore +++ /dev/null @@ -1 +0,0 @@ -secrets.yml diff --git a/vendor/github.com/go-openapi/jsonreference/.golangci.yml b/vendor/github.com/go-openapi/jsonreference/.golangci.yml deleted file mode 100644 index f9381aee..00000000 --- a/vendor/github.com/go-openapi/jsonreference/.golangci.yml +++ /dev/null @@ -1,41 +0,0 @@ -linters-settings: - govet: - check-shadowing: true - golint: - min-confidence: 0 - gocyclo: - min-complexity: 30 - maligned: - suggest-new: true - dupl: - threshold: 100 - goconst: - min-len: 2 - min-occurrences: 4 -linters: - enable-all: true - disable: - - maligned - - lll - - gochecknoglobals - - godox - - gocognit - - whitespace - - wsl - - funlen - - gochecknoglobals - - gochecknoinits - - scopelint - - wrapcheck - - exhaustivestruct - - exhaustive - - nlreturn - - testpackage - - gci - - gofumpt - - goerr113 - - gomnd - - tparallel - - nestif - - godot - - errorlint diff --git a/vendor/github.com/go-openapi/jsonreference/.travis.yml b/vendor/github.com/go-openapi/jsonreference/.travis.yml deleted file mode 100644 index 05482f4b..00000000 --- a/vendor/github.com/go-openapi/jsonreference/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.x -install: -- go get gotest.tools/gotestsum -jobs: - include: - # include linting job, but only for latest go version and amd64 arch - - go: 1.x - arch: amd64 - install: - go get github.com/golangci/golangci-lint/cmd/golangci-lint - script: - - golangci-lint run --new-from-rev master -env: -- GO111MODULE=on -language: go -notifications: - slack: - secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md b/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md deleted file mode 100644 index 9322b065..00000000 --- a/vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers 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, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at ivan+abuse@flanders.co.nz. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/go-openapi/jsonreference/LICENSE b/vendor/github.com/go-openapi/jsonreference/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/github.com/go-openapi/jsonreference/LICENSE +++ /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/go-openapi/jsonreference/README.md b/vendor/github.com/go-openapi/jsonreference/README.md deleted file mode 100644 index b94753aa..00000000 --- a/vendor/github.com/go-openapi/jsonreference/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# gojsonreference [![Build Status](https://travis-ci.org/go-openapi/jsonreference.svg?branch=master)](https://travis-ci.org/go-openapi/jsonreference) [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) - -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonreference?status.svg)](http://godoc.org/github.com/go-openapi/jsonreference) -An implementation of JSON Reference - Go language - -## Status -Feature complete. Stable API - -## Dependencies -https://github.com/go-openapi/jsonpointer - -## References -http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07 - -http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 diff --git a/vendor/github.com/go-openapi/jsonreference/reference.go b/vendor/github.com/go-openapi/jsonreference/reference.go deleted file mode 100644 index 3bc0a6e2..00000000 --- a/vendor/github.com/go-openapi/jsonreference/reference.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2013 sigu-399 ( https://github.com/sigu-399 ) -// -// 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. - -// author sigu-399 -// author-github https://github.com/sigu-399 -// author-mail sigu.399@gmail.com -// -// repository-name jsonreference -// repository-desc An implementation of JSON Reference - Go language -// -// description Main and unique file. -// -// created 26-02-2013 - -package jsonreference - -import ( - "errors" - "net/url" - "strings" - - "github.com/PuerkitoBio/purell" - "github.com/go-openapi/jsonpointer" -) - -const ( - fragmentRune = `#` -) - -// New creates a new reference for the given string -func New(jsonReferenceString string) (Ref, error) { - - var r Ref - err := r.parse(jsonReferenceString) - return r, err - -} - -// MustCreateRef parses the ref string and panics when it's invalid. -// Use the New method for a version that returns an error -func MustCreateRef(ref string) Ref { - r, err := New(ref) - if err != nil { - panic(err) - } - return r -} - -// Ref represents a json reference object -type Ref struct { - referenceURL *url.URL - referencePointer jsonpointer.Pointer - - HasFullURL bool - HasURLPathOnly bool - HasFragmentOnly bool - HasFileScheme bool - HasFullFilePath bool -} - -// GetURL gets the URL for this reference -func (r *Ref) GetURL() *url.URL { - return r.referenceURL -} - -// GetPointer gets the json pointer for this reference -func (r *Ref) GetPointer() *jsonpointer.Pointer { - return &r.referencePointer -} - -// String returns the best version of the url for this reference -func (r *Ref) String() string { - - if r.referenceURL != nil { - return r.referenceURL.String() - } - - if r.HasFragmentOnly { - return fragmentRune + r.referencePointer.String() - } - - return r.referencePointer.String() -} - -// IsRoot returns true if this reference is a root document -func (r *Ref) IsRoot() bool { - return r.referenceURL != nil && - !r.IsCanonical() && - !r.HasURLPathOnly && - r.referenceURL.Fragment == "" -} - -// IsCanonical returns true when this pointer starts with http(s):// or file:// -func (r *Ref) IsCanonical() bool { - return (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullURL) -} - -// "Constructor", parses the given string JSON reference -func (r *Ref) parse(jsonReferenceString string) error { - - parsed, err := url.Parse(jsonReferenceString) - if err != nil { - return err - } - - r.referenceURL, _ = url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes)) - refURL := r.referenceURL - - if refURL.Scheme != "" && refURL.Host != "" { - r.HasFullURL = true - } else { - if refURL.Path != "" { - r.HasURLPathOnly = true - } else if refURL.RawQuery == "" && refURL.Fragment != "" { - r.HasFragmentOnly = true - } - } - - r.HasFileScheme = refURL.Scheme == "file" - r.HasFullFilePath = strings.HasPrefix(refURL.Path, "/") - - // invalid json-pointer error means url has no json-pointer fragment. simply ignore error - r.referencePointer, _ = jsonpointer.New(refURL.Fragment) - - return nil -} - -// Inherits creates a new reference from a parent and a child -// If the child cannot inherit from the parent, an error is returned -func (r *Ref) Inherits(child Ref) (*Ref, error) { - childURL := child.GetURL() - parentURL := r.GetURL() - if childURL == nil { - return nil, errors.New("child url is nil") - } - if parentURL == nil { - return &child, nil - } - - ref, err := New(parentURL.ResolveReference(childURL).String()) - if err != nil { - return nil, err - } - return &ref, nil -} diff --git a/vendor/github.com/go-openapi/swag/.editorconfig b/vendor/github.com/go-openapi/swag/.editorconfig deleted file mode 100644 index 3152da69..00000000 --- a/vendor/github.com/go-openapi/swag/.editorconfig +++ /dev/null @@ -1,26 +0,0 @@ -# top-most EditorConfig file -root = true - -# Unix-style newlines with a newline ending every file -[*] -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true - -# Set default charset -[*.{js,py,go,scala,rb,java,html,css,less,sass,md}] -charset = utf-8 - -# Tab indentation (no size specified) -[*.go] -indent_style = tab - -[*.md] -trim_trailing_whitespace = false - -# Matches the exact files either package.json or .travis.yml -[{package.json,.travis.yml}] -indent_style = space -indent_size = 2 diff --git a/vendor/github.com/go-openapi/swag/.gitignore b/vendor/github.com/go-openapi/swag/.gitignore deleted file mode 100644 index d69b53ac..00000000 --- a/vendor/github.com/go-openapi/swag/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -secrets.yml -vendor -Godeps -.idea diff --git a/vendor/github.com/go-openapi/swag/.golangci.yml b/vendor/github.com/go-openapi/swag/.golangci.yml deleted file mode 100644 index 813c47aa..00000000 --- a/vendor/github.com/go-openapi/swag/.golangci.yml +++ /dev/null @@ -1,39 +0,0 @@ -linters-settings: - govet: - check-shadowing: true - golint: - min-confidence: 0 - gocyclo: - min-complexity: 25 - maligned: - suggest-new: true - dupl: - threshold: 100 - goconst: - min-len: 3 - min-occurrences: 2 - -linters: - enable-all: true - disable: - - maligned - - lll - - gochecknoinits - - gochecknoglobals - - nlreturn - - testpackage - - wrapcheck - - gomnd - - exhaustive - - exhaustivestruct - - goerr113 - - wsl - - whitespace - - gofumpt - - godot - - nestif - - godox - - funlen - - gci - - gocognit - - paralleltest diff --git a/vendor/github.com/go-openapi/swag/.travis.yml b/vendor/github.com/go-openapi/swag/.travis.yml deleted file mode 100644 index fc25a887..00000000 --- a/vendor/github.com/go-openapi/swag/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -after_success: -- bash <(curl -s https://codecov.io/bash) -go: -- 1.14.x -- 1.x -arch: -- amd64 -jobs: - include: - # include arch ppc, but only for latest go version - skip testing for race - - go: 1.x - arch: ppc64le - install: ~ - script: - - go test -v - - #- go: 1.x - # arch: arm - # install: ~ - # script: - # - go test -v - - # include linting job, but only for latest go version and amd64 arch - - go: 1.x - arch: amd64 - install: - go get github.com/golangci/golangci-lint/cmd/golangci-lint - script: - - golangci-lint run --new-from-rev master -install: -- GO111MODULE=off go get -u gotest.tools/gotestsum -language: go -notifications: - slack: - secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E= -script: -- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./... diff --git a/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md b/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md deleted file mode 100644 index 9322b065..00000000 --- a/vendor/github.com/go-openapi/swag/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers 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, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at ivan+abuse@flanders.co.nz. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/github.com/go-openapi/swag/LICENSE b/vendor/github.com/go-openapi/swag/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/github.com/go-openapi/swag/LICENSE +++ /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/go-openapi/swag/README.md b/vendor/github.com/go-openapi/swag/README.md deleted file mode 100644 index 217f6fa5..00000000 --- a/vendor/github.com/go-openapi/swag/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Swag [![Build Status](https://travis-ci.org/go-openapi/swag.svg?branch=master)](https://travis-ci.org/go-openapi/swag) [![codecov](https://codecov.io/gh/go-openapi/swag/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/swag) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) - -[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE) -[![GoDoc](https://godoc.org/github.com/go-openapi/swag?status.svg)](http://godoc.org/github.com/go-openapi/swag) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/swag)](https://goreportcard.com/report/github.com/go-openapi/swag) - -Contains a bunch of helper functions for go-openapi and go-swagger projects. - -You may also use it standalone for your projects. - -* convert between value and pointers for builtin types -* convert from string to builtin types (wraps strconv) -* fast json concatenation -* search in path -* load from file or http -* name mangling - - -This repo has only few dependencies outside of the standard library: - -* YAML utilities depend on gopkg.in/yaml.v2 diff --git a/vendor/github.com/go-openapi/swag/convert.go b/vendor/github.com/go-openapi/swag/convert.go deleted file mode 100644 index fc085aeb..00000000 --- a/vendor/github.com/go-openapi/swag/convert.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "math" - "strconv" - "strings" -) - -// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER -const ( - maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1 - minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1 - epsilon float64 = 1e-9 -) - -// IsFloat64AJSONInteger allow for integers [-2^53, 2^53-1] inclusive -func IsFloat64AJSONInteger(f float64) bool { - if math.IsNaN(f) || math.IsInf(f, 0) || f < minJSONFloat || f > maxJSONFloat { - return false - } - fa := math.Abs(f) - g := float64(uint64(f)) - ga := math.Abs(g) - - diff := math.Abs(f - g) - - // more info: https://floating-point-gui.de/errors/comparison/#look-out-for-edge-cases - switch { - case f == g: // best case - return true - case f == float64(int64(f)) || f == float64(uint64(f)): // optimistic case - return true - case f == 0 || g == 0 || diff < math.SmallestNonzeroFloat64: // very close to 0 values - return diff < (epsilon * math.SmallestNonzeroFloat64) - } - // check the relative error - return diff/math.Min(fa+ga, math.MaxFloat64) < epsilon -} - -var evaluatesAsTrue map[string]struct{} - -func init() { - evaluatesAsTrue = map[string]struct{}{ - "true": {}, - "1": {}, - "yes": {}, - "ok": {}, - "y": {}, - "on": {}, - "selected": {}, - "checked": {}, - "t": {}, - "enabled": {}, - } -} - -// ConvertBool turn a string into a boolean -func ConvertBool(str string) (bool, error) { - _, ok := evaluatesAsTrue[strings.ToLower(str)] - return ok, nil -} - -// ConvertFloat32 turn a string into a float32 -func ConvertFloat32(str string) (float32, error) { - f, err := strconv.ParseFloat(str, 32) - if err != nil { - return 0, err - } - return float32(f), nil -} - -// ConvertFloat64 turn a string into a float64 -func ConvertFloat64(str string) (float64, error) { - return strconv.ParseFloat(str, 64) -} - -// ConvertInt8 turn a string into an int8 -func ConvertInt8(str string) (int8, error) { - i, err := strconv.ParseInt(str, 10, 8) - if err != nil { - return 0, err - } - return int8(i), nil -} - -// ConvertInt16 turn a string into an int16 -func ConvertInt16(str string) (int16, error) { - i, err := strconv.ParseInt(str, 10, 16) - if err != nil { - return 0, err - } - return int16(i), nil -} - -// ConvertInt32 turn a string into an int32 -func ConvertInt32(str string) (int32, error) { - i, err := strconv.ParseInt(str, 10, 32) - if err != nil { - return 0, err - } - return int32(i), nil -} - -// ConvertInt64 turn a string into an int64 -func ConvertInt64(str string) (int64, error) { - return strconv.ParseInt(str, 10, 64) -} - -// ConvertUint8 turn a string into an uint8 -func ConvertUint8(str string) (uint8, error) { - i, err := strconv.ParseUint(str, 10, 8) - if err != nil { - return 0, err - } - return uint8(i), nil -} - -// ConvertUint16 turn a string into an uint16 -func ConvertUint16(str string) (uint16, error) { - i, err := strconv.ParseUint(str, 10, 16) - if err != nil { - return 0, err - } - return uint16(i), nil -} - -// ConvertUint32 turn a string into an uint32 -func ConvertUint32(str string) (uint32, error) { - i, err := strconv.ParseUint(str, 10, 32) - if err != nil { - return 0, err - } - return uint32(i), nil -} - -// ConvertUint64 turn a string into an uint64 -func ConvertUint64(str string) (uint64, error) { - return strconv.ParseUint(str, 10, 64) -} - -// FormatBool turns a boolean into a string -func FormatBool(value bool) string { - return strconv.FormatBool(value) -} - -// FormatFloat32 turns a float32 into a string -func FormatFloat32(value float32) string { - return strconv.FormatFloat(float64(value), 'f', -1, 32) -} - -// FormatFloat64 turns a float64 into a string -func FormatFloat64(value float64) string { - return strconv.FormatFloat(value, 'f', -1, 64) -} - -// FormatInt8 turns an int8 into a string -func FormatInt8(value int8) string { - return strconv.FormatInt(int64(value), 10) -} - -// FormatInt16 turns an int16 into a string -func FormatInt16(value int16) string { - return strconv.FormatInt(int64(value), 10) -} - -// FormatInt32 turns an int32 into a string -func FormatInt32(value int32) string { - return strconv.Itoa(int(value)) -} - -// FormatInt64 turns an int64 into a string -func FormatInt64(value int64) string { - return strconv.FormatInt(value, 10) -} - -// FormatUint8 turns an uint8 into a string -func FormatUint8(value uint8) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint16 turns an uint16 into a string -func FormatUint16(value uint16) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint32 turns an uint32 into a string -func FormatUint32(value uint32) string { - return strconv.FormatUint(uint64(value), 10) -} - -// FormatUint64 turns an uint64 into a string -func FormatUint64(value uint64) string { - return strconv.FormatUint(value, 10) -} diff --git a/vendor/github.com/go-openapi/swag/convert_types.go b/vendor/github.com/go-openapi/swag/convert_types.go deleted file mode 100644 index c49cc473..00000000 --- a/vendor/github.com/go-openapi/swag/convert_types.go +++ /dev/null @@ -1,730 +0,0 @@ -package swag - -import "time" - -// This file was taken from the aws go sdk - -// String returns a pointer to of the string value passed in. -func String(v string) *string { - return &v -} - -// StringValue returns the value of the string pointer passed in or -// "" if the pointer is nil. -func StringValue(v *string) string { - if v != nil { - return *v - } - return "" -} - -// StringSlice converts a slice of string values into a slice of -// string pointers -func StringSlice(src []string) []*string { - dst := make([]*string, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// StringValueSlice converts a slice of string pointers into a slice of -// string values -func StringValueSlice(src []*string) []string { - dst := make([]string, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// StringMap converts a string map of string values into a string -// map of string pointers -func StringMap(src map[string]string) map[string]*string { - dst := make(map[string]*string) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// StringValueMap converts a string map of string pointers into a string -// map of string values -func StringValueMap(src map[string]*string) map[string]string { - dst := make(map[string]string) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Bool returns a pointer to of the bool value passed in. -func Bool(v bool) *bool { - return &v -} - -// BoolValue returns the value of the bool pointer passed in or -// false if the pointer is nil. -func BoolValue(v *bool) bool { - if v != nil { - return *v - } - return false -} - -// BoolSlice converts a slice of bool values into a slice of -// bool pointers -func BoolSlice(src []bool) []*bool { - dst := make([]*bool, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// BoolValueSlice converts a slice of bool pointers into a slice of -// bool values -func BoolValueSlice(src []*bool) []bool { - dst := make([]bool, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// BoolMap converts a string map of bool values into a string -// map of bool pointers -func BoolMap(src map[string]bool) map[string]*bool { - dst := make(map[string]*bool) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// BoolValueMap converts a string map of bool pointers into a string -// map of bool values -func BoolValueMap(src map[string]*bool) map[string]bool { - dst := make(map[string]bool) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int returns a pointer to of the int value passed in. -func Int(v int) *int { - return &v -} - -// IntValue returns the value of the int pointer passed in or -// 0 if the pointer is nil. -func IntValue(v *int) int { - if v != nil { - return *v - } - return 0 -} - -// IntSlice converts a slice of int values into a slice of -// int pointers -func IntSlice(src []int) []*int { - dst := make([]*int, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// IntValueSlice converts a slice of int pointers into a slice of -// int values -func IntValueSlice(src []*int) []int { - dst := make([]int, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// IntMap converts a string map of int values into a string -// map of int pointers -func IntMap(src map[string]int) map[string]*int { - dst := make(map[string]*int) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// IntValueMap converts a string map of int pointers into a string -// map of int values -func IntValueMap(src map[string]*int) map[string]int { - dst := make(map[string]int) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int32 returns a pointer to of the int32 value passed in. -func Int32(v int32) *int32 { - return &v -} - -// Int32Value returns the value of the int32 pointer passed in or -// 0 if the pointer is nil. -func Int32Value(v *int32) int32 { - if v != nil { - return *v - } - return 0 -} - -// Int32Slice converts a slice of int32 values into a slice of -// int32 pointers -func Int32Slice(src []int32) []*int32 { - dst := make([]*int32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int32ValueSlice converts a slice of int32 pointers into a slice of -// int32 values -func Int32ValueSlice(src []*int32) []int32 { - dst := make([]int32, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Int32Map converts a string map of int32 values into a string -// map of int32 pointers -func Int32Map(src map[string]int32) map[string]*int32 { - dst := make(map[string]*int32) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Int32ValueMap converts a string map of int32 pointers into a string -// map of int32 values -func Int32ValueMap(src map[string]*int32) map[string]int32 { - dst := make(map[string]int32) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Int64 returns a pointer to of the int64 value passed in. -func Int64(v int64) *int64 { - return &v -} - -// Int64Value returns the value of the int64 pointer passed in or -// 0 if the pointer is nil. -func Int64Value(v *int64) int64 { - if v != nil { - return *v - } - return 0 -} - -// Int64Slice converts a slice of int64 values into a slice of -// int64 pointers -func Int64Slice(src []int64) []*int64 { - dst := make([]*int64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Int64ValueSlice converts a slice of int64 pointers into a slice of -// int64 values -func Int64ValueSlice(src []*int64) []int64 { - dst := make([]int64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Int64Map converts a string map of int64 values into a string -// map of int64 pointers -func Int64Map(src map[string]int64) map[string]*int64 { - dst := make(map[string]*int64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Int64ValueMap converts a string map of int64 pointers into a string -// map of int64 values -func Int64ValueMap(src map[string]*int64) map[string]int64 { - dst := make(map[string]int64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint16 returns a pointer to of the uint16 value passed in. -func Uint16(v uint16) *uint16 { - return &v -} - -// Uint16Value returns the value of the uint16 pointer passed in or -// 0 if the pointer is nil. -func Uint16Value(v *uint16) uint16 { - if v != nil { - return *v - } - - return 0 -} - -// Uint16Slice converts a slice of uint16 values into a slice of -// uint16 pointers -func Uint16Slice(src []uint16) []*uint16 { - dst := make([]*uint16, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - - return dst -} - -// Uint16ValueSlice converts a slice of uint16 pointers into a slice of -// uint16 values -func Uint16ValueSlice(src []*uint16) []uint16 { - dst := make([]uint16, len(src)) - - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - - return dst -} - -// Uint16Map converts a string map of uint16 values into a string -// map of uint16 pointers -func Uint16Map(src map[string]uint16) map[string]*uint16 { - dst := make(map[string]*uint16) - - for k, val := range src { - v := val - dst[k] = &v - } - - return dst -} - -// Uint16ValueMap converts a string map of uint16 pointers into a string -// map of uint16 values -func Uint16ValueMap(src map[string]*uint16) map[string]uint16 { - dst := make(map[string]uint16) - - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - - return dst -} - -// Uint returns a pointer to of the uint value passed in. -func Uint(v uint) *uint { - return &v -} - -// UintValue returns the value of the uint pointer passed in or -// 0 if the pointer is nil. -func UintValue(v *uint) uint { - if v != nil { - return *v - } - return 0 -} - -// UintSlice converts a slice of uint values into a slice of -// uint pointers -func UintSlice(src []uint) []*uint { - dst := make([]*uint, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// UintValueSlice converts a slice of uint pointers into a slice of -// uint values -func UintValueSlice(src []*uint) []uint { - dst := make([]uint, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// UintMap converts a string map of uint values into a string -// map of uint pointers -func UintMap(src map[string]uint) map[string]*uint { - dst := make(map[string]*uint) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// UintValueMap converts a string map of uint pointers into a string -// map of uint values -func UintValueMap(src map[string]*uint) map[string]uint { - dst := make(map[string]uint) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint32 returns a pointer to of the uint32 value passed in. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint32Value returns the value of the uint32 pointer passed in or -// 0 if the pointer is nil. -func Uint32Value(v *uint32) uint32 { - if v != nil { - return *v - } - return 0 -} - -// Uint32Slice converts a slice of uint32 values into a slice of -// uint32 pointers -func Uint32Slice(src []uint32) []*uint32 { - dst := make([]*uint32, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint32ValueSlice converts a slice of uint32 pointers into a slice of -// uint32 values -func Uint32ValueSlice(src []*uint32) []uint32 { - dst := make([]uint32, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Uint32Map converts a string map of uint32 values into a string -// map of uint32 pointers -func Uint32Map(src map[string]uint32) map[string]*uint32 { - dst := make(map[string]*uint32) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Uint32ValueMap converts a string map of uint32 pointers into a string -// map of uint32 values -func Uint32ValueMap(src map[string]*uint32) map[string]uint32 { - dst := make(map[string]uint32) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Uint64 returns a pointer to of the uint64 value passed in. -func Uint64(v uint64) *uint64 { - return &v -} - -// Uint64Value returns the value of the uint64 pointer passed in or -// 0 if the pointer is nil. -func Uint64Value(v *uint64) uint64 { - if v != nil { - return *v - } - return 0 -} - -// Uint64Slice converts a slice of uint64 values into a slice of -// uint64 pointers -func Uint64Slice(src []uint64) []*uint64 { - dst := make([]*uint64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Uint64ValueSlice converts a slice of uint64 pointers into a slice of -// uint64 values -func Uint64ValueSlice(src []*uint64) []uint64 { - dst := make([]uint64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Uint64Map converts a string map of uint64 values into a string -// map of uint64 pointers -func Uint64Map(src map[string]uint64) map[string]*uint64 { - dst := make(map[string]*uint64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Uint64ValueMap converts a string map of uint64 pointers into a string -// map of uint64 values -func Uint64ValueMap(src map[string]*uint64) map[string]uint64 { - dst := make(map[string]uint64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Float32 returns a pointer to of the float32 value passed in. -func Float32(v float32) *float32 { - return &v -} - -// Float32Value returns the value of the float32 pointer passed in or -// 0 if the pointer is nil. -func Float32Value(v *float32) float32 { - if v != nil { - return *v - } - - return 0 -} - -// Float32Slice converts a slice of float32 values into a slice of -// float32 pointers -func Float32Slice(src []float32) []*float32 { - dst := make([]*float32, len(src)) - - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - - return dst -} - -// Float32ValueSlice converts a slice of float32 pointers into a slice of -// float32 values -func Float32ValueSlice(src []*float32) []float32 { - dst := make([]float32, len(src)) - - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - - return dst -} - -// Float32Map converts a string map of float32 values into a string -// map of float32 pointers -func Float32Map(src map[string]float32) map[string]*float32 { - dst := make(map[string]*float32) - - for k, val := range src { - v := val - dst[k] = &v - } - - return dst -} - -// Float32ValueMap converts a string map of float32 pointers into a string -// map of float32 values -func Float32ValueMap(src map[string]*float32) map[string]float32 { - dst := make(map[string]float32) - - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - - return dst -} - -// Float64 returns a pointer to of the float64 value passed in. -func Float64(v float64) *float64 { - return &v -} - -// Float64Value returns the value of the float64 pointer passed in or -// 0 if the pointer is nil. -func Float64Value(v *float64) float64 { - if v != nil { - return *v - } - return 0 -} - -// Float64Slice converts a slice of float64 values into a slice of -// float64 pointers -func Float64Slice(src []float64) []*float64 { - dst := make([]*float64, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// Float64ValueSlice converts a slice of float64 pointers into a slice of -// float64 values -func Float64ValueSlice(src []*float64) []float64 { - dst := make([]float64, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// Float64Map converts a string map of float64 values into a string -// map of float64 pointers -func Float64Map(src map[string]float64) map[string]*float64 { - dst := make(map[string]*float64) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// Float64ValueMap converts a string map of float64 pointers into a string -// map of float64 values -func Float64ValueMap(src map[string]*float64) map[string]float64 { - dst := make(map[string]float64) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} - -// Time returns a pointer to of the time.Time value passed in. -func Time(v time.Time) *time.Time { - return &v -} - -// TimeValue returns the value of the time.Time pointer passed in or -// time.Time{} if the pointer is nil. -func TimeValue(v *time.Time) time.Time { - if v != nil { - return *v - } - return time.Time{} -} - -// TimeSlice converts a slice of time.Time values into a slice of -// time.Time pointers -func TimeSlice(src []time.Time) []*time.Time { - dst := make([]*time.Time, len(src)) - for i := 0; i < len(src); i++ { - dst[i] = &(src[i]) - } - return dst -} - -// TimeValueSlice converts a slice of time.Time pointers into a slice of -// time.Time values -func TimeValueSlice(src []*time.Time) []time.Time { - dst := make([]time.Time, len(src)) - for i := 0; i < len(src); i++ { - if src[i] != nil { - dst[i] = *(src[i]) - } - } - return dst -} - -// TimeMap converts a string map of time.Time values into a string -// map of time.Time pointers -func TimeMap(src map[string]time.Time) map[string]*time.Time { - dst := make(map[string]*time.Time) - for k, val := range src { - v := val - dst[k] = &v - } - return dst -} - -// TimeValueMap converts a string map of time.Time pointers into a string -// map of time.Time values -func TimeValueMap(src map[string]*time.Time) map[string]time.Time { - dst := make(map[string]time.Time) - for k, val := range src { - if val != nil { - dst[k] = *val - } - } - return dst -} diff --git a/vendor/github.com/go-openapi/swag/doc.go b/vendor/github.com/go-openapi/swag/doc.go deleted file mode 100644 index 8d2c8c50..00000000 --- a/vendor/github.com/go-openapi/swag/doc.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag contains a bunch of helper functions for go-openapi and go-swagger projects. - -You may also use it standalone for your projects. - - * convert between value and pointers for builtin types - * convert from string to builtin types (wraps strconv) - * fast json concatenation - * search in path - * load from file or http - * name mangling - - -This repo has only few dependencies outside of the standard library: - - * YAML utilities depend on gopkg.in/yaml.v2 -*/ -package swag diff --git a/vendor/github.com/go-openapi/swag/json.go b/vendor/github.com/go-openapi/swag/json.go deleted file mode 100644 index 7e9902ca..00000000 --- a/vendor/github.com/go-openapi/swag/json.go +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "bytes" - "encoding/json" - "log" - "reflect" - "strings" - "sync" - - "github.com/mailru/easyjson/jlexer" - "github.com/mailru/easyjson/jwriter" -) - -// nullJSON represents a JSON object with null type -var nullJSON = []byte("null") - -// DefaultJSONNameProvider the default cache for types -var DefaultJSONNameProvider = NewNameProvider() - -const comma = byte(',') - -var closers map[byte]byte - -func init() { - closers = map[byte]byte{ - '{': '}', - '[': ']', - } -} - -type ejMarshaler interface { - MarshalEasyJSON(w *jwriter.Writer) -} - -type ejUnmarshaler interface { - UnmarshalEasyJSON(w *jlexer.Lexer) -} - -// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler -// so it takes the fastest option available. -func WriteJSON(data interface{}) ([]byte, error) { - if d, ok := data.(ejMarshaler); ok { - jw := new(jwriter.Writer) - d.MarshalEasyJSON(jw) - return jw.BuildBytes() - } - if d, ok := data.(json.Marshaler); ok { - return d.MarshalJSON() - } - return json.Marshal(data) -} - -// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler -// so it takes the fastest option available -func ReadJSON(data []byte, value interface{}) error { - trimmedData := bytes.Trim(data, "\x00") - if d, ok := value.(ejUnmarshaler); ok { - jl := &jlexer.Lexer{Data: trimmedData} - d.UnmarshalEasyJSON(jl) - return jl.Error() - } - if d, ok := value.(json.Unmarshaler); ok { - return d.UnmarshalJSON(trimmedData) - } - return json.Unmarshal(trimmedData, value) -} - -// DynamicJSONToStruct converts an untyped json structure into a struct -func DynamicJSONToStruct(data interface{}, target interface{}) error { - // TODO: convert straight to a json typed map (mergo + iterate?) - b, err := WriteJSON(data) - if err != nil { - return err - } - return ReadJSON(b, target) -} - -// ConcatJSON concatenates multiple json objects efficiently -func ConcatJSON(blobs ...[]byte) []byte { - if len(blobs) == 0 { - return nil - } - - last := len(blobs) - 1 - for blobs[last] == nil || bytes.Equal(blobs[last], nullJSON) { - // strips trailing null objects - last-- - if last < 0 { - // there was nothing but "null"s or nil... - return nil - } - } - if last == 0 { - return blobs[0] - } - - var opening, closing byte - var idx, a int - buf := bytes.NewBuffer(nil) - - for i, b := range blobs[:last+1] { - if b == nil || bytes.Equal(b, nullJSON) { - // a null object is in the list: skip it - continue - } - if len(b) > 0 && opening == 0 { // is this an array or an object? - opening, closing = b[0], closers[b[0]] - } - - if opening != '{' && opening != '[' { - continue // don't know how to concatenate non container objects - } - - if len(b) < 3 { // yep empty but also the last one, so closing this thing - if i == last && a > 0 { - if err := buf.WriteByte(closing); err != nil { - log.Println(err) - } - } - continue - } - - idx = 0 - if a > 0 { // we need to join with a comma for everything beyond the first non-empty item - if err := buf.WriteByte(comma); err != nil { - log.Println(err) - } - idx = 1 // this is not the first or the last so we want to drop the leading bracket - } - - if i != last { // not the last one, strip brackets - if _, err := buf.Write(b[idx : len(b)-1]); err != nil { - log.Println(err) - } - } else { // last one, strip only the leading bracket - if _, err := buf.Write(b[idx:]); err != nil { - log.Println(err) - } - } - a++ - } - // somehow it ended up being empty, so provide a default value - if buf.Len() == 0 { - if err := buf.WriteByte(opening); err != nil { - log.Println(err) - } - if err := buf.WriteByte(closing); err != nil { - log.Println(err) - } - } - return buf.Bytes() -} - -// ToDynamicJSON turns an object into a properly JSON typed structure -func ToDynamicJSON(data interface{}) interface{} { - // TODO: convert straight to a json typed map (mergo + iterate?) - b, err := json.Marshal(data) - if err != nil { - log.Println(err) - } - var res interface{} - if err := json.Unmarshal(b, &res); err != nil { - log.Println(err) - } - return res -} - -// FromDynamicJSON turns an object into a properly JSON typed structure -func FromDynamicJSON(data, target interface{}) error { - b, err := json.Marshal(data) - if err != nil { - log.Println(err) - } - return json.Unmarshal(b, target) -} - -// NameProvider represents an object capable of translating from go property names -// to json property names -// This type is thread-safe. -type NameProvider struct { - lock *sync.Mutex - index map[reflect.Type]nameIndex -} - -type nameIndex struct { - jsonNames map[string]string - goNames map[string]string -} - -// NewNameProvider creates a new name provider -func NewNameProvider() *NameProvider { - return &NameProvider{ - lock: &sync.Mutex{}, - index: make(map[reflect.Type]nameIndex), - } -} - -func buildnameIndex(tpe reflect.Type, idx, reverseIdx map[string]string) { - for i := 0; i < tpe.NumField(); i++ { - targetDes := tpe.Field(i) - - if targetDes.PkgPath != "" { // unexported - continue - } - - if targetDes.Anonymous { // walk embedded structures tree down first - buildnameIndex(targetDes.Type, idx, reverseIdx) - continue - } - - if tag := targetDes.Tag.Get("json"); tag != "" { - - parts := strings.Split(tag, ",") - if len(parts) == 0 { - continue - } - - nm := parts[0] - if nm == "-" { - continue - } - if nm == "" { // empty string means we want to use the Go name - nm = targetDes.Name - } - - idx[nm] = targetDes.Name - reverseIdx[targetDes.Name] = nm - } - } -} - -func newNameIndex(tpe reflect.Type) nameIndex { - var idx = make(map[string]string, tpe.NumField()) - var reverseIdx = make(map[string]string, tpe.NumField()) - - buildnameIndex(tpe, idx, reverseIdx) - return nameIndex{jsonNames: idx, goNames: reverseIdx} -} - -// GetJSONNames gets all the json property names for a type -func (n *NameProvider) GetJSONNames(subject interface{}) []string { - n.lock.Lock() - defer n.lock.Unlock() - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - - res := make([]string, 0, len(names.jsonNames)) - for k := range names.jsonNames { - res = append(res, k) - } - return res -} - -// GetJSONName gets the json name for a go property name -func (n *NameProvider) GetJSONName(subject interface{}, name string) (string, bool) { - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - return n.GetJSONNameForType(tpe, name) -} - -// GetJSONNameForType gets the json name for a go property name on a given type -func (n *NameProvider) GetJSONNameForType(tpe reflect.Type, name string) (string, bool) { - n.lock.Lock() - defer n.lock.Unlock() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - nme, ok := names.goNames[name] - return nme, ok -} - -func (n *NameProvider) makeNameIndex(tpe reflect.Type) nameIndex { - names := newNameIndex(tpe) - n.index[tpe] = names - return names -} - -// GetGoName gets the go name for a json property name -func (n *NameProvider) GetGoName(subject interface{}, name string) (string, bool) { - tpe := reflect.Indirect(reflect.ValueOf(subject)).Type() - return n.GetGoNameForType(tpe, name) -} - -// GetGoNameForType gets the go name for a given type for a json property name -func (n *NameProvider) GetGoNameForType(tpe reflect.Type, name string) (string, bool) { - n.lock.Lock() - defer n.lock.Unlock() - names, ok := n.index[tpe] - if !ok { - names = n.makeNameIndex(tpe) - } - nme, ok := names.jsonNames[name] - return nme, ok -} diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go deleted file mode 100644 index 9a604097..00000000 --- a/vendor/github.com/go-openapi/swag/loading.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "fmt" - "io/ioutil" - "log" - "net/http" - "net/url" - "path/filepath" - "runtime" - "strings" - "time" -) - -// LoadHTTPTimeout the default timeout for load requests -var LoadHTTPTimeout = 30 * time.Second - -// LoadHTTPBasicAuthUsername the username to use when load requests require basic auth -var LoadHTTPBasicAuthUsername = "" - -// LoadHTTPBasicAuthPassword the password to use when load requests require basic auth -var LoadHTTPBasicAuthPassword = "" - -// LoadHTTPCustomHeaders an optional collection of custom HTTP headers for load requests -var LoadHTTPCustomHeaders = map[string]string{} - -// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in -func LoadFromFileOrHTTP(path string) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path) -} - -// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in -// timeout arg allows for per request overriding of the request timeout -func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) { - return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(timeout))(path) -} - -// LoadStrategy returns a loader function for a given path or uri -func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(string) ([]byte, error) { - if strings.HasPrefix(path, "http") { - return remote - } - return func(pth string) ([]byte, error) { - upth, err := pathUnescape(pth) - if err != nil { - return nil, err - } - - if strings.HasPrefix(pth, `file://`) { - if runtime.GOOS == "windows" { - // support for canonical file URIs on windows. - // Zero tolerance here for dodgy URIs. - u, _ := url.Parse(upth) - if u.Host != "" { - // assume UNC name (volume share) - // file://host/share/folder\... ==> \\host\share\path\folder - // NOTE: UNC port not yet supported - upth = strings.Join([]string{`\`, u.Host, u.Path}, `\`) - } else { - // file:///c:/folder/... ==> just remove the leading slash - upth = strings.TrimPrefix(upth, `file:///`) - } - } else { - upth = strings.TrimPrefix(upth, `file://`) - } - } - - return local(filepath.FromSlash(upth)) - } -} - -func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) { - return func(path string) ([]byte, error) { - client := &http.Client{Timeout: timeout} - req, err := http.NewRequest("GET", path, nil) // nolint: noctx - if err != nil { - return nil, err - } - - if LoadHTTPBasicAuthUsername != "" && LoadHTTPBasicAuthPassword != "" { - req.SetBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword) - } - - for key, val := range LoadHTTPCustomHeaders { - req.Header.Set(key, val) - } - - resp, err := client.Do(req) - defer func() { - if resp != nil { - if e := resp.Body.Close(); e != nil { - log.Println(e) - } - } - }() - if err != nil { - return nil, err - } - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status) - } - - return ioutil.ReadAll(resp.Body) - } -} diff --git a/vendor/github.com/go-openapi/swag/name_lexem.go b/vendor/github.com/go-openapi/swag/name_lexem.go deleted file mode 100644 index aa7f6a9b..00000000 --- a/vendor/github.com/go-openapi/swag/name_lexem.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import "unicode" - -type ( - nameLexem interface { - GetUnsafeGoName() string - GetOriginal() string - IsInitialism() bool - } - - initialismNameLexem struct { - original string - matchedInitialism string - } - - casualNameLexem struct { - original string - } -) - -func newInitialismNameLexem(original, matchedInitialism string) *initialismNameLexem { - return &initialismNameLexem{ - original: original, - matchedInitialism: matchedInitialism, - } -} - -func newCasualNameLexem(original string) *casualNameLexem { - return &casualNameLexem{ - original: original, - } -} - -func (l *initialismNameLexem) GetUnsafeGoName() string { - return l.matchedInitialism -} - -func (l *casualNameLexem) GetUnsafeGoName() string { - var first rune - var rest string - for i, orig := range l.original { - if i == 0 { - first = orig - continue - } - if i > 0 { - rest = l.original[i:] - break - } - } - if len(l.original) > 1 { - return string(unicode.ToUpper(first)) + lower(rest) - } - - return l.original -} - -func (l *initialismNameLexem) GetOriginal() string { - return l.original -} - -func (l *casualNameLexem) GetOriginal() string { - return l.original -} - -func (l *initialismNameLexem) IsInitialism() bool { - return true -} - -func (l *casualNameLexem) IsInitialism() bool { - return false -} diff --git a/vendor/github.com/go-openapi/swag/net.go b/vendor/github.com/go-openapi/swag/net.go deleted file mode 100644 index 821235f8..00000000 --- a/vendor/github.com/go-openapi/swag/net.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "net" - "strconv" -) - -// SplitHostPort splits a network address into a host and a port. -// The port is -1 when there is no port to be found -func SplitHostPort(addr string) (host string, port int, err error) { - h, p, err := net.SplitHostPort(addr) - if err != nil { - return "", -1, err - } - if p == "" { - return "", -1, &net.AddrError{Err: "missing port in address", Addr: addr} - } - - pi, err := strconv.Atoi(p) - if err != nil { - return "", -1, err - } - return h, pi, nil -} diff --git a/vendor/github.com/go-openapi/swag/path.go b/vendor/github.com/go-openapi/swag/path.go deleted file mode 100644 index 941bd017..00000000 --- a/vendor/github.com/go-openapi/swag/path.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "os" - "path/filepath" - "runtime" - "strings" -) - -const ( - // GOPATHKey represents the env key for gopath - GOPATHKey = "GOPATH" -) - -// FindInSearchPath finds a package in a provided lists of paths -func FindInSearchPath(searchPath, pkg string) string { - pathsList := filepath.SplitList(searchPath) - for _, path := range pathsList { - if evaluatedPath, err := filepath.EvalSymlinks(filepath.Join(path, "src", pkg)); err == nil { - if _, err := os.Stat(evaluatedPath); err == nil { - return evaluatedPath - } - } - } - return "" -} - -// FindInGoSearchPath finds a package in the $GOPATH:$GOROOT -func FindInGoSearchPath(pkg string) string { - return FindInSearchPath(FullGoSearchPath(), pkg) -} - -// FullGoSearchPath gets the search paths for finding packages -func FullGoSearchPath() string { - allPaths := os.Getenv(GOPATHKey) - if allPaths == "" { - allPaths = filepath.Join(os.Getenv("HOME"), "go") - } - if allPaths != "" { - allPaths = strings.Join([]string{allPaths, runtime.GOROOT()}, ":") - } else { - allPaths = runtime.GOROOT() - } - return allPaths -} diff --git a/vendor/github.com/go-openapi/swag/post_go18.go b/vendor/github.com/go-openapi/swag/post_go18.go deleted file mode 100644 index c2e686d3..00000000 --- a/vendor/github.com/go-openapi/swag/post_go18.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build go1.8 - -package swag - -import "net/url" - -func pathUnescape(path string) (string, error) { - return url.PathUnescape(path) -} diff --git a/vendor/github.com/go-openapi/swag/post_go19.go b/vendor/github.com/go-openapi/swag/post_go19.go deleted file mode 100644 index eb2f2d8b..00000000 --- a/vendor/github.com/go-openapi/swag/post_go19.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build go1.9 - -package swag - -import ( - "sort" - "sync" -) - -// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms. -// Since go1.9, this may be implemented with sync.Map. -type indexOfInitialisms struct { - sortMutex *sync.Mutex - index *sync.Map -} - -func newIndexOfInitialisms() *indexOfInitialisms { - return &indexOfInitialisms{ - sortMutex: new(sync.Mutex), - index: new(sync.Map), - } -} - -func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms { - m.sortMutex.Lock() - defer m.sortMutex.Unlock() - for k, v := range initial { - m.index.Store(k, v) - } - return m -} - -func (m *indexOfInitialisms) isInitialism(key string) bool { - _, ok := m.index.Load(key) - return ok -} - -func (m *indexOfInitialisms) add(key string) *indexOfInitialisms { - m.index.Store(key, true) - return m -} - -func (m *indexOfInitialisms) sorted() (result []string) { - m.sortMutex.Lock() - defer m.sortMutex.Unlock() - m.index.Range(func(key, value interface{}) bool { - k := key.(string) - result = append(result, k) - return true - }) - sort.Sort(sort.Reverse(byInitialism(result))) - return -} diff --git a/vendor/github.com/go-openapi/swag/pre_go18.go b/vendor/github.com/go-openapi/swag/pre_go18.go deleted file mode 100644 index 6607f339..00000000 --- a/vendor/github.com/go-openapi/swag/pre_go18.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build !go1.8 - -package swag - -import "net/url" - -func pathUnescape(path string) (string, error) { - return url.QueryUnescape(path) -} diff --git a/vendor/github.com/go-openapi/swag/pre_go19.go b/vendor/github.com/go-openapi/swag/pre_go19.go deleted file mode 100644 index 4bae187d..00000000 --- a/vendor/github.com/go-openapi/swag/pre_go19.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build !go1.9 - -package swag - -import ( - "sort" - "sync" -) - -// indexOfInitialisms is a thread-safe implementation of the sorted index of initialisms. -// Before go1.9, this may be implemented with a mutex on the map. -type indexOfInitialisms struct { - getMutex *sync.Mutex - index map[string]bool -} - -func newIndexOfInitialisms() *indexOfInitialisms { - return &indexOfInitialisms{ - getMutex: new(sync.Mutex), - index: make(map[string]bool, 50), - } -} - -func (m *indexOfInitialisms) load(initial map[string]bool) *indexOfInitialisms { - m.getMutex.Lock() - defer m.getMutex.Unlock() - for k, v := range initial { - m.index[k] = v - } - return m -} - -func (m *indexOfInitialisms) isInitialism(key string) bool { - m.getMutex.Lock() - defer m.getMutex.Unlock() - _, ok := m.index[key] - return ok -} - -func (m *indexOfInitialisms) add(key string) *indexOfInitialisms { - m.getMutex.Lock() - defer m.getMutex.Unlock() - m.index[key] = true - return m -} - -func (m *indexOfInitialisms) sorted() (result []string) { - m.getMutex.Lock() - defer m.getMutex.Unlock() - for k := range m.index { - result = append(result, k) - } - sort.Sort(sort.Reverse(byInitialism(result))) - return -} diff --git a/vendor/github.com/go-openapi/swag/split.go b/vendor/github.com/go-openapi/swag/split.go deleted file mode 100644 index a1825fb7..00000000 --- a/vendor/github.com/go-openapi/swag/split.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "unicode" -) - -var nameReplaceTable = map[rune]string{ - '@': "At ", - '&': "And ", - '|': "Pipe ", - '$': "Dollar ", - '!': "Bang ", - '-': "", - '_': "", -} - -type ( - splitter struct { - postSplitInitialismCheck bool - initialisms []string - } - - splitterOption func(*splitter) *splitter -) - -// split calls the splitter; splitter provides more control and post options -func split(str string) []string { - lexems := newSplitter().split(str) - result := make([]string, 0, len(lexems)) - - for _, lexem := range lexems { - result = append(result, lexem.GetOriginal()) - } - - return result - -} - -func (s *splitter) split(str string) []nameLexem { - return s.toNameLexems(str) -} - -func newSplitter(options ...splitterOption) *splitter { - splitter := &splitter{ - postSplitInitialismCheck: false, - initialisms: initialisms, - } - - for _, option := range options { - splitter = option(splitter) - } - - return splitter -} - -// withPostSplitInitialismCheck allows to catch initialisms after main split process -func withPostSplitInitialismCheck(s *splitter) *splitter { - s.postSplitInitialismCheck = true - return s -} - -type ( - initialismMatch struct { - start, end int - body []rune - complete bool - } - initialismMatches []*initialismMatch -) - -func (s *splitter) toNameLexems(name string) []nameLexem { - nameRunes := []rune(name) - matches := s.gatherInitialismMatches(nameRunes) - return s.mapMatchesToNameLexems(nameRunes, matches) -} - -func (s *splitter) gatherInitialismMatches(nameRunes []rune) initialismMatches { - matches := make(initialismMatches, 0) - - for currentRunePosition, currentRune := range nameRunes { - newMatches := make(initialismMatches, 0, len(matches)) - - // check current initialism matches - for _, match := range matches { - if keepCompleteMatch := match.complete; keepCompleteMatch { - newMatches = append(newMatches, match) - continue - } - - // drop failed match - currentMatchRune := match.body[currentRunePosition-match.start] - if !s.initialismRuneEqual(currentMatchRune, currentRune) { - continue - } - - // try to complete ongoing match - if currentRunePosition-match.start == len(match.body)-1 { - // we are close; the next step is to check the symbol ahead - // if it is a small letter, then it is not the end of match - // but beginning of the next word - - if currentRunePosition < len(nameRunes)-1 { - nextRune := nameRunes[currentRunePosition+1] - if newWord := unicode.IsLower(nextRune); newWord { - // oh ok, it was the start of a new word - continue - } - } - - match.complete = true - match.end = currentRunePosition - } - - newMatches = append(newMatches, match) - } - - // check for new initialism matches - for _, initialism := range s.initialisms { - initialismRunes := []rune(initialism) - if s.initialismRuneEqual(initialismRunes[0], currentRune) { - newMatches = append(newMatches, &initialismMatch{ - start: currentRunePosition, - body: initialismRunes, - complete: false, - }) - } - } - - matches = newMatches - } - - return matches -} - -func (s *splitter) mapMatchesToNameLexems(nameRunes []rune, matches initialismMatches) []nameLexem { - nameLexems := make([]nameLexem, 0) - - var lastAcceptedMatch *initialismMatch - for _, match := range matches { - if !match.complete { - continue - } - - if firstMatch := lastAcceptedMatch == nil; firstMatch { - nameLexems = append(nameLexems, s.breakCasualString(nameRunes[:match.start])...) - nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) - - lastAcceptedMatch = match - - continue - } - - if overlappedMatch := match.start <= lastAcceptedMatch.end; overlappedMatch { - continue - } - - middle := nameRunes[lastAcceptedMatch.end+1 : match.start] - nameLexems = append(nameLexems, s.breakCasualString(middle)...) - nameLexems = append(nameLexems, s.breakInitialism(string(match.body))) - - lastAcceptedMatch = match - } - - // we have not found any accepted matches - if lastAcceptedMatch == nil { - return s.breakCasualString(nameRunes) - } - - if lastAcceptedMatch.end+1 != len(nameRunes) { - rest := nameRunes[lastAcceptedMatch.end+1:] - nameLexems = append(nameLexems, s.breakCasualString(rest)...) - } - - return nameLexems -} - -func (s *splitter) initialismRuneEqual(a, b rune) bool { - return a == b -} - -func (s *splitter) breakInitialism(original string) nameLexem { - return newInitialismNameLexem(original, original) -} - -func (s *splitter) breakCasualString(str []rune) []nameLexem { - segments := make([]nameLexem, 0) - currentSegment := "" - - addCasualNameLexem := func(original string) { - segments = append(segments, newCasualNameLexem(original)) - } - - addInitialismNameLexem := func(original, match string) { - segments = append(segments, newInitialismNameLexem(original, match)) - } - - addNameLexem := func(original string) { - if s.postSplitInitialismCheck { - for _, initialism := range s.initialisms { - if upper(initialism) == upper(original) { - addInitialismNameLexem(original, initialism) - return - } - } - } - - addCasualNameLexem(original) - } - - for _, rn := range string(str) { - if replace, found := nameReplaceTable[rn]; found { - if currentSegment != "" { - addNameLexem(currentSegment) - currentSegment = "" - } - - if replace != "" { - addNameLexem(replace) - } - - continue - } - - if !unicode.In(rn, unicode.L, unicode.M, unicode.N, unicode.Pc) { - if currentSegment != "" { - addNameLexem(currentSegment) - currentSegment = "" - } - - continue - } - - if unicode.IsUpper(rn) { - if currentSegment != "" { - addNameLexem(currentSegment) - } - currentSegment = "" - } - - currentSegment += string(rn) - } - - if currentSegment != "" { - addNameLexem(currentSegment) - } - - return segments -} diff --git a/vendor/github.com/go-openapi/swag/util.go b/vendor/github.com/go-openapi/swag/util.go deleted file mode 100644 index 193702f2..00000000 --- a/vendor/github.com/go-openapi/swag/util.go +++ /dev/null @@ -1,385 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "reflect" - "strings" - "unicode" -) - -// commonInitialisms are common acronyms that are kept as whole uppercased words. -var commonInitialisms *indexOfInitialisms - -// initialisms is a slice of sorted initialisms -var initialisms []string - -var isInitialism func(string) bool - -// GoNamePrefixFunc sets an optional rule to prefix go names -// which do not start with a letter. -// -// e.g. to help convert "123" into "{prefix}123" -// -// The default is to prefix with "X" -var GoNamePrefixFunc func(string) string - -func init() { - // Taken from https://github.com/golang/lint/blob/3390df4df2787994aea98de825b964ac7944b817/lint.go#L732-L769 - var configuredInitialisms = map[string]bool{ - "ACL": true, - "API": true, - "ASCII": true, - "CPU": true, - "CSS": true, - "DNS": true, - "EOF": true, - "GUID": true, - "HTML": true, - "HTTPS": true, - "HTTP": true, - "ID": true, - "IP": true, - "IPv4": true, - "IPv6": true, - "JSON": true, - "LHS": true, - "OAI": true, - "QPS": true, - "RAM": true, - "RHS": true, - "RPC": true, - "SLA": true, - "SMTP": true, - "SQL": true, - "SSH": true, - "TCP": true, - "TLS": true, - "TTL": true, - "UDP": true, - "UI": true, - "UID": true, - "UUID": true, - "URI": true, - "URL": true, - "UTF8": true, - "VM": true, - "XML": true, - "XMPP": true, - "XSRF": true, - "XSS": true, - } - - // a thread-safe index of initialisms - commonInitialisms = newIndexOfInitialisms().load(configuredInitialisms) - initialisms = commonInitialisms.sorted() - - // a test function - isInitialism = commonInitialisms.isInitialism -} - -const ( - // collectionFormatComma = "csv" - collectionFormatSpace = "ssv" - collectionFormatTab = "tsv" - collectionFormatPipe = "pipes" - collectionFormatMulti = "multi" -) - -// JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute): -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) -func JoinByFormat(data []string, format string) []string { - if len(data) == 0 { - return data - } - var sep string - switch format { - case collectionFormatSpace: - sep = " " - case collectionFormatTab: - sep = "\t" - case collectionFormatPipe: - sep = "|" - case collectionFormatMulti: - return data - default: - sep = "," - } - return []string{strings.Join(data, sep)} -} - -// SplitByFormat splits a string by a known format: -// ssv: space separated value -// tsv: tab separated value -// pipes: pipe (|) separated value -// csv: comma separated value (default) -// -func SplitByFormat(data, format string) []string { - if data == "" { - return nil - } - var sep string - switch format { - case collectionFormatSpace: - sep = " " - case collectionFormatTab: - sep = "\t" - case collectionFormatPipe: - sep = "|" - case collectionFormatMulti: - return nil - default: - sep = "," - } - var result []string - for _, s := range strings.Split(data, sep) { - if ts := strings.TrimSpace(s); ts != "" { - result = append(result, ts) - } - } - return result -} - -type byInitialism []string - -func (s byInitialism) Len() int { - return len(s) -} -func (s byInitialism) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} -func (s byInitialism) Less(i, j int) bool { - if len(s[i]) != len(s[j]) { - return len(s[i]) < len(s[j]) - } - - return strings.Compare(s[i], s[j]) > 0 -} - -// Removes leading whitespaces -func trim(str string) string { - return strings.Trim(str, " ") -} - -// Shortcut to strings.ToUpper() -func upper(str string) string { - return strings.ToUpper(trim(str)) -} - -// Shortcut to strings.ToLower() -func lower(str string) string { - return strings.ToLower(trim(str)) -} - -// Camelize an uppercased word -func Camelize(word string) (camelized string) { - for pos, ru := range []rune(word) { - if pos > 0 { - camelized += string(unicode.ToLower(ru)) - } else { - camelized += string(unicode.ToUpper(ru)) - } - } - return -} - -// ToFileName lowercases and underscores a go type name -func ToFileName(name string) string { - in := split(name) - out := make([]string, 0, len(in)) - - for _, w := range in { - out = append(out, lower(w)) - } - - return strings.Join(out, "_") -} - -// ToCommandName lowercases and underscores a go type name -func ToCommandName(name string) string { - in := split(name) - out := make([]string, 0, len(in)) - - for _, w := range in { - out = append(out, lower(w)) - } - return strings.Join(out, "-") -} - -// ToHumanNameLower represents a code name as a human series of words -func ToHumanNameLower(name string) string { - in := newSplitter(withPostSplitInitialismCheck).split(name) - out := make([]string, 0, len(in)) - - for _, w := range in { - if !w.IsInitialism() { - out = append(out, lower(w.GetOriginal())) - } else { - out = append(out, w.GetOriginal()) - } - } - - return strings.Join(out, " ") -} - -// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized -func ToHumanNameTitle(name string) string { - in := newSplitter(withPostSplitInitialismCheck).split(name) - - out := make([]string, 0, len(in)) - for _, w := range in { - original := w.GetOriginal() - if !w.IsInitialism() { - out = append(out, Camelize(original)) - } else { - out = append(out, original) - } - } - return strings.Join(out, " ") -} - -// ToJSONName camelcases a name which can be underscored or pascal cased -func ToJSONName(name string) string { - in := split(name) - out := make([]string, 0, len(in)) - - for i, w := range in { - if i == 0 { - out = append(out, lower(w)) - continue - } - out = append(out, Camelize(w)) - } - return strings.Join(out, "") -} - -// ToVarName camelcases a name which can be underscored or pascal cased -func ToVarName(name string) string { - res := ToGoName(name) - if isInitialism(res) { - return lower(res) - } - if len(res) <= 1 { - return lower(res) - } - return lower(res[:1]) + res[1:] -} - -// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes -func ToGoName(name string) string { - lexems := newSplitter(withPostSplitInitialismCheck).split(name) - - result := "" - for _, lexem := range lexems { - goName := lexem.GetUnsafeGoName() - - // to support old behavior - if lexem.IsInitialism() { - goName = upper(goName) - } - result += goName - } - - if len(result) > 0 { - // Only prefix with X when the first character isn't an ascii letter - first := []rune(result)[0] - if !unicode.IsLetter(first) || (first > unicode.MaxASCII && !unicode.IsUpper(first)) { - if GoNamePrefixFunc == nil { - return "X" + result - } - result = GoNamePrefixFunc(name) + result - } - first = []rune(result)[0] - if unicode.IsLetter(first) && !unicode.IsUpper(first) { - result = string(append([]rune{unicode.ToUpper(first)}, []rune(result)[1:]...)) - } - } - - return result -} - -// ContainsStrings searches a slice of strings for a case-sensitive match -func ContainsStrings(coll []string, item string) bool { - for _, a := range coll { - if a == item { - return true - } - } - return false -} - -// ContainsStringsCI searches a slice of strings for a case-insensitive match -func ContainsStringsCI(coll []string, item string) bool { - for _, a := range coll { - if strings.EqualFold(a, item) { - return true - } - } - return false -} - -type zeroable interface { - IsZero() bool -} - -// IsZero returns true when the value passed into the function is a zero value. -// This allows for safer checking of interface values. -func IsZero(data interface{}) bool { - // check for things that have an IsZero method instead - if vv, ok := data.(zeroable); ok { - return vv.IsZero() - } - // continue with slightly more complex reflection - v := reflect.ValueOf(data) - switch v.Kind() { - case reflect.String: - return v.Len() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - case reflect.Struct, reflect.Array: - return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface()) - case reflect.Invalid: - return true - } - return false -} - -// AddInitialisms add additional initialisms -func AddInitialisms(words ...string) { - for _, word := range words { - // commonInitialisms[upper(word)] = true - commonInitialisms.add(upper(word)) - } - // sort again - initialisms = commonInitialisms.sorted() -} - -// CommandLineOptionsGroup represents a group of user-defined command line options -type CommandLineOptionsGroup struct { - ShortDescription string - LongDescription string - Options interface{} -} diff --git a/vendor/github.com/go-openapi/swag/yaml.go b/vendor/github.com/go-openapi/swag/yaml.go deleted file mode 100644 index ec969144..00000000 --- a/vendor/github.com/go-openapi/swag/yaml.go +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2015 go-swagger maintainers -// -// 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 swag - -import ( - "encoding/json" - "fmt" - "path/filepath" - "strconv" - - "github.com/mailru/easyjson/jlexer" - "github.com/mailru/easyjson/jwriter" - yaml "gopkg.in/yaml.v2" -) - -// YAMLMatcher matches yaml -func YAMLMatcher(path string) bool { - ext := filepath.Ext(path) - return ext == ".yaml" || ext == ".yml" -} - -// YAMLToJSON converts YAML unmarshaled data into json compatible data -func YAMLToJSON(data interface{}) (json.RawMessage, error) { - jm, err := transformData(data) - if err != nil { - return nil, err - } - b, err := WriteJSON(jm) - return json.RawMessage(b), err -} - -// BytesToYAMLDoc converts a byte slice into a YAML document -func BytesToYAMLDoc(data []byte) (interface{}, error) { - var canary map[interface{}]interface{} // validate this is an object and not a different type - if err := yaml.Unmarshal(data, &canary); err != nil { - return nil, err - } - - var document yaml.MapSlice // preserve order that is present in the document - if err := yaml.Unmarshal(data, &document); err != nil { - return nil, err - } - return document, nil -} - -// JSONMapSlice represent a JSON object, with the order of keys maintained -type JSONMapSlice []JSONMapItem - -// MarshalJSON renders a JSONMapSlice as JSON -func (s JSONMapSlice) MarshalJSON() ([]byte, error) { - w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty} - s.MarshalEasyJSON(w) - return w.BuildBytes() -} - -// MarshalEasyJSON renders a JSONMapSlice as JSON, using easyJSON -func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) { - w.RawByte('{') - - ln := len(s) - last := ln - 1 - for i := 0; i < ln; i++ { - s[i].MarshalEasyJSON(w) - if i != last { // last item - w.RawByte(',') - } - } - - w.RawByte('}') -} - -// UnmarshalJSON makes a JSONMapSlice from JSON -func (s *JSONMapSlice) UnmarshalJSON(data []byte) error { - l := jlexer.Lexer{Data: data} - s.UnmarshalEasyJSON(&l) - return l.Error() -} - -// UnmarshalEasyJSON makes a JSONMapSlice from JSON, using easyJSON -func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) { - if in.IsNull() { - in.Skip() - return - } - - var result JSONMapSlice - in.Delim('{') - for !in.IsDelim('}') { - var mi JSONMapItem - mi.UnmarshalEasyJSON(in) - result = append(result, mi) - } - *s = result -} - -// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice -type JSONMapItem struct { - Key string - Value interface{} -} - -// MarshalJSON renders a JSONMapItem as JSON -func (s JSONMapItem) MarshalJSON() ([]byte, error) { - w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty} - s.MarshalEasyJSON(w) - return w.BuildBytes() -} - -// MarshalEasyJSON renders a JSONMapItem as JSON, using easyJSON -func (s JSONMapItem) MarshalEasyJSON(w *jwriter.Writer) { - w.String(s.Key) - w.RawByte(':') - w.Raw(WriteJSON(s.Value)) -} - -// UnmarshalJSON makes a JSONMapItem from JSON -func (s *JSONMapItem) UnmarshalJSON(data []byte) error { - l := jlexer.Lexer{Data: data} - s.UnmarshalEasyJSON(&l) - return l.Error() -} - -// UnmarshalEasyJSON makes a JSONMapItem from JSON, using easyJSON -func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) { - key := in.UnsafeString() - in.WantColon() - value := in.Interface() - in.WantComma() - s.Key = key - s.Value = value -} - -func transformData(input interface{}) (out interface{}, err error) { - format := func(t interface{}) (string, error) { - switch k := t.(type) { - case string: - return k, nil - case uint: - return strconv.FormatUint(uint64(k), 10), nil - case uint8: - return strconv.FormatUint(uint64(k), 10), nil - case uint16: - return strconv.FormatUint(uint64(k), 10), nil - case uint32: - return strconv.FormatUint(uint64(k), 10), nil - case uint64: - return strconv.FormatUint(k, 10), nil - case int: - return strconv.Itoa(k), nil - case int8: - return strconv.FormatInt(int64(k), 10), nil - case int16: - return strconv.FormatInt(int64(k), 10), nil - case int32: - return strconv.FormatInt(int64(k), 10), nil - case int64: - return strconv.FormatInt(k, 10), nil - default: - return "", fmt.Errorf("unexpected map key type, got: %T", k) - } - } - - switch in := input.(type) { - case yaml.MapSlice: - - o := make(JSONMapSlice, len(in)) - for i, mi := range in { - var nmi JSONMapItem - if nmi.Key, err = format(mi.Key); err != nil { - return nil, err - } - - v, ert := transformData(mi.Value) - if ert != nil { - return nil, ert - } - nmi.Value = v - o[i] = nmi - } - return o, nil - case map[interface{}]interface{}: - o := make(JSONMapSlice, 0, len(in)) - for ke, va := range in { - var nmi JSONMapItem - if nmi.Key, err = format(ke); err != nil { - return nil, err - } - - v, ert := transformData(va) - if ert != nil { - return nil, ert - } - nmi.Value = v - o = append(o, nmi) - } - return o, nil - case []interface{}: - len1 := len(in) - o := make([]interface{}, len1) - for i := 0; i < len1; i++ { - o[i], err = transformData(in[i]) - if err != nil { - return nil, err - } - } - return o, nil - } - return input, nil -} - -// YAMLDoc loads a yaml document from either http or a file and converts it to json -func YAMLDoc(path string) (json.RawMessage, error) { - yamlDoc, err := YAMLData(path) - if err != nil { - return nil, err - } - - data, err := YAMLToJSON(yamlDoc) - if err != nil { - return nil, err - } - - return data, nil -} - -// YAMLData loads a yaml document from either http or a file -func YAMLData(path string) (interface{}, error) { - data, err := LoadFromFileOrHTTP(path) - if err != nil { - return nil, err - } - - return BytesToYAMLDoc(data) -} diff --git a/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md b/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md deleted file mode 100644 index c88f9b2b..00000000 --- a/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# How to Contribute - -## Getting Started - -- Fork the repository on GitHub -- Read the [README](README.markdown) for build and test instructions -- Play with the project, submit bugs, submit patches! - -## Contribution Flow - -This is a rough outline of what a contributor's workflow looks like: - -- Create a topic branch from where you want to base your work (usually master). -- Make commits of logical units. -- Make sure your commit messages are in the proper format (see below). -- Push your changes to a topic branch in your fork of the repository. -- Make sure the tests pass, and add any new tests as appropriate. -- Submit a pull request to the original repository. - -Thanks for your contributions! - -### Format of the Commit Message - -We follow a rough convention for commit messages that is designed to answer two -questions: what changed and why. The subject line should feature the what and -the body of the commit should describe the why. - -``` -scripts: add the test-cluster command - -this uses tmux to setup a test cluster that you can easily kill and -start for debugging. - -Fixes #38 -``` - -The format can be described more formally as follows: - -``` -: - - - -