Update dependencies
This commit is contained in:
parent
4334105f95
commit
4cc82dd333
@ -669,20 +669,6 @@ func (a *api) start() error {
|
||||
}
|
||||
certmagic.Default.DefaultServerName = cfg.Host.Name[0]
|
||||
certmagic.Default.Logger = nil
|
||||
certmagic.Default.OnEvent = func(event string, data interface{}) {
|
||||
message := ""
|
||||
|
||||
switch data := data.(type) {
|
||||
case string:
|
||||
message = data
|
||||
case fmt.Stringer:
|
||||
message = data.String()
|
||||
}
|
||||
|
||||
if len(message) != 0 {
|
||||
a.log.logger.core.WithComponent("certmagic").Info().WithField("event", event).Log(message)
|
||||
}
|
||||
}
|
||||
|
||||
magic := certmagic.NewDefault()
|
||||
acme := certmagic.NewACMEIssuer(magic, certmagic.DefaultACME)
|
||||
|
||||
@ -3837,7 +3837,7 @@ const docTemplate = `{
|
||||
"description": "The total number of received KM (Key Material) control packets",
|
||||
"type": "integer"
|
||||
},
|
||||
"recv_loss__bytes": {
|
||||
"recv_loss_bytes": {
|
||||
"description": "Same as pktRcvLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size",
|
||||
"type": "integer"
|
||||
},
|
||||
@ -3945,7 +3945,7 @@ const docTemplate = `{
|
||||
"description": "The total number of retransmitted packets sent by the SRT sender",
|
||||
"type": "integer"
|
||||
},
|
||||
"sent_unique__bytes": {
|
||||
"sent_unique_bytes": {
|
||||
"description": "Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)",
|
||||
"type": "integer"
|
||||
},
|
||||
|
||||
@ -3829,7 +3829,7 @@
|
||||
"description": "The total number of received KM (Key Material) control packets",
|
||||
"type": "integer"
|
||||
},
|
||||
"recv_loss__bytes": {
|
||||
"recv_loss_bytes": {
|
||||
"description": "Same as pktRcvLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size",
|
||||
"type": "integer"
|
||||
},
|
||||
@ -3937,7 +3937,7 @@
|
||||
"description": "The total number of retransmitted packets sent by the SRT sender",
|
||||
"type": "integer"
|
||||
},
|
||||
"sent_unique__bytes": {
|
||||
"sent_unique_bytes": {
|
||||
"description": "Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)",
|
||||
"type": "integer"
|
||||
},
|
||||
|
||||
@ -979,7 +979,7 @@ definitions:
|
||||
recv_km_pkt:
|
||||
description: The total number of received KM (Key Material) control packets
|
||||
type: integer
|
||||
recv_loss__bytes:
|
||||
recv_loss_bytes:
|
||||
description: Same as pktRcvLoss, but expressed in bytes, including payload
|
||||
and all the headers (IP, TCP, SRT), bytes for the presently missing (either
|
||||
reordered or lost) packets' payloads are estimated based on the average
|
||||
@ -1088,7 +1088,7 @@ definitions:
|
||||
sent_retrans_pkt:
|
||||
description: The total number of retransmitted packets sent by the SRT sender
|
||||
type: integer
|
||||
sent_unique__bytes:
|
||||
sent_unique_bytes:
|
||||
description: Same as pktSentUnique, but expressed in bytes, including payload
|
||||
and all the headers (IP, TCP, SRT)
|
||||
type: integer
|
||||
|
||||
54
go.mod
54
go.mod
@ -3,29 +3,29 @@ module github.com/datarhei/core/v16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.17.16
|
||||
github.com/99designs/gqlgen v0.17.20
|
||||
github.com/atrox/haikunatorgo/v2 v2.0.1
|
||||
github.com/caddyserver/certmagic v0.16.2
|
||||
github.com/datarhei/gosrt v0.2.1-0.20220817080252-d44df04a3845
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/datarhei/gosrt v0.3.1
|
||||
github.com/datarhei/joy4 v0.0.0-20220914170649-23c70d207759
|
||||
github.com/go-playground/validator/v10 v10.11.0
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/invopop/jsonschema v0.4.0
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/labstack/echo/v4 v4.9.0
|
||||
github.com/labstack/echo/v4 v4.9.1
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0
|
||||
github.com/mattn/go-isatty v0.0.16
|
||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
|
||||
github.com/prometheus/client_golang v1.13.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.8
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/swaggo/echo-swagger v1.3.4
|
||||
github.com/swaggo/swag v1.8.5
|
||||
github.com/vektah/gqlparser/v2 v2.5.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.9
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/swaggo/echo-swagger v1.3.5
|
||||
github.com/swaggo/swag v1.8.7
|
||||
github.com/vektah/gqlparser/v2 v2.5.1
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
||||
golang.org/x/mod v0.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -49,20 +49,20 @@ require (
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.11 // indirect
|
||||
github.com/labstack/gommon v0.3.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.1.2 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/libdns/libdns v0.2.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mholt/acmez v1.0.4 // indirect
|
||||
github.com/miekg/dns v1.1.46 // indirect
|
||||
github.com/miekg/dns v1.1.50 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
@ -71,20 +71,20 @@ require (
|
||||
github.com/tklauser/numcpus v0.5.0 // indirect
|
||||
github.com/urfave/cli/v2 v2.8.1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
||||
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 // indirect
|
||||
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.23.0 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
golang.org/x/net v0.1.0 // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
111
go.sum
111
go.sum
@ -31,8 +31,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||
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/99designs/gqlgen v0.17.16 h1:tTIw/cQ/uvf3iXIb2I6YSkdaDkmHmH2W2eZkVe0IVLA=
|
||||
github.com/99designs/gqlgen v0.17.16/go.mod h1:dnJdUkgfh8iw8CEx2hhTdgTQO/GvVWKLcm/kult5gwI=
|
||||
github.com/99designs/gqlgen v0.17.20 h1:O7WzccIhKB1dm+7g6dhQcULINftfiLSBg2l/mwbpJMw=
|
||||
github.com/99designs/gqlgen v0.17.20/go.mod h1:Mja2HI23kWT1VRH09hvWshFgOzKswpO20o4ScpJIES4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@ -63,8 +63,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/caddyserver/certmagic v0.16.2 h1:k2n3LkkUG3aMUK/kckMuF9/0VFo+0FtMX3drPYESbmQ=
|
||||
github.com/caddyserver/certmagic v0.16.2/go.mod h1:PgLIr/dSJa+WA7t7z6Je5xuS/e5A/GFCPHRuZ1QP+MQ=
|
||||
github.com/caddyserver/certmagic v0.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
|
||||
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
@ -78,8 +78,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/datarhei/gosrt v0.2.1-0.20220817080252-d44df04a3845 h1:nlVb4EVMwdVUwH6e10WZrx4lW0n2utnlE+4ILMPyD5o=
|
||||
github.com/datarhei/gosrt v0.2.1-0.20220817080252-d44df04a3845/go.mod h1:wyoTu+DG45XRuCgEq/y+R8nhZCrJbOyQKn+SwNrNVZ8=
|
||||
github.com/datarhei/gosrt v0.3.1 h1:9A75hIvnY74IUFyeguqYXh1lsGF8Qt8fjxJS2Ewr12Q=
|
||||
github.com/datarhei/gosrt v0.3.1/go.mod h1:M2nl2WPrawncUc1FtUBK6gZX4tpZRC7FqL8NjOdBZV0=
|
||||
github.com/datarhei/joy4 v0.0.0-20220914170649-23c70d207759 h1:h8NyekuQSDvLIsZVTV172m5/RVArXkEM/cnHaUzszQU=
|
||||
github.com/datarhei/joy4 v0.0.0-20220914170649-23c70d207759/go.mod h1:Jcw/6jZDQQmPx8A7INEkXmuEF7E9jjBbSTfVSLwmiQw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -124,8 +124,8 @@ github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw=
|
||||
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
@ -174,8 +174,8 @@ github.com/google/go-cmp v0.5.1/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.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@ -220,8 +220,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid/v2 v2.0.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A=
|
||||
github.com/klauspost/cpuid/v2 v2.0.11/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/cpuid/v2 v2.1.2 h1:XhdX4fqAJUA0yj+kUwMavO0hHrSPAecYdYf1ZmxHvak=
|
||||
github.com/klauspost/cpuid/v2 v2.1.2/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
@ -233,11 +233,12 @@ 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/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
|
||||
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
|
||||
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
||||
@ -246,8 +247,8 @@ github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw
|
||||
github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y=
|
||||
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 h1:aczX6NMOtt6L4YT0fQvKkDK6LZEtdOso9sUH89V1+P0=
|
||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281/go.mod h1:lc+czkgO/8F7puNki5jk8QyujbfK1LOT7Wl0ON2hxyk=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
|
||||
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=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
@ -255,18 +256,18 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80=
|
||||
github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY=
|
||||
github.com/miekg/dns v1.1.46 h1:uzwpxRtSVxtcIZmz/4Uz6/Rn7G11DvsaslXoy5LxQio=
|
||||
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
@ -306,8 +307,9 @@ github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
@ -330,8 +332,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHSzD9Y=
|
||||
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||
github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=
|
||||
github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
@ -341,6 +343,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/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.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -348,16 +351,16 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
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.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/swaggo/echo-swagger v1.3.4 h1:8B+yVqjVm7cMy4QBLRUuRaOzrTVAqZahcrgrOSdpC5I=
|
||||
github.com/swaggo/echo-swagger v1.3.4/go.mod h1:vh8QAdbHtTXwTSaWzc1Nby7zMYJd/g0FwQyArmrFHA8=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/swaggo/echo-swagger v1.3.5 h1:kCx1wvX5AKhjI6Ykt48l3PTsfL9UD40ZROOx/tYzWyY=
|
||||
github.com/swaggo/echo-swagger v1.3.5/go.mod h1:3IMHd2Z8KftdWFEEjGmv6QpWj370LwMCOfovuh7vF34=
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowNo2MY5p6xzqtJ/wQ7LZynSvGaY=
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||
github.com/swaggo/swag v1.8.5 h1:7NgtfXsXE+jrcOwRyiftGKW7Ppydj7tZiVenuRf1fE4=
|
||||
github.com/swaggo/swag v1.8.5/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
|
||||
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
|
||||
github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
@ -368,10 +371,11 @@ github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
|
||||
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vektah/gqlparser/v2 v2.5.0 h1:GwEwy7AJsqPWrey0bHnn+3JLaHLZVT66wY/+O+Tf9SU=
|
||||
github.com/vektah/gqlparser/v2 v2.5.0/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4=
|
||||
github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@ -387,6 +391,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
@ -394,14 +399,17 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
|
||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -412,9 +420,8 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -447,8 +454,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -489,8 +497,9 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 h1:1WGATo9HAhkWMbfyuVU0tEFP88OIkUvwaHFveQPvzCQ=
|
||||
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -509,6 +518,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -562,25 +572,29 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd h1:AZeIEzg+8RCELJYq8w+ODLVxFgLMMigSwO/ffKPEd9U=
|
||||
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
|
||||
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@ -626,8 +640,9 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@ -33,9 +33,9 @@ type SRTStatistics struct {
|
||||
|
||||
ByteSent uint64 `json:"sent_bytes"` // Same as pktSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecv uint64 `json:"recv_bytes"` // Same as pktRecv, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSentUnique uint64 `json:"sent_unique__bytes"` // Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSentUnique uint64 `json:"sent_unique_bytes"` // Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvUnique uint64 `json:"recv_unique_bytes"` // Same as pktRecvUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRcvLoss uint64 `json:"recv_loss__bytes"` // Same as pktRcvLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size
|
||||
ByteRcvLoss uint64 `json:"recv_loss_bytes"` // Same as pktRcvLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size
|
||||
ByteRetrans uint64 `json:"sent_retrans_bytes"` // Same as pktRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSndDrop uint64 `json:"send_drop_bytes"` // Same as pktSndDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRcvDrop uint64 `json:"recv_drop_bytes"` // Same as pktRcvDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
@ -68,54 +68,54 @@ type SRTStatistics struct {
|
||||
func (s *SRTStatistics) Unmarshal(ss *gosrt.Statistics) {
|
||||
s.MsTimeStamp = ss.MsTimeStamp
|
||||
|
||||
s.PktSent = ss.PktSent
|
||||
s.PktRecv = ss.PktRecv
|
||||
s.PktSentUnique = ss.PktSentUnique
|
||||
s.PktRecvUnique = ss.PktRecvUnique
|
||||
s.PktSndLoss = ss.PktSndLoss
|
||||
s.PktRcvLoss = ss.PktRcvLoss
|
||||
s.PktRetrans = ss.PktRetrans
|
||||
s.PktRcvRetrans = ss.PktRcvRetrans
|
||||
s.PktSentACK = ss.PktSentACK
|
||||
s.PktRecvACK = ss.PktRecvACK
|
||||
s.PktSentNAK = ss.PktSentNAK
|
||||
s.PktRecvNAK = ss.PktRecvNAK
|
||||
s.PktSentKM = ss.PktSentKM
|
||||
s.PktRecvKM = ss.PktRecvKM
|
||||
s.UsSndDuration = ss.UsSndDuration
|
||||
s.PktSndDrop = ss.PktSndDrop
|
||||
s.PktRcvDrop = ss.PktRcvDrop
|
||||
s.PktRcvUndecrypt = ss.PktRcvUndecrypt
|
||||
s.PktSent = ss.Accumulated.PktSent
|
||||
s.PktRecv = ss.Accumulated.PktRecv
|
||||
s.PktSentUnique = ss.Accumulated.PktSentUnique
|
||||
s.PktRecvUnique = ss.Accumulated.PktRecvUnique
|
||||
s.PktSndLoss = ss.Accumulated.PktSendLoss
|
||||
s.PktRcvLoss = ss.Accumulated.PktRecvLoss
|
||||
s.PktRetrans = ss.Accumulated.PktRetrans
|
||||
s.PktRcvRetrans = ss.Accumulated.PktRecvRetrans
|
||||
s.PktSentACK = ss.Accumulated.PktSentACK
|
||||
s.PktRecvACK = ss.Accumulated.PktRecvACK
|
||||
s.PktSentNAK = ss.Accumulated.PktSentNAK
|
||||
s.PktRecvNAK = ss.Accumulated.PktRecvNAK
|
||||
s.PktSentKM = ss.Accumulated.PktSentKM
|
||||
s.PktRecvKM = ss.Accumulated.PktRecvKM
|
||||
s.UsSndDuration = ss.Accumulated.UsSndDuration
|
||||
s.PktSndDrop = ss.Accumulated.PktSendDrop
|
||||
s.PktRcvDrop = ss.Accumulated.PktRecvDrop
|
||||
s.PktRcvUndecrypt = ss.Accumulated.PktRecvUndecrypt
|
||||
|
||||
s.ByteSent = ss.ByteSent
|
||||
s.ByteRecv = ss.ByteRecv
|
||||
s.ByteSentUnique = ss.ByteSentUnique
|
||||
s.ByteRecvUnique = ss.ByteRecvUnique
|
||||
s.ByteRcvLoss = ss.ByteRcvLoss
|
||||
s.ByteRetrans = ss.ByteRetrans
|
||||
s.ByteSndDrop = ss.ByteSndDrop
|
||||
s.ByteRcvDrop = ss.ByteRcvDrop
|
||||
s.ByteRcvUndecrypt = ss.ByteRcvUndecrypt
|
||||
s.ByteSent = ss.Accumulated.ByteSent
|
||||
s.ByteRecv = ss.Accumulated.ByteRecv
|
||||
s.ByteSentUnique = ss.Accumulated.ByteSentUnique
|
||||
s.ByteRecvUnique = ss.Accumulated.ByteRecvUnique
|
||||
s.ByteRcvLoss = ss.Accumulated.ByteRecvLoss
|
||||
s.ByteRetrans = ss.Accumulated.ByteRetrans
|
||||
s.ByteSndDrop = ss.Accumulated.ByteSendDrop
|
||||
s.ByteRcvDrop = ss.Accumulated.ByteRecvDrop
|
||||
s.ByteRcvUndecrypt = ss.Accumulated.ByteRecvUndecrypt
|
||||
|
||||
s.UsPktSndPeriod = ss.UsPktSndPeriod
|
||||
s.PktFlowWindow = ss.PktFlowWindow
|
||||
s.PktFlightSize = ss.PktFlightSize
|
||||
s.MsRTT = ss.MsRTT
|
||||
s.MbpsBandwidth = ss.MbpsBandwidth
|
||||
s.ByteAvailSndBuf = ss.ByteAvailSndBuf
|
||||
s.ByteAvailRcvBuf = ss.ByteAvailRcvBuf
|
||||
s.MbpsMaxBW = ss.MbpsMaxBW
|
||||
s.ByteMSS = ss.ByteMSS
|
||||
s.PktSndBuf = ss.PktSndBuf
|
||||
s.ByteSndBuf = ss.ByteSndBuf
|
||||
s.MsSndBuf = ss.MsSndBuf
|
||||
s.MsSndTsbPdDelay = ss.MsSndTsbPdDelay
|
||||
s.PktRcvBuf = ss.PktRcvBuf
|
||||
s.ByteRcvBuf = ss.ByteRcvBuf
|
||||
s.MsRcvBuf = ss.MsRcvBuf
|
||||
s.MsRcvTsbPdDelay = ss.MsRcvTsbPdDelay
|
||||
s.PktReorderTolerance = ss.PktReorderTolerance
|
||||
s.PktRcvAvgBelatedTime = ss.PktRcvAvgBelatedTime
|
||||
s.UsPktSndPeriod = ss.Instantaneous.UsPktSendPeriod
|
||||
s.PktFlowWindow = ss.Instantaneous.PktFlowWindow
|
||||
s.PktFlightSize = ss.Instantaneous.PktFlightSize
|
||||
s.MsRTT = ss.Instantaneous.MsRTT
|
||||
s.MbpsBandwidth = ss.Instantaneous.MbpsLinkCapacity
|
||||
s.ByteAvailSndBuf = ss.Instantaneous.ByteAvailSendBuf
|
||||
s.ByteAvailRcvBuf = ss.Instantaneous.ByteAvailRecvBuf
|
||||
s.MbpsMaxBW = ss.Instantaneous.MbpsMaxBW
|
||||
s.ByteMSS = ss.Instantaneous.ByteMSS
|
||||
s.PktSndBuf = ss.Instantaneous.PktSendBuf
|
||||
s.ByteSndBuf = ss.Instantaneous.ByteSendBuf
|
||||
s.MsSndBuf = ss.Instantaneous.MsSendBuf
|
||||
s.MsSndTsbPdDelay = ss.Instantaneous.MsSendTsbPdDelay
|
||||
s.PktRcvBuf = ss.Instantaneous.PktRecvBuf
|
||||
s.ByteRcvBuf = ss.Instantaneous.ByteRecvBuf
|
||||
s.MsRcvBuf = ss.Instantaneous.MsRecvBuf
|
||||
s.MsRcvTsbPdDelay = ss.Instantaneous.MsRecvTsbPdDelay
|
||||
s.PktReorderTolerance = ss.Instantaneous.PktReorderTolerance
|
||||
s.PktRcvAvgBelatedTime = ss.Instantaneous.PktRecvAvgBelatedTime
|
||||
}
|
||||
|
||||
type SRTLog struct {
|
||||
|
||||
18
srt/srt.go
18
srt/srt.go
@ -53,15 +53,17 @@ func (c *client) ticker(ctx context.Context) {
|
||||
ticker := time.NewTicker(1 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
stats := &srt.Statistics{}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
stats := c.conn.Stats()
|
||||
c.conn.Stats(stats)
|
||||
|
||||
rxbytes := stats.ByteRecv
|
||||
txbytes := stats.ByteSent
|
||||
rxbytes := stats.Accumulated.ByteRecv
|
||||
txbytes := stats.Accumulated.ByteSent
|
||||
|
||||
c.collector.Ingress(c.id, int64(rxbytes-c.rxbytes))
|
||||
c.collector.Egress(c.id, int64(txbytes-c.txbytes))
|
||||
@ -285,8 +287,11 @@ func (s *server) Channels() Channels {
|
||||
socketId := ch.publisher.conn.SocketId()
|
||||
st.Publisher[id] = socketId
|
||||
|
||||
stats := &srt.Statistics{}
|
||||
ch.publisher.conn.Stats(stats)
|
||||
|
||||
st.Connections[socketId] = Connection{
|
||||
Stats: ch.publisher.conn.Stats(),
|
||||
Stats: *stats,
|
||||
Log: map[string][]Log{},
|
||||
}
|
||||
|
||||
@ -294,8 +299,11 @@ func (s *server) Channels() Channels {
|
||||
socketId := c.conn.SocketId()
|
||||
st.Subscriber[id] = append(st.Subscriber[id], socketId)
|
||||
|
||||
stats := &srt.Statistics{}
|
||||
c.conn.Stats(stats)
|
||||
|
||||
st.Connections[socketId] = Connection{
|
||||
Stats: c.conn.Stats(),
|
||||
Stats: *stats,
|
||||
Log: map[string][]Log{},
|
||||
}
|
||||
}
|
||||
|
||||
130
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
130
vendor/github.com/99designs/gqlgen/CHANGELOG.md
generated
vendored
@ -5,10 +5,138 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.14...HEAD)
|
||||
## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.19...HEAD)
|
||||
|
||||
<!-- end of if -->
|
||||
<!-- end of CommitGroups -->
|
||||
<a name="v0.17.19"></a>
|
||||
## [v0.17.19](https://github.com/99designs/gqlgen/compare/v0.17.18...v0.17.19) - 2022-09-15
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/588c6ac137b8ed7aea1bc7c009ea23cb9dec5caa"><tt>588c6ac1</tt></a> release v0.17.19
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/c671317056298db8073498c8db02120b6f737032"><tt>c6713170</tt></a> v0.17.18 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.18"></a>
|
||||
## [v0.17.18](https://github.com/99designs/gqlgen/compare/v0.17.17...v0.17.18) - 2022-09-15
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/1d41c808a93446fca8ff867e957ef552e56f6ae3"><tt>1d41c808</tt></a> release v0.17.18
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/4dbe2e475f15ce77a498c841ea6c9149ef5ceaba"><tt>4dbe2e47</tt></a> update graphiql to 2.0.7 (<a href="https://github.com/99designs/gqlgen/pull/2375">#2375</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/b7cc094a49e3d348cfc457aa76f1640c86cdcae9"><tt>b7cc094a</tt></a> testfix: make apollo federated tracer test more consistent (<a href="https://github.com/99designs/gqlgen/pull/2374">#2374</a>)</summary>
|
||||
|
||||
* Update tracing_test.go
|
||||
|
||||
* add missing imports
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/d096fb9b08531b0dc389a786b6f44add045ea75e"><tt>d096fb9b</tt></a> Update directives (<a href="https://github.com/99designs/gqlgen/pull/2371">#2371</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/1acfea2fbdf3564df16f8023f4e736e90a05b909"><tt>1acfea2f</tt></a> Add v0.17.17 changelog
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/c273adc8ad45e15940bbb6fe211603670d9f3220"><tt>c273adc8</tt></a> v0.17.17 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.17"></a>
|
||||
## [v0.17.17](https://github.com/99designs/gqlgen/compare/v0.17.16...v0.17.17) - 2022-09-13
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/d50bc5aca10c5a5dd6a1680b2288c35a61327ade"><tt>d50bc5ac</tt></a> release v0.17.17
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/462025b400e9b792a5afbe320cde4cc952f6b547"><tt>462025b4</tt></a> nil check error before type assertion follow-up from <a href="https://github.com/99designs/gqlgen/pull/2341">#2341</a> (<a href="https://github.com/99designs/gqlgen/pull/2368">#2368</a>)</summary>
|
||||
|
||||
* Improve errcode.Set safety
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/59493aff86020d170e58900654d334f5ebc2ceee"><tt>59493aff</tt></a> fix: apollo federation tracer was race prone (<a href="https://github.com/99designs/gqlgen/pull/2366">#2366</a>)</summary>
|
||||
|
||||
The tracer was using a global state across different goroutines
|
||||
Added req headers to operation context to allow it to be fetched in InterceptOperation
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/fc0185567f2dfc37b38f11283efb9cc1db69e96d"><tt>fc018556</tt></a> Update gqlparser to v2.5.1 (<a href="https://github.com/99designs/gqlgen/pull/2363">#2363</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/56574a146bd16a13c9055128ec3c80e96a7c4b29"><tt>56574a14</tt></a> feat: make Playground HTML content compatible with UTF-8 charset (<a href="https://github.com/99designs/gqlgen/pull/2355">#2355</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/182b039d34cb730f432c486ebe763f246937dea4"><tt>182b039d</tt></a> Add `subscriptions.md` recipe to docs (<a href="https://github.com/99designs/gqlgen/pull/2346">#2346</a>)</summary>
|
||||
|
||||
* Add `subscriptions.md` recipe to docs
|
||||
|
||||
* Fix wrong request type
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/b66fff16de0b16edc317398a5574fcff2cb39e66"><tt>b66fff16</tt></a> Add omit_getters config option (<a href="https://github.com/99designs/gqlgen/pull/2348">#2348</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/2ba8040f20e32d06dc6d5bfacaadc5619a6e66ee"><tt>2ba8040f</tt></a> Update changelog for v0.17.16
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/8bef8c8061222071e6c814e45bbc33fcabcb3980"><tt>8bef8c80</tt></a> v0.17.16 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.16"></a>
|
||||
## [v0.17.16](https://github.com/99designs/gqlgen/compare/v0.17.15...v0.17.16) - 2022-08-26
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/9593ceadd6e07c6fd0f0b0e0c55b9f1bf8ade762"><tt>9593cead</tt></a> release v0.17.16
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/2390af2db920dc632fe47bc778a24c30495b9efd"><tt>2390af2d</tt></a> Update gqlparser to v2.5.0 (<a href="https://github.com/99designs/gqlgen/pull/2341">#2341</a>)
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/2a87fe0645fd271e4e71d2b7bde34ecf31bf844c"><tt>2a87fe06</tt></a> feat: update Graphiql to version 2 (<a href="https://github.com/99designs/gqlgen/pull/2340">#2340</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/32e2ccd30e82fc566ca022a65dcc4a67c4b6125a"><tt>32e2ccd3</tt></a> Update yaml to v3 (<a href="https://github.com/99designs/gqlgen/pull/2339">#2339</a>)</summary>
|
||||
|
||||
* update yaml to v3
|
||||
|
||||
* add missing go entry for yaml on _example
|
||||
|
||||
* add missing sum file
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/7949117a524be7f8882a61e2d4ade1bedf105107"><tt>7949117a</tt></a> v0.17.15 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.15"></a>
|
||||
## [v0.17.15](https://github.com/99designs/gqlgen/compare/v0.17.14...v0.17.15) - 2022-08-23
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/23cc749256b4e2edc4b11ce9e84c643a7bb3194f"><tt>23cc7492</tt></a> release v0.17.15
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/577a570cdb6b1b9185f24940690a14cdced37a36"><tt>577a570c</tt></a> Markdown formatting fixes (<a href="https://github.com/99designs/gqlgen/pull/2335">#2335</a>)
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/2b584011fc64a55cbda67f46637a280bf94d9cc1"><tt>2b584011</tt></a> Fix Interface Slice Getter Generation (<a href="https://github.com/99designs/gqlgen/pull/2332">#2332</a>)</summary>
|
||||
|
||||
* Make modelgen test fail if generated doesn't build
|
||||
Added returning list of interface to modelgen test schema
|
||||
|
||||
* Implement slice copying when returning interface slices
|
||||
|
||||
* Re-generate to satisfy the linter
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
<dl><dd><details><summary><a href="https://github.com/99designs/gqlgen/commit/aee57b4c521e527ebc0538b8edfbe610973abf21"><tt>aee57b4c</tt></a> Correct boolean logic (<a href="https://github.com/99designs/gqlgen/pull/2330">#2330</a>)</summary>
|
||||
|
||||
Correcting boolean logic issue
|
||||
|
||||
</details></dd></dl>
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/da0610e11accf3afd34903f03bfc0abd045d07ed"><tt>da0610e1</tt></a> Update changelog for v0.17.14
|
||||
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/ddcb524e3321d849505f6937307ef3dcbd3acace"><tt>ddcb524e</tt></a> v0.17.14 postrelease bump
|
||||
|
||||
<!-- end of Commits -->
|
||||
<!-- end of Else -->
|
||||
|
||||
<!-- end of If NoteGroups -->
|
||||
<a name="v0.17.14"></a>
|
||||
## [v0.17.14](https://github.com/99designs/gqlgen/compare/v0.17.13...v0.17.14) - 2022-08-18
|
||||
- <a href="https://github.com/99designs/gqlgen/commit/581bf6eb063a0d6a3cec3b6bc7a16ca10e310a97"><tt>581bf6eb</tt></a> release v0.17.14
|
||||
|
||||
10
vendor/github.com/99designs/gqlgen/README.md
generated
vendored
10
vendor/github.com/99designs/gqlgen/README.md
generated
vendored
@ -142,6 +142,16 @@ first model in this list is used as the default type and it will always be used
|
||||
|
||||
There isn't any way around this, gqlgen has no way to know what you want in a given context.
|
||||
|
||||
### Why do my interfaces have getters? Can I disable these?
|
||||
These were added in v0.17.14 to allow accessing common interface fields without casting to a concrete type.
|
||||
However, certain fields, like Relay-style Connections, cannot be implemented with simple getters.
|
||||
|
||||
If you'd prefer to not have getters generated in your interfaces, you can add the following in your `gqlgen.yml`:
|
||||
```yaml
|
||||
# gqlgen.yml
|
||||
omit_getters: true
|
||||
```
|
||||
|
||||
## Other Resources
|
||||
|
||||
- [Christopher Biscardi @ Gophercon UK 2018](https://youtu.be/FdURVezcdcw)
|
||||
|
||||
1
vendor/github.com/99designs/gqlgen/codegen/config/config.go
generated
vendored
1
vendor/github.com/99designs/gqlgen/codegen/config/config.go
generated
vendored
@ -26,6 +26,7 @@ type Config struct {
|
||||
StructTag string `yaml:"struct_tag,omitempty"`
|
||||
Directives map[string]DirectiveConfig `yaml:"directives,omitempty"`
|
||||
OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"`
|
||||
OmitGetters bool `yaml:"omit_getters,omitempty"`
|
||||
StructFieldsAlwaysPointers bool `yaml:"struct_fields_always_pointers,omitempty"`
|
||||
ResolversAlwaysReturnPointers bool `yaml:"resolvers_always_return_pointers,omitempty"`
|
||||
SkipValidation bool `yaml:"skip_validation,omitempty"`
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
@ -3,6 +3,7 @@ package graphql
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
)
|
||||
@ -15,6 +16,7 @@ type OperationContext struct {
|
||||
Variables map[string]interface{}
|
||||
OperationName string
|
||||
Doc *ast.QueryDocument
|
||||
Headers http.Header
|
||||
|
||||
Operation *ast.OperationDefinition
|
||||
DisableIntrospection bool
|
||||
|
||||
12
vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go
generated
vendored
12
vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go
generated
vendored
@ -23,14 +23,22 @@ var codeType = map[string]ErrorKind{
|
||||
ParseFailed: KindProtocol,
|
||||
}
|
||||
|
||||
// RegisterErrorType should be called by extensions that want to customize the http status codes for errors they return
|
||||
// RegisterErrorType should be called by extensions that want to customize the http status codes for
|
||||
// errors they return
|
||||
func RegisterErrorType(code string, kind ErrorKind) {
|
||||
codeType[code] = kind
|
||||
}
|
||||
|
||||
// Set the error code on a given graphql error extension
|
||||
func Set(err error, value string) {
|
||||
gqlErr, _ := err.(*gqlerror.Error)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
gqlErr, ok := err.(*gqlerror.Error)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if gqlErr.Extensions == nil {
|
||||
gqlErr.Extensions = map[string]interface{}{}
|
||||
}
|
||||
|
||||
5
vendor/github.com/99designs/gqlgen/graphql/executable_schema.go
generated
vendored
5
vendor/github.com/99designs/gqlgen/graphql/executable_schema.go
generated
vendored
@ -118,6 +118,11 @@ func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, o
|
||||
return &(*c)[i]
|
||||
}
|
||||
}
|
||||
for _, ifc := range cf.ObjectDefinition.Interfaces {
|
||||
if ifc == objectDefinition.Name {
|
||||
return &(*c)[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
41
vendor/github.com/99designs/gqlgen/graphql/executor/executor.go
generated
vendored
41
vendor/github.com/99designs/gqlgen/graphql/executor/executor.go
generated
vendored
@ -37,7 +37,10 @@ func New(es graphql.ExecutableSchema) *Executor {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.RawParams) (*graphql.OperationContext, gqlerror.List) {
|
||||
func (e *Executor) CreateOperationContext(
|
||||
ctx context.Context,
|
||||
params *graphql.RawParams,
|
||||
) (*graphql.OperationContext, gqlerror.List) {
|
||||
rc := &graphql.OperationContext{
|
||||
DisableIntrospection: true,
|
||||
RecoverFunc: e.recoverFunc,
|
||||
@ -58,6 +61,7 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||
|
||||
rc.RawQuery = params.Query
|
||||
rc.OperationName = params.OperationName
|
||||
rc.Headers = params.Headers
|
||||
|
||||
var listErr gqlerror.List
|
||||
rc.Doc, listErr = e.parseQuery(ctx, &rc.Stats, params.Query)
|
||||
@ -74,10 +78,13 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||
|
||||
var err error
|
||||
rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables)
|
||||
gqlErr, _ := err.(*gqlerror.Error)
|
||||
if gqlErr != nil {
|
||||
errcode.Set(gqlErr, errcode.ValidationFailed)
|
||||
return rc, gqlerror.List{gqlErr}
|
||||
|
||||
if err != nil {
|
||||
gqlErr, ok := err.(*gqlerror.Error)
|
||||
if ok {
|
||||
errcode.Set(gqlErr, errcode.ValidationFailed)
|
||||
return rc, gqlerror.List{gqlErr}
|
||||
}
|
||||
}
|
||||
rc.Stats.Validation.End = graphql.Now()
|
||||
|
||||
@ -90,7 +97,10 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
func (e *Executor) DispatchOperation(ctx context.Context, rc *graphql.OperationContext) (graphql.ResponseHandler, context.Context) {
|
||||
func (e *Executor) DispatchOperation(
|
||||
ctx context.Context,
|
||||
rc *graphql.OperationContext,
|
||||
) (graphql.ResponseHandler, context.Context) {
|
||||
ctx = graphql.WithOperationContext(ctx, rc)
|
||||
|
||||
var innerCtx context.Context
|
||||
@ -160,9 +170,14 @@ func (e *Executor) SetRecoverFunc(f graphql.RecoverFunc) {
|
||||
|
||||
// parseQuery decodes the incoming query and validates it, pulling from cache if present.
|
||||
//
|
||||
// NOTE: This should NOT look at variables, they will change per request. It should only parse and validate
|
||||
// NOTE: This should NOT look at variables, they will change per request. It should only parse and
|
||||
// validate
|
||||
// the raw query string.
|
||||
func (e *Executor) parseQuery(ctx context.Context, stats *graphql.Stats, query string) (*ast.QueryDocument, gqlerror.List) {
|
||||
func (e *Executor) parseQuery(
|
||||
ctx context.Context,
|
||||
stats *graphql.Stats,
|
||||
query string,
|
||||
) (*ast.QueryDocument, gqlerror.List) {
|
||||
stats.Parsing.Start = graphql.Now()
|
||||
|
||||
if doc, ok := e.queryCache.Get(ctx, query); ok {
|
||||
@ -174,10 +189,12 @@ func (e *Executor) parseQuery(ctx context.Context, stats *graphql.Stats, query s
|
||||
}
|
||||
|
||||
doc, err := parser.ParseQuery(&ast.Source{Input: query})
|
||||
gqlErr, _ := err.(*gqlerror.Error)
|
||||
if gqlErr != nil {
|
||||
errcode.Set(gqlErr, errcode.ParseFailed)
|
||||
return nil, gqlerror.List{gqlErr}
|
||||
if err != nil {
|
||||
gqlErr, ok := err.(*gqlerror.Error)
|
||||
if ok {
|
||||
errcode.Set(gqlErr, errcode.ParseFailed)
|
||||
return nil, gqlerror.List{gqlErr}
|
||||
}
|
||||
}
|
||||
stats.Parsing.End = graphql.Now()
|
||||
|
||||
|
||||
16
vendor/github.com/99designs/gqlgen/graphql/handler.go
generated
vendored
16
vendor/github.com/99designs/gqlgen/graphql/handler.go
generated
vendored
@ -42,14 +42,14 @@ type (
|
||||
// Its important to understand the lifecycle of a graphql request and the terminology we use in gqlgen
|
||||
// before working with these
|
||||
//
|
||||
// +--- REQUEST POST /graphql --------------------------------------------+
|
||||
// | +- OPERATION query OpName { viewer { name } } -----------------------+ |
|
||||
// | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | |
|
||||
// | +- OPERATION subscription OpName2 { chat { message } } --------------+ |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "hello" } } } | |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "byee" } } } | |
|
||||
// | +--------------------------------------------------------------------+ |
|
||||
// +------------------------------------------------------------------------+
|
||||
// +--- REQUEST POST /graphql --------------------------------------------+
|
||||
// | +- OPERATION query OpName { viewer { name } } -----------------------+ |
|
||||
// | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | |
|
||||
// | +- OPERATION subscription OpName2 { chat { message } } --------------+ |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "hello" } } } | |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "byee" } } } | |
|
||||
// | +--------------------------------------------------------------------+ |
|
||||
// +------------------------------------------------------------------------+
|
||||
HandlerExtension interface {
|
||||
// ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging.
|
||||
ExtensionName() string
|
||||
|
||||
9
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
9
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
||||
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{.title}}</title>
|
||||
<style>
|
||||
body {
|
||||
@ -75,15 +76,15 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
// Handler responsible for setting up the playground
|
||||
func Handler(title string, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
|
||||
err := page.Execute(w, map[string]interface{}{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||
"version": "2.0.1",
|
||||
"cssSRI": "sha256-hYUgpHapGug0ucdB5kG0zSipubcQOJcGjclIZke2rl8=",
|
||||
"jsSRI": "sha256-jMXGO5+Y4OhcHPSR34jpzpzlz4OZTlxcvaDXSWmUMRo=",
|
||||
"version": "2.0.7",
|
||||
"cssSRI": "sha256-gQryfbGYeYFxnJYnfPStPYFt0+uv8RP8Dm++eh00G9c=",
|
||||
"jsSRI": "sha256-qQ6pw7LwTLC+GfzN+cJsYXfVWRKH9O5o7+5H96gTJhQ=",
|
||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||||
})
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
@ -1,3 +1,3 @@
|
||||
package graphql
|
||||
|
||||
const Version = "v0.17.16"
|
||||
const Version = "v0.17.20"
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
generated
vendored
4
vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
generated
vendored
@ -102,10 +102,10 @@ func (f *federation) InjectSourceEarly() *ast.Source {
|
||||
`
|
||||
} else if f.Version == 2 {
|
||||
input += `
|
||||
directive @key(fields: _FieldSet!, resolvable: Boolean) repeatable on OBJECT | INTERFACE
|
||||
directive @key(fields: _FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
|
||||
directive @link(import: [String!], url: String!) repeatable on SCHEMA
|
||||
directive @shareable on OBJECT | FIELD_DEFINITION
|
||||
directive @tag repeatable on OBJECT | FIELD_DEFINITION | INTERFACE | UNION
|
||||
directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
|
||||
directive @override(from: String!) on FIELD_DEFINITION
|
||||
directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
|
||||
`
|
||||
|
||||
10
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
10
vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
generated
vendored
@ -103,9 +103,13 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
|
||||
}
|
||||
switch schemaType.Kind {
|
||||
case ast.Interface, ast.Union:
|
||||
fields, err := m.generateFields(cfg, schemaType)
|
||||
if err != nil {
|
||||
return err
|
||||
var fields []*Field
|
||||
var err error
|
||||
if !cfg.OmitGetters {
|
||||
fields, err = m.generateFields(cfg, schemaType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
it := &Interface{
|
||||
|
||||
36
vendor/github.com/caddyserver/certmagic/README.md
generated
vendored
36
vendor/github.com/caddyserver/certmagic/README.md
generated
vendored
@ -458,6 +458,42 @@ Most applications will not need to interact with certificate caches directly. Us
|
||||
|
||||
Again, if you're needing to do this, you've probably over-complicated your application design.
|
||||
|
||||
## Events
|
||||
|
||||
(Events are new and still experimental, so they may change.)
|
||||
|
||||
CertMagic emits events when possible things of interest happen. Set the [`OnEvent` field of your `Config`](https://pkg.go.dev/github.com/caddyserver/certmagic#Config.OnEvent) to subscribe to events; ignore the ones you aren't interested in. Here are the events currently emitted along with their metadata you can use:
|
||||
|
||||
- **`cached_unmanaged_cert`** An unmanaged certificate was cached
|
||||
- `sans`: The subject names on the certificate
|
||||
- **`cert_obtaining`** A certificate is about to be obtained
|
||||
- `renewal`: Whether this is a renewal
|
||||
- `identifier`: The name on the certificate
|
||||
- `forced`: Whether renewal is being forced (if renewal)
|
||||
- `remaining`: Time left on the certificate (if renewal)
|
||||
- `issuer`: The previous or current issuer
|
||||
- **`cert_obtained`** A certificate was successfully obtained
|
||||
- `renewal`: Whether this is a renewal
|
||||
- `identifier`: The name on the certificate
|
||||
- `remaining`: Time left on the certificate (if renewal)
|
||||
- `issuer`: The previous or current issuer
|
||||
- `storage_key`: The path to the cert resources within storage
|
||||
- **`cert_failed`** An attempt to obtain a certificate failed
|
||||
- `renewal`: Whether this is a renewal
|
||||
- `identifier`: The name on the certificate
|
||||
- `remaining`: Time left on the certificate (if renewal)
|
||||
- `issuer`: The previous or current issuer
|
||||
- `storage_key`: The path to the cert resources within storage
|
||||
- `error`: The (final) error message
|
||||
- **`tls_get_certificate`** The GetCertificate phase of a TLS handshake is under way
|
||||
- `client_hello`: The tls.ClientHelloInfo struct
|
||||
- **`cert_ocsp_revoked`** A certificate's OCSP indicates it has been revoked
|
||||
- `subjects`: The subject names on the certificate
|
||||
- `certificate`: The Certificate struct
|
||||
- `reason`: The OCSP revocation reason
|
||||
- `revoked_at`: When the certificate was revoked
|
||||
|
||||
`OnEvent` can return an error. Some events may be aborted by returning an error. For example, returning an error from `cert_obtained` can cancel obtaining the certificate. Only return an error from `OnEvent` if you want to abort program flow.
|
||||
|
||||
## FAQ
|
||||
|
||||
|
||||
28
vendor/github.com/caddyserver/certmagic/acmeclient.go
generated
vendored
28
vendor/github.com/caddyserver/certmagic/acmeclient.go
generated
vendored
@ -175,9 +175,7 @@ func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, error) {
|
||||
},
|
||||
ChallengeSolvers: make(map[string]acmez.Solver),
|
||||
}
|
||||
if iss.Logger != nil {
|
||||
client.Logger = iss.Logger.Named("acme_client")
|
||||
}
|
||||
client.Logger = iss.Logger.Named("acme_client")
|
||||
|
||||
// configure challenges (most of the time, DNS challenge is
|
||||
// exclusive of other ones because it is usually only used
|
||||
@ -260,24 +258,20 @@ func (c *acmeClient) throttle(ctx context.Context, names []string) error {
|
||||
// TODO: stop rate limiter when it is garbage-collected...
|
||||
}
|
||||
rateLimitersMu.Unlock()
|
||||
if c.iss.Logger != nil {
|
||||
c.iss.Logger.Info("waiting on internal rate limiter",
|
||||
zap.Strings("identifiers", names),
|
||||
zap.String("ca", c.acmeClient.Directory),
|
||||
zap.String("account", email),
|
||||
)
|
||||
}
|
||||
c.iss.Logger.Info("waiting on internal rate limiter",
|
||||
zap.Strings("identifiers", names),
|
||||
zap.String("ca", c.acmeClient.Directory),
|
||||
zap.String("account", email),
|
||||
)
|
||||
err := rl.Wait(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if c.iss.Logger != nil {
|
||||
c.iss.Logger.Info("done waiting on internal rate limiter",
|
||||
zap.Strings("identifiers", names),
|
||||
zap.String("ca", c.acmeClient.Directory),
|
||||
zap.String("account", email),
|
||||
)
|
||||
}
|
||||
c.iss.Logger.Info("done waiting on internal rate limiter",
|
||||
zap.Strings("identifiers", names),
|
||||
zap.String("ca", c.acmeClient.Directory),
|
||||
zap.String("account", email),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
40
vendor/github.com/caddyserver/certmagic/acmeissuer.go
generated
vendored
40
vendor/github.com/caddyserver/certmagic/acmeissuer.go
generated
vendored
@ -110,7 +110,9 @@ type ACMEIssuer struct {
|
||||
// certificate chains
|
||||
PreferredChains ChainPreference
|
||||
|
||||
// Set a logger to enable logging
|
||||
// Set a logger to configure logging; a default
|
||||
// logger must always be set; if no logging is
|
||||
// desired, set this to zap.NewNop().
|
||||
Logger *zap.Logger
|
||||
|
||||
config *Config
|
||||
@ -197,6 +199,11 @@ func NewACMEIssuer(cfg *Config, template ACMEIssuer) *ACMEIssuer {
|
||||
template.Logger = DefaultACME.Logger
|
||||
}
|
||||
|
||||
// absolutely do not allow a nil logger; that would panic
|
||||
if template.Logger == nil {
|
||||
template.Logger = defaultLogger
|
||||
}
|
||||
|
||||
template.config = cfg
|
||||
template.mu = new(sync.Mutex)
|
||||
|
||||
@ -398,7 +405,7 @@ func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.CertificateRequest,
|
||||
// processing. If there are no matches, the first chain is returned.
|
||||
func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.Certificate {
|
||||
if len(certChains) == 1 {
|
||||
if am.Logger != nil && (len(am.PreferredChains.AnyCommonName) > 0 || len(am.PreferredChains.RootCommonName) > 0) {
|
||||
if len(am.PreferredChains.AnyCommonName) > 0 || len(am.PreferredChains.RootCommonName) > 0 {
|
||||
am.Logger.Debug("there is only one chain offered; selecting it regardless of preferences",
|
||||
zap.String("chain_url", certChains[0].URL))
|
||||
}
|
||||
@ -423,11 +430,9 @@ func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.C
|
||||
for i, chain := range certChains {
|
||||
certs, err := parseCertsFromPEMBundle(chain.ChainPEM)
|
||||
if err != nil {
|
||||
if am.Logger != nil {
|
||||
am.Logger.Error("unable to parse PEM certificate chain",
|
||||
zap.Int("chain", i),
|
||||
zap.Error(err))
|
||||
}
|
||||
am.Logger.Error("unable to parse PEM certificate chain",
|
||||
zap.Int("chain", i),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
decodedChains[i] = certs
|
||||
@ -438,11 +443,9 @@ func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.C
|
||||
for i, chain := range decodedChains {
|
||||
for _, cert := range chain {
|
||||
if cert.Issuer.CommonName == prefAnyCN {
|
||||
if am.Logger != nil {
|
||||
am.Logger.Debug("found preferred certificate chain by issuer common name",
|
||||
zap.String("preference", prefAnyCN),
|
||||
zap.Int("chain", i))
|
||||
}
|
||||
am.Logger.Debug("found preferred certificate chain by issuer common name",
|
||||
zap.String("preference", prefAnyCN),
|
||||
zap.Int("chain", i))
|
||||
return certChains[i]
|
||||
}
|
||||
}
|
||||
@ -454,20 +457,16 @@ func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.C
|
||||
for _, prefRootCN := range am.PreferredChains.RootCommonName {
|
||||
for i, chain := range decodedChains {
|
||||
if chain[len(chain)-1].Issuer.CommonName == prefRootCN {
|
||||
if am.Logger != nil {
|
||||
am.Logger.Debug("found preferred certificate chain by root common name",
|
||||
zap.String("preference", prefRootCN),
|
||||
zap.Int("chain", i))
|
||||
}
|
||||
am.Logger.Debug("found preferred certificate chain by root common name",
|
||||
zap.String("preference", prefRootCN),
|
||||
zap.Int("chain", i))
|
||||
return certChains[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if am.Logger != nil {
|
||||
am.Logger.Warn("did not find chain matching preferences; using first")
|
||||
}
|
||||
am.Logger.Warn("did not find chain matching preferences; using first")
|
||||
}
|
||||
|
||||
return certChains[0]
|
||||
@ -509,6 +508,7 @@ type ChainPreference struct {
|
||||
var DefaultACME = ACMEIssuer{
|
||||
CA: LetsEncryptProductionCA,
|
||||
TestCA: LetsEncryptStagingCA,
|
||||
Logger: defaultLogger,
|
||||
}
|
||||
|
||||
// Some well-known CA endpoints available to use.
|
||||
|
||||
31
vendor/github.com/caddyserver/certmagic/async.go
generated
vendored
31
vendor/github.com/caddyserver/certmagic/async.go
generated
vendored
@ -71,9 +71,7 @@ func (jm *jobManager) worker() {
|
||||
jm.queue = jm.queue[1:]
|
||||
jm.mu.Unlock()
|
||||
if err := next.job(); err != nil {
|
||||
if next.logger != nil {
|
||||
next.logger.Error("job failed", zap.Error(err))
|
||||
}
|
||||
next.logger.Error("job failed", zap.Error(err))
|
||||
}
|
||||
if next.name != "" {
|
||||
jm.mu.Lock()
|
||||
@ -116,22 +114,19 @@ func doWithRetry(ctx context.Context, log *zap.Logger, f func(context.Context) e
|
||||
intervalIndex++
|
||||
}
|
||||
if time.Since(start) < maxRetryDuration {
|
||||
if log != nil {
|
||||
log.Error("will retry",
|
||||
zap.Error(err),
|
||||
zap.Int("attempt", attempts),
|
||||
zap.Duration("retrying_in", retryIntervals[intervalIndex]),
|
||||
zap.Duration("elapsed", time.Since(start)),
|
||||
zap.Duration("max_duration", maxRetryDuration))
|
||||
}
|
||||
log.Error("will retry",
|
||||
zap.Error(err),
|
||||
zap.Int("attempt", attempts),
|
||||
zap.Duration("retrying_in", retryIntervals[intervalIndex]),
|
||||
zap.Duration("elapsed", time.Since(start)),
|
||||
zap.Duration("max_duration", maxRetryDuration))
|
||||
|
||||
} else {
|
||||
if log != nil {
|
||||
log.Error("final attempt; giving up",
|
||||
zap.Error(err),
|
||||
zap.Int("attempt", attempts),
|
||||
zap.Duration("elapsed", time.Since(start)),
|
||||
zap.Duration("max_duration", maxRetryDuration))
|
||||
}
|
||||
log.Error("final attempt; giving up",
|
||||
zap.Error(err),
|
||||
zap.Int("attempt", attempts),
|
||||
zap.Duration("elapsed", time.Since(start)),
|
||||
zap.Duration("max_duration", maxRetryDuration))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
75
vendor/github.com/caddyserver/certmagic/cache.go
generated
vendored
75
vendor/github.com/caddyserver/certmagic/cache.go
generated
vendored
@ -118,6 +118,11 @@ func NewCache(opts CacheOptions) *Cache {
|
||||
logger: opts.Logger,
|
||||
}
|
||||
|
||||
// absolutely do not allow a nil logger; panics galore
|
||||
if c.logger == nil {
|
||||
c.logger = defaultLogger
|
||||
}
|
||||
|
||||
go c.maintainAssets(0)
|
||||
|
||||
return c
|
||||
@ -194,14 +199,12 @@ func (certCache *Cache) cacheCertificate(cert Certificate) {
|
||||
func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||
// no-op if this certificate already exists in the cache
|
||||
if _, ok := certCache.cache[cert.hash]; ok {
|
||||
if certCache.logger != nil {
|
||||
certCache.logger.Debug("certificate already cached",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash))
|
||||
}
|
||||
certCache.logger.Debug("certificate already cached",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash))
|
||||
return
|
||||
}
|
||||
|
||||
@ -217,13 +220,11 @@ func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||
i := 0
|
||||
for _, randomCert := range certCache.cache {
|
||||
if i == rnd {
|
||||
if certCache.logger != nil {
|
||||
certCache.logger.Debug("cache full; evicting random certificate",
|
||||
zap.Strings("removing_subjects", randomCert.Names),
|
||||
zap.String("removing_hash", randomCert.hash),
|
||||
zap.Strings("inserting_subjects", cert.Names),
|
||||
zap.String("inserting_hash", cert.hash))
|
||||
}
|
||||
certCache.logger.Debug("cache full; evicting random certificate",
|
||||
zap.Strings("removing_subjects", randomCert.Names),
|
||||
zap.String("removing_hash", randomCert.hash),
|
||||
zap.Strings("inserting_subjects", cert.Names),
|
||||
zap.String("inserting_hash", cert.hash))
|
||||
certCache.removeCertificate(randomCert)
|
||||
break
|
||||
}
|
||||
@ -239,16 +240,14 @@ func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||
certCache.cacheIndex[name] = append(certCache.cacheIndex[name], cert.hash)
|
||||
}
|
||||
|
||||
if certCache.logger != nil {
|
||||
certCache.logger.Debug("added certificate to cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash),
|
||||
zap.Int("cache_size", len(certCache.cache)),
|
||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||
}
|
||||
certCache.logger.Debug("added certificate to cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash),
|
||||
zap.Int("cache_size", len(certCache.cache)),
|
||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||
}
|
||||
|
||||
// removeCertificate removes cert from the cache.
|
||||
@ -275,16 +274,14 @@ func (certCache *Cache) removeCertificate(cert Certificate) {
|
||||
// delete the actual cert from the cache
|
||||
delete(certCache.cache, cert.hash)
|
||||
|
||||
if certCache.logger != nil {
|
||||
certCache.logger.Debug("removed certificate from cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash),
|
||||
zap.Int("cache_size", len(certCache.cache)),
|
||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||
}
|
||||
certCache.logger.Debug("removed certificate from cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash),
|
||||
zap.Int("cache_size", len(certCache.cache)),
|
||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||
}
|
||||
|
||||
// replaceCertificate atomically replaces oldCert with newCert in
|
||||
@ -296,11 +293,9 @@ func (certCache *Cache) replaceCertificate(oldCert, newCert Certificate) {
|
||||
certCache.removeCertificate(oldCert)
|
||||
certCache.unsyncedCacheCertificate(newCert)
|
||||
certCache.mu.Unlock()
|
||||
if certCache.logger != nil {
|
||||
certCache.logger.Info("replaced certificate in cache",
|
||||
zap.Strings("subjects", newCert.Names),
|
||||
zap.Time("new_expiration", newCert.Leaf.NotAfter))
|
||||
}
|
||||
certCache.logger.Info("replaced certificate in cache",
|
||||
zap.Strings("subjects", newCert.Names),
|
||||
zap.Time("new_expiration", expiresAt(newCert.Leaf)))
|
||||
}
|
||||
|
||||
func (certCache *Cache) getAllMatchingCerts(name string) []Certificate {
|
||||
|
||||
27
vendor/github.com/caddyserver/certmagic/certificates.go
generated
vendored
27
vendor/github.com/caddyserver/certmagic/certificates.go
generated
vendored
@ -67,7 +67,7 @@ func (cert Certificate) Empty() bool {
|
||||
// NeedsRenewal returns true if the certificate is
|
||||
// expiring soon (according to cfg) or has expired.
|
||||
func (cert Certificate) NeedsRenewal(cfg *Config) bool {
|
||||
return currentlyInRenewalWindow(cert.Leaf.NotBefore, cert.Leaf.NotAfter, cfg.RenewalWindowRatio)
|
||||
return currentlyInRenewalWindow(cert.Leaf.NotBefore, expiresAt(cert.Leaf), cfg.RenewalWindowRatio)
|
||||
}
|
||||
|
||||
// Expired returns true if the certificate has expired.
|
||||
@ -79,7 +79,7 @@ func (cert Certificate) Expired() bool {
|
||||
// tls.X509KeyPair() discards the leaf; oh well
|
||||
return false
|
||||
}
|
||||
return time.Now().After(cert.Leaf.NotAfter)
|
||||
return time.Now().After(expiresAt(cert.Leaf))
|
||||
}
|
||||
|
||||
// currentlyInRenewalWindow returns true if the current time is
|
||||
@ -109,6 +109,13 @@ func (cert Certificate) HasTag(tag string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// expiresAt return the time that a certificate expires. Account for the 1s
|
||||
// resolution of ASN.1 UTCTime/GeneralizedTime by including the extra fraction
|
||||
// of a second of certificate validity beyond the NotAfter value.
|
||||
func expiresAt(cert *x509.Certificate) time.Time {
|
||||
return cert.NotAfter.Truncate(time.Second).Add(1 * time.Second)
|
||||
}
|
||||
|
||||
// CacheManagedCertificate loads the certificate for domain into the
|
||||
// cache, from the TLS storage for managed certificates. It returns a
|
||||
// copy of the Certificate that was put into the cache.
|
||||
@ -122,7 +129,7 @@ func (cfg *Config) CacheManagedCertificate(ctx context.Context, domain string) (
|
||||
return cert, err
|
||||
}
|
||||
cfg.certCache.cacheCertificate(cert)
|
||||
cfg.emit("cached_managed_cert", cert.Names)
|
||||
cfg.emit(ctx, "cached_managed_cert", map[string]any{"sans": cert.Names})
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
@ -155,7 +162,7 @@ func (cfg *Config) CacheUnmanagedCertificatePEMFile(ctx context.Context, certFil
|
||||
}
|
||||
cert.Tags = tags
|
||||
cfg.certCache.cacheCertificate(cert)
|
||||
cfg.emit("cached_unmanaged_cert", cert.Names)
|
||||
cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -170,10 +177,10 @@ func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tlsCert tls
|
||||
return err
|
||||
}
|
||||
err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil)
|
||||
if err != nil && cfg.Logger != nil {
|
||||
if err != nil {
|
||||
cfg.Logger.Warn("stapling OCSP", zap.Error(err))
|
||||
}
|
||||
cfg.emit("cached_unmanaged_cert", cert.Names)
|
||||
cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names})
|
||||
cert.Tags = tags
|
||||
cfg.certCache.cacheCertificate(cert)
|
||||
return nil
|
||||
@ -190,7 +197,7 @@ func (cfg *Config) CacheUnmanagedCertificatePEMBytes(ctx context.Context, certBy
|
||||
}
|
||||
cert.Tags = tags
|
||||
cfg.certCache.cacheCertificate(cert)
|
||||
cfg.emit("cached_unmanaged_cert", cert.Names)
|
||||
cfg.emit(ctx, "cached_unmanaged_cert", map[string]any{"sans": cert.Names})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -218,7 +225,7 @@ func (cfg Config) makeCertificateWithOCSP(ctx context.Context, certPEMBlock, key
|
||||
return cert, err
|
||||
}
|
||||
err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, certPEMBlock)
|
||||
if err != nil && cfg.Logger != nil {
|
||||
if err != nil {
|
||||
cfg.Logger.Warn("stapling OCSP", zap.Error(err), zap.Strings("identifiers", cert.Names))
|
||||
}
|
||||
return cert, nil
|
||||
@ -326,9 +333,7 @@ func (cfg *Config) managedCertInStorageExpiresSoon(ctx context.Context, cert Cer
|
||||
// to the new cert. It assumes that the new certificate for oldCert.Names[0] is
|
||||
// already in storage. It returns the newly-loaded certificate if successful.
|
||||
func (cfg *Config) reloadManagedCertificate(ctx context.Context, oldCert Certificate) (Certificate, error) {
|
||||
if cfg.Logger != nil {
|
||||
cfg.Logger.Info("reloading managed certificate", zap.Strings("identifiers", oldCert.Names))
|
||||
}
|
||||
cfg.Logger.Info("reloading managed certificate", zap.Strings("identifiers", oldCert.Names))
|
||||
newCert, err := cfg.loadManagedCertificate(ctx, oldCert.Names[0])
|
||||
if err != nil {
|
||||
return Certificate{}, fmt.Errorf("loading managed certificate for %v from storage: %v", oldCert.Names, err)
|
||||
|
||||
16
vendor/github.com/caddyserver/certmagic/certmagic.go
generated
vendored
16
vendor/github.com/caddyserver/certmagic/certmagic.go
generated
vendored
@ -43,10 +43,14 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// HTTPS serves mux for all domainNames using the HTTP
|
||||
@ -405,7 +409,7 @@ type IssuedCertificate struct {
|
||||
|
||||
// Any extra information to serialize alongside the
|
||||
// certificate in storage.
|
||||
Metadata interface{}
|
||||
Metadata any
|
||||
}
|
||||
|
||||
// CertificateResource associates a certificate with its private
|
||||
@ -425,7 +429,7 @@ type CertificateResource struct {
|
||||
|
||||
// Any extra information associated with the certificate,
|
||||
// usually provided by the issuer implementation.
|
||||
IssuerData interface{} `json:"issuer_data,omitempty"`
|
||||
IssuerData any `json:"issuer_data,omitempty"`
|
||||
|
||||
// The unique string identifying the issuer of the
|
||||
// certificate; internally useful for storage access.
|
||||
@ -468,8 +472,16 @@ var Default = Config{
|
||||
RenewalWindowRatio: DefaultRenewalWindowRatio,
|
||||
Storage: defaultFileStorage,
|
||||
KeySource: DefaultKeyGenerator,
|
||||
Logger: defaultLogger,
|
||||
}
|
||||
|
||||
// defaultLogger is guaranteed to be a non-nil fallback logger.
|
||||
var defaultLogger = zap.New(zapcore.NewCore(
|
||||
zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig()),
|
||||
os.Stderr,
|
||||
zap.InfoLevel,
|
||||
))
|
||||
|
||||
const (
|
||||
// HTTPChallengePort is the officially-designated port for
|
||||
// the HTTP challenge according to the ACME spec.
|
||||
|
||||
254
vendor/github.com/caddyserver/certmagic/config.go
generated
vendored
254
vendor/github.com/caddyserver/certmagic/config.go
generated
vendored
@ -56,7 +56,16 @@ type Config struct {
|
||||
// to subscribe to certain things happening
|
||||
// internally by this config; invocations are
|
||||
// synchronous, so make them return quickly!
|
||||
OnEvent func(event string, data interface{})
|
||||
// Functions should honor context cancellation.
|
||||
//
|
||||
// An error should only be returned to advise
|
||||
// the emitter to abort or cancel an upcoming
|
||||
// event. Some events, especially those that have
|
||||
// already happened, cannot be aborted. For example,
|
||||
// cert_obtaining can be canceled, but
|
||||
// cert_obtained cannot. Emitters may choose to
|
||||
// ignore returned errors.
|
||||
OnEvent func(ctx context.Context, event string, data map[string]any) error
|
||||
|
||||
// DefaultServerName specifies a server name
|
||||
// to use when choosing a certificate if the
|
||||
@ -110,7 +119,8 @@ type Config struct {
|
||||
// TLS assets. Default is the local file system.
|
||||
Storage Storage
|
||||
|
||||
// Set a logger to enable logging.
|
||||
// Set a logger to enable logging. If not set,
|
||||
// a default logger will be created.
|
||||
Logger *zap.Logger
|
||||
|
||||
// required pointer to the in-memory cert cache
|
||||
@ -196,6 +206,16 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||
if cfg.OnDemand == nil {
|
||||
cfg.OnDemand = Default.OnDemand
|
||||
}
|
||||
if !cfg.MustStaple {
|
||||
cfg.MustStaple = Default.MustStaple
|
||||
}
|
||||
if len(cfg.Issuers) == 0 {
|
||||
cfg.Issuers = Default.Issuers
|
||||
if len(cfg.Issuers) == 0 {
|
||||
// at least one issuer is absolutely required
|
||||
cfg.Issuers = []Issuer{NewACMEIssuer(&cfg, DefaultACME)}
|
||||
}
|
||||
}
|
||||
if cfg.RenewalWindowRatio == 0 {
|
||||
cfg.RenewalWindowRatio = Default.RenewalWindowRatio
|
||||
}
|
||||
@ -208,18 +228,11 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||
if cfg.DefaultServerName == "" {
|
||||
cfg.DefaultServerName = Default.DefaultServerName
|
||||
}
|
||||
if !cfg.MustStaple {
|
||||
cfg.MustStaple = Default.MustStaple
|
||||
}
|
||||
if cfg.Storage == nil {
|
||||
cfg.Storage = Default.Storage
|
||||
}
|
||||
if len(cfg.Issuers) == 0 {
|
||||
cfg.Issuers = Default.Issuers
|
||||
if len(cfg.Issuers) == 0 {
|
||||
// at least one issuer is absolutely required
|
||||
cfg.Issuers = []Issuer{NewACMEIssuer(&cfg, DefaultACME)}
|
||||
}
|
||||
if cfg.Logger == nil {
|
||||
cfg.Logger = Default.Logger
|
||||
}
|
||||
|
||||
// absolutely don't allow a nil storage,
|
||||
@ -229,6 +242,12 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||
cfg.Storage = defaultFileStorage
|
||||
}
|
||||
|
||||
// absolutely don't allow a nil logger either,
|
||||
// because that would result in panics
|
||||
if cfg.Logger == nil {
|
||||
cfg.Logger = defaultLogger
|
||||
}
|
||||
|
||||
cfg.certCache = certCache
|
||||
|
||||
return &cfg
|
||||
@ -460,11 +479,9 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
return fmt.Errorf("failed storage check: %v - storage is probably misconfigured", err)
|
||||
}
|
||||
|
||||
log := loggerNamed(cfg.Logger, "obtain")
|
||||
log := cfg.Logger.Named("obtain")
|
||||
|
||||
if log != nil {
|
||||
log.Info("acquiring lock", zap.String("identifier", name))
|
||||
}
|
||||
log.Info("acquiring lock", zap.String("identifier", name))
|
||||
|
||||
// ensure idempotency of the obtain operation for this name
|
||||
lockKey := cfg.lockKey(certIssueLockOp, name)
|
||||
@ -473,33 +490,30 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
return fmt.Errorf("unable to acquire lock '%s': %v", lockKey, err)
|
||||
}
|
||||
defer func() {
|
||||
if log != nil {
|
||||
log.Info("releasing lock", zap.String("identifier", name))
|
||||
}
|
||||
log.Info("releasing lock", zap.String("identifier", name))
|
||||
if err := releaseLock(ctx, cfg.Storage, lockKey); err != nil {
|
||||
if log != nil {
|
||||
log.Error("unable to unlock",
|
||||
zap.String("identifier", name),
|
||||
zap.String("lock_key", lockKey),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Error("unable to unlock",
|
||||
zap.String("identifier", name),
|
||||
zap.String("lock_key", lockKey),
|
||||
zap.Error(err))
|
||||
}
|
||||
}()
|
||||
if log != nil {
|
||||
log.Info("lock acquired", zap.String("identifier", name))
|
||||
}
|
||||
log.Info("lock acquired", zap.String("identifier", name))
|
||||
|
||||
f := func(ctx context.Context) error {
|
||||
// check if obtain is still needed -- might have been obtained during lock
|
||||
if cfg.storageHasCertResourcesAnyIssuer(ctx, name) {
|
||||
if log != nil {
|
||||
log.Info("certificate already exists in storage", zap.String("identifier", name))
|
||||
}
|
||||
log.Info("certificate already exists in storage", zap.String("identifier", name))
|
||||
return nil
|
||||
}
|
||||
|
||||
// if storage has a private key already, use it; otherwise,
|
||||
// we'll generate our own
|
||||
log.Info("obtaining certificate", zap.String("identifier", name))
|
||||
|
||||
if err := cfg.emit(ctx, "cert_obtaining", map[string]any{"identifier": name}); err != nil {
|
||||
return fmt.Errorf("obtaining certificate aborted by event handler: %w", err)
|
||||
}
|
||||
|
||||
// if storage has a private key already, use it; otherwise we'll generate our own
|
||||
privKey, privKeyPEM, issuers, err := cfg.reusePrivateKey(ctx, name)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -523,11 +537,12 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
// try to obtain from each issuer until we succeed
|
||||
var issuedCert *IssuedCertificate
|
||||
var issuerUsed Issuer
|
||||
var issuerKeys []string
|
||||
for i, issuer := range issuers {
|
||||
if log != nil {
|
||||
log.Debug(fmt.Sprintf("trying issuer %d/%d", i+1, len(cfg.Issuers)),
|
||||
zap.String("issuer", issuer.IssuerKey()))
|
||||
}
|
||||
issuerKeys = append(issuerKeys, issuer.IssuerKey())
|
||||
|
||||
log.Debug(fmt.Sprintf("trying issuer %d/%d", i+1, len(cfg.Issuers)),
|
||||
zap.String("issuer", issuer.IssuerKey()))
|
||||
|
||||
if prechecker, ok := issuer.(PreChecker); ok {
|
||||
err = prechecker.PreCheck(ctx, []string{name}, interactive)
|
||||
@ -549,14 +564,19 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
if errors.As(err, &problem) {
|
||||
errToLog = problem
|
||||
}
|
||||
if log != nil {
|
||||
log.Error("could not get certificate from issuer",
|
||||
zap.String("identifier", name),
|
||||
zap.String("issuer", issuer.IssuerKey()),
|
||||
zap.Error(errToLog))
|
||||
}
|
||||
log.Error("could not get certificate from issuer",
|
||||
zap.String("identifier", name),
|
||||
zap.String("issuer", issuer.IssuerKey()),
|
||||
zap.Error(errToLog))
|
||||
}
|
||||
if err != nil {
|
||||
cfg.emit(ctx, "cert_failed", map[string]any{
|
||||
"renewal": false,
|
||||
"identifier": name,
|
||||
"issuers": issuerKeys,
|
||||
"error": err,
|
||||
})
|
||||
|
||||
// only the error from the last issuer will be returned, but we logged the others
|
||||
return fmt.Errorf("[%s] Obtain: %w", name, err)
|
||||
}
|
||||
@ -573,15 +593,14 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
|
||||
return fmt.Errorf("[%s] Obtain: saving assets: %v", name, err)
|
||||
}
|
||||
|
||||
cfg.emit("cert_obtained", CertificateEventData{
|
||||
Name: name,
|
||||
IssuerKey: issuerUsed.IssuerKey(),
|
||||
StorageKey: certRes.NamesKey(),
|
||||
})
|
||||
log.Info("certificate obtained successfully", zap.String("identifier", name))
|
||||
|
||||
if log != nil {
|
||||
log.Info("certificate obtained successfully", zap.String("identifier", name))
|
||||
}
|
||||
cfg.emit(ctx, "cert_obtained", map[string]any{
|
||||
"renewal": false,
|
||||
"identifier": name,
|
||||
"issuers": issuerUsed.IssuerKey(),
|
||||
"storage_key": certRes.NamesKey(),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -675,11 +694,9 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
return fmt.Errorf("failed storage check: %v - storage is probably misconfigured", err)
|
||||
}
|
||||
|
||||
log := loggerNamed(cfg.Logger, "renew")
|
||||
log := cfg.Logger.Named("renew")
|
||||
|
||||
if log != nil {
|
||||
log.Info("acquiring lock", zap.String("identifier", name))
|
||||
}
|
||||
log.Info("acquiring lock", zap.String("identifier", name))
|
||||
|
||||
// ensure idempotency of the renew operation for this name
|
||||
lockKey := cfg.lockKey(certIssueLockOp, name)
|
||||
@ -688,21 +705,16 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
return fmt.Errorf("unable to acquire lock '%s': %v", lockKey, err)
|
||||
}
|
||||
defer func() {
|
||||
if log != nil {
|
||||
log.Info("releasing lock", zap.String("identifier", name))
|
||||
}
|
||||
log.Info("releasing lock", zap.String("identifier", name))
|
||||
|
||||
if err := releaseLock(ctx, cfg.Storage, lockKey); err != nil {
|
||||
if log != nil {
|
||||
log.Error("unable to unlock",
|
||||
zap.String("identifier", name),
|
||||
zap.String("lock_key", lockKey),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Error("unable to unlock",
|
||||
zap.String("identifier", name),
|
||||
zap.String("lock_key", lockKey),
|
||||
zap.Error(err))
|
||||
}
|
||||
}()
|
||||
if log != nil {
|
||||
log.Info("lock acquired", zap.String("identifier", name))
|
||||
}
|
||||
log.Info("lock acquired", zap.String("identifier", name))
|
||||
|
||||
f := func(ctx context.Context) error {
|
||||
// prepare for renewal (load PEM cert, key, and meta)
|
||||
@ -715,25 +727,29 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
timeLeft, needsRenew := cfg.managedCertNeedsRenewal(certRes)
|
||||
if !needsRenew {
|
||||
if force {
|
||||
if log != nil {
|
||||
log.Info("certificate does not need to be renewed, but renewal is being forced",
|
||||
zap.String("identifier", name),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
}
|
||||
log.Info("certificate does not need to be renewed, but renewal is being forced",
|
||||
zap.String("identifier", name),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
} else {
|
||||
if log != nil {
|
||||
log.Info("certificate appears to have been renewed already",
|
||||
zap.String("identifier", name),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
}
|
||||
log.Info("certificate appears to have been renewed already",
|
||||
zap.String("identifier", name),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if log != nil {
|
||||
log.Info("renewing certificate",
|
||||
zap.String("identifier", name),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
log.Info("renewing certificate",
|
||||
zap.String("identifier", name),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
|
||||
if err := cfg.emit(ctx, "cert_obtaining", map[string]any{
|
||||
"renewal": true,
|
||||
"identifier": name,
|
||||
"forced": force,
|
||||
"remaining": timeLeft,
|
||||
"issuer": certRes.issuerKey, // previous/current issuer
|
||||
}); err != nil {
|
||||
return fmt.Errorf("renewing certificate aborted by event handler: %w", err)
|
||||
}
|
||||
|
||||
privateKey, err := PEMDecodePrivateKey(certRes.PrivateKeyPEM)
|
||||
@ -748,7 +764,9 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
// try to obtain from each issuer until we succeed
|
||||
var issuedCert *IssuedCertificate
|
||||
var issuerUsed Issuer
|
||||
var issuerKeys []string
|
||||
for _, issuer := range cfg.Issuers {
|
||||
issuerKeys = append(issuerKeys, issuer.IssuerKey())
|
||||
if prechecker, ok := issuer.(PreChecker); ok {
|
||||
err = prechecker.PreCheck(ctx, []string{name}, interactive)
|
||||
if err != nil {
|
||||
@ -769,14 +787,21 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
if errors.As(err, &problem) {
|
||||
errToLog = problem
|
||||
}
|
||||
if log != nil {
|
||||
log.Error("could not get certificate from issuer",
|
||||
zap.String("identifier", name),
|
||||
zap.String("issuer", issuer.IssuerKey()),
|
||||
zap.Error(errToLog))
|
||||
}
|
||||
log.Error("could not get certificate from issuer",
|
||||
zap.String("identifier", name),
|
||||
zap.String("issuer", issuer.IssuerKey()),
|
||||
zap.Error(errToLog))
|
||||
}
|
||||
if err != nil {
|
||||
cfg.emit(ctx, "cert_failed", map[string]any{
|
||||
"renewal": true,
|
||||
"identifier": name,
|
||||
"remaining": timeLeft,
|
||||
"issuers": issuerKeys,
|
||||
"storage_key": certRes.NamesKey(),
|
||||
"error": err,
|
||||
})
|
||||
|
||||
// only the error from the last issuer will be returned, but we logged the others
|
||||
return fmt.Errorf("[%s] Renew: %w", name, err)
|
||||
}
|
||||
@ -793,15 +818,15 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||
return fmt.Errorf("[%s] Renew: saving assets: %v", name, err)
|
||||
}
|
||||
|
||||
cfg.emit("cert_renewed", CertificateEventData{
|
||||
Name: name,
|
||||
IssuerKey: issuerUsed.IssuerKey(),
|
||||
StorageKey: certRes.NamesKey(),
|
||||
})
|
||||
log.Info("certificate renewed successfully", zap.String("identifier", name))
|
||||
|
||||
if log != nil {
|
||||
log.Info("certificate renewed successfully", zap.String("identifier", name))
|
||||
}
|
||||
cfg.emit(ctx, "cert_obtained", map[string]any{
|
||||
"renewal": true,
|
||||
"remaining": timeLeft,
|
||||
"identifier": name,
|
||||
"issuer": issuerUsed.IssuerKey(),
|
||||
"storage_key": certRes.NamesKey(),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -876,12 +901,6 @@ func (cfg *Config) RevokeCert(ctx context.Context, domain string, reason int, in
|
||||
return fmt.Errorf("issuer %d (%s): %v", i, issuerKey, err)
|
||||
}
|
||||
|
||||
cfg.emit("cert_revoked", CertificateEventData{
|
||||
Name: domain,
|
||||
IssuerKey: issuerKey,
|
||||
StorageKey: certRes.NamesKey(),
|
||||
})
|
||||
|
||||
err = cfg.deleteSiteAssets(ctx, issuerKey, domain)
|
||||
if err != nil {
|
||||
return fmt.Errorf("certificate revoked, but unable to fully clean up assets from issuer %s: %v", issuerKey, err)
|
||||
@ -994,10 +1013,8 @@ func (cfg *Config) checkStorage(ctx context.Context) error {
|
||||
defer func() {
|
||||
deleteErr := cfg.Storage.Delete(ctx, key)
|
||||
if deleteErr != nil {
|
||||
if cfg.Logger != nil {
|
||||
cfg.Logger.Error("deleting test key from storage",
|
||||
zap.String("key", key), zap.Error(err))
|
||||
}
|
||||
cfg.Logger.Error("deleting test key from storage",
|
||||
zap.String("key", key), zap.Error(err))
|
||||
}
|
||||
// if there was no other error, make sure
|
||||
// to return any error returned from Delete
|
||||
@ -1065,23 +1082,16 @@ func (cfg *Config) managedCertNeedsRenewal(certRes CertificateResource) (time.Du
|
||||
if err != nil {
|
||||
return 0, true
|
||||
}
|
||||
remaining := time.Until(certChain[0].NotAfter)
|
||||
needsRenew := currentlyInRenewalWindow(certChain[0].NotBefore, certChain[0].NotAfter, cfg.RenewalWindowRatio)
|
||||
remaining := time.Until(expiresAt(certChain[0]))
|
||||
needsRenew := currentlyInRenewalWindow(certChain[0].NotBefore, expiresAt(certChain[0]), cfg.RenewalWindowRatio)
|
||||
return remaining, needsRenew
|
||||
}
|
||||
|
||||
func (cfg *Config) emit(eventName string, data interface{}) {
|
||||
func (cfg *Config) emit(ctx context.Context, eventName string, data map[string]any) error {
|
||||
if cfg.OnEvent == nil {
|
||||
return
|
||||
}
|
||||
cfg.OnEvent(eventName, data)
|
||||
}
|
||||
|
||||
func loggerNamed(l *zap.Logger, name string) *zap.Logger {
|
||||
if l == nil {
|
||||
return nil
|
||||
}
|
||||
return l.Named(name)
|
||||
return cfg.OnEvent(ctx, eventName, data)
|
||||
}
|
||||
|
||||
// CertificateSelector is a type which can select a certificate to use given multiple choices.
|
||||
@ -1105,20 +1115,6 @@ type OCSPConfig struct {
|
||||
ResponderOverrides map[string]string
|
||||
}
|
||||
|
||||
// CertificateEventData contains contextual information for
|
||||
// an obtained, renewed or revoked certificate.
|
||||
// EXPERIMENTAL: subject to change.
|
||||
type CertificateEventData struct {
|
||||
// Domain or subject name of the certificate.
|
||||
Name string
|
||||
|
||||
// Storage key for the issuer used for this certificate.
|
||||
IssuerKey string
|
||||
|
||||
// Location in storage at which the certificate could be found.
|
||||
StorageKey string
|
||||
}
|
||||
|
||||
// certIssueLockOp is the name of the operation used
|
||||
// when naming a lock to make it mutually exclusive
|
||||
// with other certificate issuance operations for a
|
||||
|
||||
14
vendor/github.com/caddyserver/certmagic/crypto.go
generated
vendored
14
vendor/github.com/caddyserver/certmagic/crypto.go
generated
vendored
@ -226,14 +226,12 @@ func (cfg *Config) loadCertResourceAnyIssuer(ctx context.Context, certNamesKey s
|
||||
return certResources[j].decoded.NotBefore.Before(certResources[i].decoded.NotBefore)
|
||||
})
|
||||
|
||||
if cfg.Logger != nil {
|
||||
cfg.Logger.Debug("loading managed certificate",
|
||||
zap.String("domain", certNamesKey),
|
||||
zap.Time("expiration", certResources[0].decoded.NotAfter),
|
||||
zap.String("issuer_key", certResources[0].issuer.IssuerKey()),
|
||||
zap.Any("storage", cfg.Storage),
|
||||
)
|
||||
}
|
||||
cfg.Logger.Debug("loading managed certificate",
|
||||
zap.String("domain", certNamesKey),
|
||||
zap.Time("expiration", expiresAt(certResources[0].decoded)),
|
||||
zap.String("issuer_key", certResources[0].issuer.IssuerKey()),
|
||||
zap.Any("storage", cfg.Storage),
|
||||
)
|
||||
|
||||
return certResources[0].CertificateResource, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/caddyserver/certmagic/dnsutil.go
generated
vendored
2
vendor/github.com/caddyserver/certmagic/dnsutil.go
generated
vendored
@ -243,7 +243,7 @@ func checkAuthoritativeNss(fqdn, value string, nameservers []string) (bool, erro
|
||||
}
|
||||
|
||||
if r.Rcode != dns.RcodeSuccess {
|
||||
if r.Rcode == dns.RcodeNameError {
|
||||
if r.Rcode == dns.RcodeNameError || r.Rcode == dns.RcodeServerFailure {
|
||||
// if Present() succeeded, then it must show up eventually, or else
|
||||
// something is really broken in the DNS provider or their API;
|
||||
// no need for error here, simply have the caller try again
|
||||
|
||||
26
vendor/github.com/caddyserver/certmagic/filestorage.go
generated
vendored
26
vendor/github.com/caddyserver/certmagic/filestorage.go
generated
vendored
@ -149,10 +149,10 @@ func (s *FileStorage) Filename(key string) string {
|
||||
return filepath.Join(s.Path, filepath.FromSlash(key))
|
||||
}
|
||||
|
||||
// Lock obtains a lock named by the given key. It blocks
|
||||
// Lock obtains a lock named by the given name. It blocks
|
||||
// until the lock can be obtained or an error is returned.
|
||||
func (s *FileStorage) Lock(ctx context.Context, key string) error {
|
||||
filename := s.lockFilename(key)
|
||||
func (s *FileStorage) Lock(ctx context.Context, name string) error {
|
||||
filename := s.lockFilename(name)
|
||||
|
||||
for {
|
||||
err := createLockfile(filename)
|
||||
@ -172,7 +172,13 @@ func (s *FileStorage) Lock(ctx context.Context, key string) error {
|
||||
if err == nil {
|
||||
err2 := json.NewDecoder(f).Decode(&meta)
|
||||
f.Close()
|
||||
if err2 != nil {
|
||||
if errors.Is(err2, io.EOF) {
|
||||
// lockfile is empty or truncated; I *think* we can assume the previous
|
||||
// acquirer either crashed or had some sort of failure that caused them
|
||||
// to be unable to fully acquire or retain the lock, therefore we should
|
||||
// treat it as if the lockfile did not exist
|
||||
log.Printf("[INFO][%s] %s: Empty lockfile (%v) - likely previous process crashed or storage medium failure; treating as stale", s, filename, err2)
|
||||
} else if err2 != nil {
|
||||
return fmt.Errorf("decoding lockfile contents: %w", err2)
|
||||
}
|
||||
}
|
||||
@ -193,10 +199,10 @@ func (s *FileStorage) Lock(ctx context.Context, key string) error {
|
||||
// or must give up on perfect mutual exclusivity; however, these cases are rare,
|
||||
// so we prefer the simpler solution that avoids infinite loops)
|
||||
log.Printf("[INFO][%s] Lock for '%s' is stale (created: %s, last update: %s); removing then retrying: %s",
|
||||
s, key, meta.Created, meta.Updated, filename)
|
||||
s, name, meta.Created, meta.Updated, filename)
|
||||
if err = os.Remove(filename); err != nil { // hopefully we can replace the lock file quickly!
|
||||
if !errors.Is(err, fs.ErrNotExist) {
|
||||
return fmt.Errorf("unable to delete stale lock; deadlocked: %w", err)
|
||||
return fmt.Errorf("unable to delete stale lockfile; deadlocked: %w", err)
|
||||
}
|
||||
}
|
||||
continue
|
||||
@ -215,16 +221,16 @@ func (s *FileStorage) Lock(ctx context.Context, key string) error {
|
||||
}
|
||||
|
||||
// Unlock releases the lock for name.
|
||||
func (s *FileStorage) Unlock(_ context.Context, key string) error {
|
||||
return os.Remove(s.lockFilename(key))
|
||||
func (s *FileStorage) Unlock(_ context.Context, name string) error {
|
||||
return os.Remove(s.lockFilename(name))
|
||||
}
|
||||
|
||||
func (s *FileStorage) String() string {
|
||||
return "FileStorage:" + s.Path
|
||||
}
|
||||
|
||||
func (s *FileStorage) lockFilename(key string) string {
|
||||
return filepath.Join(s.lockDir(), StorageKeys.Safe(key)+".lock")
|
||||
func (s *FileStorage) lockFilename(name string) string {
|
||||
return filepath.Join(s.lockDir(), StorageKeys.Safe(name)+".lock")
|
||||
}
|
||||
|
||||
func (s *FileStorage) lockDir() string {
|
||||
|
||||
335
vendor/github.com/caddyserver/certmagic/handshake.go
generated
vendored
335
vendor/github.com/caddyserver/certmagic/handshake.go
generated
vendored
@ -43,7 +43,15 @@ import (
|
||||
//
|
||||
// This method is safe for use as a tls.Config.GetCertificate callback.
|
||||
func (cfg *Config) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
cfg.emit("tls_handshake_started", clientHello)
|
||||
ctx := context.TODO() // TODO: get a proper context? from somewhere...
|
||||
|
||||
if err := cfg.emit(ctx, "tls_get_certificate", map[string]any{"client_hello": clientHello}); err != nil {
|
||||
cfg.Logger.Error("TLS handshake aborted by event handler",
|
||||
zap.String("server_name", clientHello.ServerName),
|
||||
zap.String("remote", clientHello.Conn.RemoteAddr().String()),
|
||||
zap.Error(err))
|
||||
return nil, fmt.Errorf("handshake aborted by event handler: %w", err)
|
||||
}
|
||||
|
||||
// special case: serve up the certificate for a TLS-ALPN ACME challenge
|
||||
// (https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05)
|
||||
@ -51,29 +59,23 @@ func (cfg *Config) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certif
|
||||
if proto == acmez.ACMETLS1Protocol {
|
||||
challengeCert, distributed, err := cfg.getTLSALPNChallengeCert(clientHello)
|
||||
if err != nil {
|
||||
if cfg.Logger != nil {
|
||||
cfg.Logger.Error("tls-alpn challenge",
|
||||
zap.String("server_name", clientHello.ServerName),
|
||||
zap.Error(err))
|
||||
}
|
||||
cfg.Logger.Error("tls-alpn challenge",
|
||||
zap.String("server_name", clientHello.ServerName),
|
||||
zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
if cfg.Logger != nil {
|
||||
cfg.Logger.Info("served key authentication certificate",
|
||||
zap.String("server_name", clientHello.ServerName),
|
||||
zap.String("challenge", "tls-alpn-01"),
|
||||
zap.String("remote", clientHello.Conn.RemoteAddr().String()),
|
||||
zap.Bool("distributed", distributed))
|
||||
}
|
||||
cfg.Logger.Info("served key authentication certificate",
|
||||
zap.String("server_name", clientHello.ServerName),
|
||||
zap.String("challenge", "tls-alpn-01"),
|
||||
zap.String("remote", clientHello.Conn.RemoteAddr().String()),
|
||||
zap.Bool("distributed", distributed))
|
||||
return challengeCert, nil
|
||||
}
|
||||
}
|
||||
|
||||
// get the certificate and serve it up
|
||||
cert, err := cfg.getCertDuringHandshake(clientHello, true, true)
|
||||
if err == nil {
|
||||
cfg.emit("tls_handshake_completed", clientHello)
|
||||
}
|
||||
cert, err := cfg.getCertDuringHandshake(ctx, clientHello, true, true)
|
||||
|
||||
return &cert.Certificate, err
|
||||
}
|
||||
|
||||
@ -152,48 +154,44 @@ func (cfg *Config) getCertificateFromCache(hello *tls.ClientHelloInfo) (cert Cer
|
||||
// then all certificates in the cache will be passed in
|
||||
// for the cfg.CertSelection to make the final decision.
|
||||
func (cfg *Config) selectCert(hello *tls.ClientHelloInfo, name string) (Certificate, bool) {
|
||||
logger := loggerNamed(cfg.Logger, "handshake")
|
||||
logger := cfg.Logger.Named("handshake")
|
||||
choices := cfg.certCache.getAllMatchingCerts(name)
|
||||
|
||||
if len(choices) == 0 {
|
||||
if cfg.CertSelection == nil {
|
||||
if logger != nil {
|
||||
logger.Debug("no matching certificates and no custom selection logic", zap.String("identifier", name))
|
||||
}
|
||||
logger.Debug("no matching certificates and no custom selection logic", zap.String("identifier", name))
|
||||
return Certificate{}, false
|
||||
}
|
||||
if logger != nil {
|
||||
logger.Debug("no matching certificate; will choose from all certificates", zap.String("identifier", name))
|
||||
}
|
||||
logger.Debug("no matching certificate; will choose from all certificates", zap.String("identifier", name))
|
||||
choices = cfg.certCache.getAllCerts()
|
||||
}
|
||||
if logger != nil {
|
||||
logger.Debug("choosing certificate",
|
||||
zap.String("identifier", name),
|
||||
zap.Int("num_choices", len(choices)))
|
||||
}
|
||||
|
||||
logger.Debug("choosing certificate",
|
||||
zap.String("identifier", name),
|
||||
zap.Int("num_choices", len(choices)))
|
||||
|
||||
if cfg.CertSelection == nil {
|
||||
cert, err := DefaultCertificateSelector(hello, choices)
|
||||
if logger != nil {
|
||||
logger.Debug("default certificate selection results",
|
||||
zap.Error(err),
|
||||
zap.String("identifier", name),
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash))
|
||||
}
|
||||
return cert, err == nil
|
||||
}
|
||||
cert, err := cfg.CertSelection.SelectCertificate(hello, choices)
|
||||
if logger != nil {
|
||||
logger.Debug("custom certificate selection results",
|
||||
logger.Debug("default certificate selection results",
|
||||
zap.Error(err),
|
||||
zap.String("identifier", name),
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash))
|
||||
return cert, err == nil
|
||||
}
|
||||
|
||||
cert, err := cfg.CertSelection.SelectCertificate(hello, choices)
|
||||
|
||||
logger.Debug("custom certificate selection results",
|
||||
zap.Error(err),
|
||||
zap.String("identifier", name),
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.String("issuer_key", cert.issuerKey),
|
||||
zap.String("hash", cert.hash))
|
||||
|
||||
return cert, err == nil
|
||||
}
|
||||
|
||||
@ -214,7 +212,7 @@ func DefaultCertificateSelector(hello *tls.ClientHelloInfo, choices []Certificat
|
||||
continue
|
||||
}
|
||||
best = choice // at least the client supports it...
|
||||
if now.After(choice.Leaf.NotBefore) && now.Before(choice.Leaf.NotAfter) {
|
||||
if now.After(choice.Leaf.NotBefore) && now.Before(expiresAt(choice.Leaf)) {
|
||||
return choice, nil // ...and unexpired, great! "Certificate, I choose you!"
|
||||
}
|
||||
}
|
||||
@ -234,26 +232,22 @@ func DefaultCertificateSelector(hello *tls.ClientHelloInfo, choices []Certificat
|
||||
// An error will be returned if and only if no certificate is available.
|
||||
//
|
||||
// This function is safe for concurrent use.
|
||||
func (cfg *Config) getCertDuringHandshake(hello *tls.ClientHelloInfo, loadIfNecessary, obtainIfNecessary bool) (Certificate, error) {
|
||||
log := loggerNamed(cfg.Logger, "handshake")
|
||||
|
||||
ctx := context.TODO() // TODO: get a proper context? from somewhere...
|
||||
func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.ClientHelloInfo, loadIfNecessary, obtainIfNecessary bool) (Certificate, error) {
|
||||
log := logWithRemote(cfg.Logger.Named("handshake"), hello)
|
||||
|
||||
// First check our in-memory cache to see if we've already loaded it
|
||||
cert, matched, defaulted := cfg.getCertificateFromCache(hello)
|
||||
if matched {
|
||||
if log != nil {
|
||||
log.Debug("matched certificate in cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
||||
zap.String("hash", cert.hash))
|
||||
}
|
||||
log.Debug("matched certificate in cache",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
zap.String("hash", cert.hash))
|
||||
if cert.managed && cfg.OnDemand != nil && obtainIfNecessary {
|
||||
// On-demand certificates are maintained in the background, but
|
||||
// maintenance is triggered by handshakes instead of by a timer
|
||||
// as in maintain.go.
|
||||
return cfg.optionalMaintenance(ctx, loggerNamed(cfg.Logger, "on_demand"), cert, hello)
|
||||
return cfg.optionalMaintenance(ctx, cfg.Logger.Named("on_demand"), cert, hello)
|
||||
}
|
||||
return cert, nil
|
||||
}
|
||||
@ -302,20 +296,16 @@ func (cfg *Config) getCertDuringHandshake(hello *tls.ClientHelloInfo, loadIfNece
|
||||
loadedCert, err = cfg.CacheManagedCertificate(ctx, strings.Join(labels, "."))
|
||||
}
|
||||
if err == nil {
|
||||
if log != nil {
|
||||
log.Debug("loaded certificate from storage",
|
||||
zap.Strings("subjects", loadedCert.Names),
|
||||
zap.Bool("managed", loadedCert.managed),
|
||||
zap.Time("expiration", loadedCert.Leaf.NotAfter),
|
||||
zap.String("hash", loadedCert.hash))
|
||||
}
|
||||
log.Debug("loaded certificate from storage",
|
||||
zap.Strings("subjects", loadedCert.Names),
|
||||
zap.Bool("managed", loadedCert.managed),
|
||||
zap.Time("expiration", expiresAt(loadedCert.Leaf)),
|
||||
zap.String("hash", loadedCert.hash))
|
||||
loadedCert, err = cfg.handshakeMaintenance(ctx, hello, loadedCert)
|
||||
if err != nil {
|
||||
if log != nil {
|
||||
log.Error("maintaining newly-loaded certificate",
|
||||
zap.String("server_name", name),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Error("maintaining newly-loaded certificate",
|
||||
zap.String("server_name", name),
|
||||
zap.Error(err))
|
||||
}
|
||||
return loadedCert, nil
|
||||
}
|
||||
@ -327,27 +317,23 @@ func (cfg *Config) getCertDuringHandshake(hello *tls.ClientHelloInfo, loadIfNece
|
||||
|
||||
// Fall back to the default certificate if there is one
|
||||
if defaulted {
|
||||
if log != nil {
|
||||
log.Debug("fell back to default certificate",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
||||
zap.String("hash", cert.hash))
|
||||
}
|
||||
log.Debug("fell back to default certificate",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Bool("managed", cert.managed),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||
zap.String("hash", cert.hash))
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
if log != nil {
|
||||
log.Debug("no certificate matching TLS ClientHello",
|
||||
zap.String("server_name", hello.ServerName),
|
||||
zap.String("remote", hello.Conn.RemoteAddr().String()),
|
||||
zap.String("identifier", name),
|
||||
zap.Uint16s("cipher_suites", hello.CipherSuites),
|
||||
zap.Float64("cert_cache_fill", float64(cacheSize)/cacheCapacity), // may be approximate! because we are not within the lock
|
||||
zap.Bool("load_if_necessary", loadIfNecessary),
|
||||
zap.Bool("obtain_if_necessary", obtainIfNecessary),
|
||||
zap.Bool("on_demand", cfg.OnDemand != nil))
|
||||
}
|
||||
log.Debug("no certificate matching TLS ClientHello",
|
||||
zap.String("server_name", hello.ServerName),
|
||||
zap.String("remote", hello.Conn.RemoteAddr().String()),
|
||||
zap.String("identifier", name),
|
||||
zap.Uint16s("cipher_suites", hello.CipherSuites),
|
||||
zap.Float64("cert_cache_fill", float64(cacheSize)/cacheCapacity), // may be approximate! because we are not within the lock
|
||||
zap.Bool("load_if_necessary", loadIfNecessary),
|
||||
zap.Bool("obtain_if_necessary", obtainIfNecessary),
|
||||
zap.Bool("on_demand", cfg.OnDemand != nil))
|
||||
|
||||
return Certificate{}, fmt.Errorf("no certificate available for '%s'", name)
|
||||
}
|
||||
@ -361,12 +347,10 @@ func (cfg *Config) optionalMaintenance(ctx context.Context, log *zap.Logger, cer
|
||||
return newCert, nil
|
||||
}
|
||||
|
||||
if log != nil {
|
||||
log.Error("renewing certificate on-demand failed",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("not_after", cert.Leaf.NotAfter),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Error("renewing certificate on-demand failed",
|
||||
zap.Strings("subjects", cert.Names),
|
||||
zap.Time("not_after", expiresAt(cert.Leaf)),
|
||||
zap.Error(err))
|
||||
|
||||
if cert.Expired() {
|
||||
return cert, err
|
||||
@ -402,13 +386,13 @@ func (cfg *Config) checkIfCertShouldBeObtained(name string) error {
|
||||
//
|
||||
// This function is safe for use by multiple concurrent goroutines.
|
||||
func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.ClientHelloInfo) (Certificate, error) {
|
||||
log := loggerNamed(cfg.Logger, "on_demand")
|
||||
log := logWithRemote(cfg.Logger.Named("on_demand"), hello)
|
||||
|
||||
name := cfg.getNameFromClientHello(hello)
|
||||
|
||||
getCertWithoutReobtaining := func() (Certificate, error) {
|
||||
// very important to set the obtainIfNecessary argument to false, so we don't repeat this infinitely
|
||||
return cfg.getCertDuringHandshake(hello, true, false)
|
||||
return cfg.getCertDuringHandshake(ctx, hello, true, false)
|
||||
}
|
||||
|
||||
// We must protect this process from happening concurrently, so synchronize.
|
||||
@ -451,9 +435,7 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
|
||||
return Certificate{}, err
|
||||
}
|
||||
|
||||
if log != nil {
|
||||
log.Info("obtaining new certificate", zap.String("server_name", name))
|
||||
}
|
||||
log.Info("obtaining new certificate", zap.String("server_name", name))
|
||||
|
||||
// TODO: we are only adding a timeout because we don't know if the context passed in is actually cancelable...
|
||||
// (timeout duration is based on https://caddy.community/t/zerossl-dns-challenge-failing-often-route53-plugin/13822/24?u=matt)
|
||||
@ -485,35 +467,29 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
|
||||
//
|
||||
// This function is safe for use by multiple concurrent goroutines.
|
||||
func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHelloInfo, cert Certificate) (Certificate, error) {
|
||||
log := loggerNamed(cfg.Logger, "on_demand")
|
||||
log := cfg.Logger.Named("on_demand")
|
||||
|
||||
// Check OCSP staple validity
|
||||
if cert.ocsp != nil && !freshOCSP(cert.ocsp) {
|
||||
if log != nil {
|
||||
log.Debug("OCSP response needs refreshing",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||
}
|
||||
log.Debug("OCSP response needs refreshing",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||
|
||||
err := stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil)
|
||||
if err != nil {
|
||||
// An error with OCSP stapling is not the end of the world, and in fact, is
|
||||
// quite common considering not all certs have issuer URLs that support it.
|
||||
if log != nil {
|
||||
log.Warn("stapling OCSP",
|
||||
zap.String("server_name", hello.ServerName),
|
||||
zap.Error(err))
|
||||
}
|
||||
} else if log != nil {
|
||||
if log != nil {
|
||||
log.Debug("successfully stapled new OCSP response",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||
}
|
||||
log.Warn("stapling OCSP",
|
||||
zap.String("server_name", hello.ServerName),
|
||||
zap.Error(err))
|
||||
} else {
|
||||
log.Debug("successfully stapled new OCSP response",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||
}
|
||||
|
||||
// our copy of cert has the new OCSP staple, so replace it in the cache
|
||||
@ -525,19 +501,17 @@ func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHe
|
||||
// We attempt to replace any certificates that were revoked.
|
||||
// Crucially, this happens OUTSIDE a lock on the certCache.
|
||||
if certShouldBeForceRenewed(cert) {
|
||||
if log != nil {
|
||||
log.Warn("on-demand certificate's OCSP status is REVOKED; will try to forcefully renew",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||
zap.Time("revoked_at", cert.ocsp.RevokedAt),
|
||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||
}
|
||||
log.Warn("on-demand certificate's OCSP status is REVOKED; will try to forcefully renew",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||
zap.Time("revoked_at", cert.ocsp.RevokedAt),
|
||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||
return cfg.renewDynamicCertificate(ctx, hello, cert)
|
||||
}
|
||||
|
||||
// Check cert expiration
|
||||
if currentlyInRenewalWindow(cert.Leaf.NotBefore, cert.Leaf.NotAfter, cfg.RenewalWindowRatio) {
|
||||
if currentlyInRenewalWindow(cert.Leaf.NotBefore, expiresAt(cert.Leaf), cfg.RenewalWindowRatio) {
|
||||
return cfg.renewDynamicCertificate(ctx, hello, cert)
|
||||
}
|
||||
|
||||
@ -556,15 +530,15 @@ func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHe
|
||||
//
|
||||
// This function is safe for use by multiple concurrent goroutines.
|
||||
func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.ClientHelloInfo, currentCert Certificate) (Certificate, error) {
|
||||
log := loggerNamed(cfg.Logger, "on_demand")
|
||||
log := cfg.Logger.Named("on_demand")
|
||||
|
||||
name := cfg.getNameFromClientHello(hello)
|
||||
timeLeft := time.Until(currentCert.Leaf.NotAfter)
|
||||
timeLeft := time.Until(expiresAt(currentCert.Leaf))
|
||||
revoked := currentCert.ocsp != nil && currentCert.ocsp.Status == ocsp.Revoked
|
||||
|
||||
getCertWithoutReobtaining := func() (Certificate, error) {
|
||||
// very important to set the obtainIfNecessary argument to false, so we don't repeat this infinitely
|
||||
return cfg.getCertDuringHandshake(hello, true, false)
|
||||
return cfg.getCertDuringHandshake(ctx, hello, true, false)
|
||||
}
|
||||
|
||||
// see if another goroutine is already working on this certificate
|
||||
@ -578,23 +552,19 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
|
||||
// renewing it, so we might as well serve what we have without blocking, UNLESS
|
||||
// we're forcing renewal, in which case the current certificate is not usable
|
||||
if timeLeft > 0 && !revoked {
|
||||
if log != nil {
|
||||
log.Debug("certificate expires soon but is already being renewed; serving current certificate",
|
||||
zap.Strings("subjects", currentCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
}
|
||||
log.Debug("certificate expires soon but is already being renewed; serving current certificate",
|
||||
zap.Strings("subjects", currentCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
return currentCert, nil
|
||||
}
|
||||
|
||||
// otherwise, we'll have to wait for the renewal to finish so we don't serve
|
||||
// a revoked or expired certificate
|
||||
|
||||
if log != nil {
|
||||
log.Debug("certificate has expired, but is already being renewed; waiting for renewal to complete",
|
||||
zap.Strings("subjects", currentCert.Names),
|
||||
zap.Time("expired", currentCert.Leaf.NotAfter),
|
||||
zap.Bool("revoked", revoked))
|
||||
}
|
||||
log.Debug("certificate has expired, but is already being renewed; waiting for renewal to complete",
|
||||
zap.Strings("subjects", currentCert.Names),
|
||||
zap.Time("expired", expiresAt(currentCert.Leaf)),
|
||||
zap.Bool("revoked", revoked))
|
||||
|
||||
// TODO: see if we can get a proper context in here, for true cancellation
|
||||
timeout := time.NewTimer(2 * time.Minute)
|
||||
@ -620,30 +590,36 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
|
||||
obtainCertWaitChansMu.Unlock()
|
||||
}
|
||||
|
||||
if log != nil {
|
||||
log.Info("attempting certificate renewal",
|
||||
zap.String("server_name", name),
|
||||
zap.Strings("subjects", currentCert.Names),
|
||||
zap.Time("expiration", currentCert.Leaf.NotAfter),
|
||||
zap.Duration("remaining", timeLeft),
|
||||
zap.Bool("revoked", revoked))
|
||||
}
|
||||
|
||||
// Make sure a certificate for this name should be obtained on-demand
|
||||
err := cfg.checkIfCertShouldBeObtained(name)
|
||||
if err != nil {
|
||||
// if not, remove from cache (it will be deleted from storage later)
|
||||
cfg.certCache.mu.Lock()
|
||||
cfg.certCache.removeCertificate(currentCert)
|
||||
cfg.certCache.mu.Unlock()
|
||||
unblockWaiters()
|
||||
return Certificate{}, err
|
||||
}
|
||||
log = log.With(
|
||||
zap.String("server_name", name),
|
||||
zap.Strings("subjects", currentCert.Names),
|
||||
zap.Time("expiration", expiresAt(currentCert.Leaf)),
|
||||
zap.Duration("remaining", timeLeft),
|
||||
zap.Bool("revoked", revoked),
|
||||
)
|
||||
|
||||
// Renew and reload the certificate
|
||||
renewAndReload := func(ctx context.Context, cancel context.CancelFunc) (Certificate, error) {
|
||||
defer cancel()
|
||||
|
||||
log.Info("attempting certificate renewal")
|
||||
|
||||
// Make sure a certificate for this name should be obtained on-demand
|
||||
err := cfg.checkIfCertShouldBeObtained(name)
|
||||
if err != nil {
|
||||
// if not, remove from cache (it will be deleted from storage later)
|
||||
cfg.certCache.mu.Lock()
|
||||
cfg.certCache.removeCertificate(currentCert)
|
||||
cfg.certCache.mu.Unlock()
|
||||
unblockWaiters()
|
||||
|
||||
if log != nil {
|
||||
log.Error("certificate should not be obtained", zap.Error(err))
|
||||
}
|
||||
|
||||
return Certificate{}, err
|
||||
}
|
||||
|
||||
// otherwise, renew with issuer, etc.
|
||||
var newCert Certificate
|
||||
if revoked {
|
||||
@ -656,9 +632,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
|
||||
// make the replacement as atomic as possible.
|
||||
newCert, err = cfg.CacheManagedCertificate(ctx, name)
|
||||
if err != nil {
|
||||
if log != nil {
|
||||
log.Error("loading renewed certificate", zap.String("server_name", name), zap.Error(err))
|
||||
}
|
||||
log.Error("loading renewed certificate", zap.String("server_name", name), zap.Error(err))
|
||||
} else {
|
||||
// replace the old certificate with the new one
|
||||
cfg.certCache.replaceCertificate(currentCert, newCert)
|
||||
@ -672,12 +646,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
|
||||
unblockWaiters()
|
||||
|
||||
if err != nil {
|
||||
if log != nil {
|
||||
log.Error("renewing and reloading certificate",
|
||||
zap.String("server_name", name),
|
||||
zap.Error(err),
|
||||
zap.Bool("forced", revoked))
|
||||
}
|
||||
log.Error("renewing and reloading certificate", zap.Error(err))
|
||||
return newCert, err
|
||||
}
|
||||
|
||||
@ -723,9 +692,7 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
|
||||
}
|
||||
}
|
||||
if upstreamCert == nil {
|
||||
if log != nil {
|
||||
log.Debug("all external certificate managers yielded no certificates and no errors", zap.String("sni", hello.ServerName))
|
||||
}
|
||||
log.Debug("all external certificate managers yielded no certificates and no errors", zap.String("sni", hello.ServerName))
|
||||
return Certificate{}, nil
|
||||
}
|
||||
|
||||
@ -735,12 +702,10 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
|
||||
return Certificate{}, fmt.Errorf("external certificate manager: %s: filling cert from leaf: %v", hello.ServerName, err)
|
||||
}
|
||||
|
||||
if log != nil {
|
||||
log.Debug("using externally-managed certificate",
|
||||
zap.String("sni", hello.ServerName),
|
||||
zap.Strings("names", cert.Names),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter))
|
||||
}
|
||||
log.Debug("using externally-managed certificate",
|
||||
zap.String("sni", hello.ServerName),
|
||||
zap.Strings("names", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)))
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
@ -785,6 +750,20 @@ func (*Config) getNameFromClientHello(hello *tls.ClientHelloInfo) string {
|
||||
return localIPFromConn(hello.Conn)
|
||||
}
|
||||
|
||||
// logWithRemote adds the remote host and port to the logger.
|
||||
func logWithRemote(l *zap.Logger, hello *tls.ClientHelloInfo) *zap.Logger {
|
||||
if hello.Conn == nil || l == nil {
|
||||
return l
|
||||
}
|
||||
addr := hello.Conn.RemoteAddr().String()
|
||||
ip, port, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
ip = addr
|
||||
port = ""
|
||||
}
|
||||
return l.With(zap.String("remote_ip", ip), zap.String("remote_port", port))
|
||||
}
|
||||
|
||||
// localIPFromConn returns the host portion of c's local address
|
||||
// and strips the scope ID if one exists (see RFC 4007).
|
||||
func localIPFromConn(c net.Conn) string {
|
||||
|
||||
20
vendor/github.com/caddyserver/certmagic/httphandler.go
generated
vendored
20
vendor/github.com/caddyserver/certmagic/httphandler.go
generated
vendored
@ -73,11 +73,9 @@ func (am *ACMEIssuer) distributedHTTPChallengeSolver(w http.ResponseWriter, r *h
|
||||
host := hostOnly(r.Host)
|
||||
chalInfo, distributed, err := am.config.getChallengeInfo(r.Context(), host)
|
||||
if err != nil {
|
||||
if am.Logger != nil {
|
||||
am.Logger.Error("looking up info for HTTP challenge",
|
||||
zap.String("host", host),
|
||||
zap.Error(err))
|
||||
}
|
||||
am.Logger.Error("looking up info for HTTP challenge",
|
||||
zap.String("host", host),
|
||||
zap.Error(err))
|
||||
return false
|
||||
}
|
||||
return solveHTTPChallenge(am.Logger, w, r, chalInfo.Challenge, distributed)
|
||||
@ -95,13 +93,11 @@ func solveHTTPChallenge(logger *zap.Logger, w http.ResponseWriter, r *http.Reque
|
||||
w.Header().Add("Content-Type", "text/plain")
|
||||
w.Write([]byte(challenge.KeyAuthorization))
|
||||
r.Close = true
|
||||
if logger != nil {
|
||||
logger.Info("served key authentication",
|
||||
zap.String("identifier", challenge.Identifier.Value),
|
||||
zap.String("challenge", "http-01"),
|
||||
zap.String("remote", r.RemoteAddr),
|
||||
zap.Bool("distributed", distributed))
|
||||
}
|
||||
logger.Info("served key authentication",
|
||||
zap.String("identifier", challenge.Identifier.Value),
|
||||
zap.String("challenge", "http-01"),
|
||||
zap.String("remote", r.RemoteAddr),
|
||||
zap.Bool("distributed", distributed))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
169
vendor/github.com/caddyserver/certmagic/maintain.go
generated
vendored
169
vendor/github.com/caddyserver/certmagic/maintain.go
generated
vendored
@ -39,18 +39,14 @@ import (
|
||||
// incrementing panicCount each time. Initial invocation should
|
||||
// start panicCount at 0.
|
||||
func (certCache *Cache) maintainAssets(panicCount int) {
|
||||
log := loggerNamed(certCache.logger, "maintenance")
|
||||
if log != nil {
|
||||
log = log.With(zap.String("cache", fmt.Sprintf("%p", certCache)))
|
||||
}
|
||||
log := certCache.logger.Named("maintenance")
|
||||
log = log.With(zap.String("cache", fmt.Sprintf("%p", certCache)))
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
buf := make([]byte, stackTraceBufferSize)
|
||||
buf = buf[:runtime.Stack(buf, false)]
|
||||
if log != nil {
|
||||
log.Error("panic", zap.Any("error", err), zap.ByteString("stack", buf))
|
||||
}
|
||||
log.Error("panic", zap.Any("error", err), zap.ByteString("stack", buf))
|
||||
if panicCount < 10 {
|
||||
certCache.maintainAssets(panicCount + 1)
|
||||
}
|
||||
@ -60,9 +56,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||
renewalTicker := time.NewTicker(certCache.options.RenewCheckInterval)
|
||||
ocspTicker := time.NewTicker(certCache.options.OCSPCheckInterval)
|
||||
|
||||
if log != nil {
|
||||
log.Info("started background certificate maintenance")
|
||||
}
|
||||
log.Info("started background certificate maintenance")
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
@ -71,7 +65,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||
select {
|
||||
case <-renewalTicker.C:
|
||||
err := certCache.RenewManagedCertificates(ctx)
|
||||
if err != nil && log != nil {
|
||||
if err != nil {
|
||||
log.Error("renewing managed certificates", zap.Error(err))
|
||||
}
|
||||
case <-ocspTicker.C:
|
||||
@ -79,9 +73,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||
case <-certCache.stopChan:
|
||||
renewalTicker.Stop()
|
||||
ocspTicker.Stop()
|
||||
if log != nil {
|
||||
log.Info("stopped background certificate maintenance")
|
||||
}
|
||||
log.Info("stopped background certificate maintenance")
|
||||
close(certCache.doneChan)
|
||||
return
|
||||
}
|
||||
@ -94,7 +86,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||
// need to call this. This method assumes non-interactive
|
||||
// mode (i.e. operating in the background).
|
||||
func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||
log := loggerNamed(certCache.logger, "maintenance")
|
||||
log := certCache.logger.Named("maintenance")
|
||||
|
||||
// configs will hold a map of certificate name to the config
|
||||
// to use when managing that certificate
|
||||
@ -116,9 +108,7 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||
|
||||
// the list of names on this cert should never be empty... programmer error?
|
||||
if cert.Names == nil || len(cert.Names) == 0 {
|
||||
if log != nil {
|
||||
log.Warn("certificate has no names; removing from cache", zap.String("cert_key", certKey))
|
||||
}
|
||||
log.Warn("certificate has no names; removing from cache", zap.String("cert_key", certKey))
|
||||
deleteQueue = append(deleteQueue, cert)
|
||||
continue
|
||||
}
|
||||
@ -126,19 +116,15 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||
// get the config associated with this certificate
|
||||
cfg, err := certCache.getConfig(cert)
|
||||
if err != nil {
|
||||
if log != nil {
|
||||
log.Error("unable to get configuration to manage certificate; unable to renew",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Error("unable to get configuration to manage certificate; unable to renew",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
if cfg == nil {
|
||||
// this is bad if this happens, probably a programmer error (oops)
|
||||
if log != nil {
|
||||
log.Error("no configuration associated with certificate; unable to manage",
|
||||
zap.Strings("identifiers", cert.Names))
|
||||
}
|
||||
log.Error("no configuration associated with certificate; unable to manage",
|
||||
zap.Strings("identifiers", cert.Names))
|
||||
continue
|
||||
}
|
||||
if cfg.OnDemand != nil {
|
||||
@ -156,11 +142,9 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||
storedCertExpiring, err := cfg.managedCertInStorageExpiresSoon(ctx, cert)
|
||||
if err != nil {
|
||||
// hmm, weird, but not a big deal, maybe it was deleted or something
|
||||
if log != nil {
|
||||
log.Warn("error while checking if stored certificate is also expiring soon",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Warn("error while checking if stored certificate is also expiring soon",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
} else if !storedCertExpiring {
|
||||
// if the certificate is NOT expiring soon and there was no error, then we
|
||||
// are good to just reload the certificate from storage instead of repeating
|
||||
@ -180,23 +164,19 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||
|
||||
// Reload certificates that merely need to be updated in memory
|
||||
for _, oldCert := range reloadQueue {
|
||||
timeLeft := oldCert.Leaf.NotAfter.Sub(time.Now().UTC())
|
||||
if log != nil {
|
||||
log.Info("certificate expires soon, but is already renewed in storage; reloading stored certificate",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
}
|
||||
timeLeft := expiresAt(oldCert.Leaf).Sub(time.Now().UTC())
|
||||
log.Info("certificate expires soon, but is already renewed in storage; reloading stored certificate",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
|
||||
cfg := configs[oldCert.Names[0]]
|
||||
|
||||
// crucially, this happens OUTSIDE a lock on the certCache
|
||||
_, err := cfg.reloadManagedCertificate(ctx, oldCert)
|
||||
if err != nil {
|
||||
if log != nil {
|
||||
log.Error("loading renewed certificate",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Error("loading renewed certificate",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -206,11 +186,9 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||
cfg := configs[oldCert.Names[0]]
|
||||
err := certCache.queueRenewalTask(ctx, oldCert, cfg)
|
||||
if err != nil {
|
||||
if log != nil {
|
||||
log.Error("queueing renewal task",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
log.Error("queueing renewal task",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -226,14 +204,12 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (certCache *Cache) queueRenewalTask(ctx context.Context, oldCert Certificate, cfg *Config) error {
|
||||
log := loggerNamed(certCache.logger, "maintenance")
|
||||
log := certCache.logger.Named("maintenance")
|
||||
|
||||
timeLeft := oldCert.Leaf.NotAfter.Sub(time.Now().UTC())
|
||||
if log != nil {
|
||||
log.Info("certificate expires soon; queuing for renewal",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
}
|
||||
timeLeft := expiresAt(oldCert.Leaf).Sub(time.Now().UTC())
|
||||
log.Info("certificate expires soon; queuing for renewal",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
|
||||
// Get the name which we should use to renew this certificate;
|
||||
// we only support managing certificates with one name per cert,
|
||||
@ -242,12 +218,10 @@ func (certCache *Cache) queueRenewalTask(ctx context.Context, oldCert Certificat
|
||||
|
||||
// queue up this renewal job (is a no-op if already active or queued)
|
||||
jm.Submit(cfg.Logger, "renew_"+renewName, func() error {
|
||||
timeLeft := oldCert.Leaf.NotAfter.Sub(time.Now().UTC())
|
||||
if log != nil {
|
||||
log.Info("attempting certificate renewal",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
}
|
||||
timeLeft := expiresAt(oldCert.Leaf).Sub(time.Now().UTC())
|
||||
log.Info("attempting certificate renewal",
|
||||
zap.Strings("identifiers", oldCert.Names),
|
||||
zap.Duration("remaining", timeLeft))
|
||||
|
||||
// perform renewal - crucially, this happens OUTSIDE a lock on certCache
|
||||
err := cfg.RenewCertAsync(ctx, renewName, false)
|
||||
@ -280,7 +254,7 @@ func (certCache *Cache) queueRenewalTask(ctx context.Context, oldCert Certificat
|
||||
// Ryan Sleevi's recommendations for good OCSP support:
|
||||
// https://gist.github.com/sleevi/5efe9ef98961ecfb4da8
|
||||
func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||
logger := loggerNamed(certCache.logger, "maintenance")
|
||||
logger := certCache.logger.Named("maintenance")
|
||||
|
||||
// temporary structures to store updates or tasks
|
||||
// so that we can keep our locks short-lived
|
||||
@ -311,11 +285,9 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||
}
|
||||
cfg, err := certCache.getConfig(cert)
|
||||
if err != nil {
|
||||
if logger != nil {
|
||||
logger.Error("unable to get automation config for certificate; maintenance for this certificate will likely fail",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
logger.Error("unable to get automation config for certificate; maintenance for this certificate will likely fail",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
// always try to replace revoked certificates, even if OCSP response is still fresh
|
||||
@ -347,10 +319,8 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||
|
||||
if qe.cfg == nil {
|
||||
// this is bad if this happens, probably a programmer error (oops)
|
||||
if logger != nil {
|
||||
logger.Error("no configuration associated with certificate; unable to manage OCSP staples",
|
||||
zap.Strings("identifiers", cert.Names))
|
||||
}
|
||||
logger.Error("no configuration associated with certificate; unable to manage OCSP staples",
|
||||
zap.Strings("identifiers", cert.Names))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -358,11 +328,9 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||
if err != nil {
|
||||
if cert.ocsp != nil {
|
||||
// if there was no staple before, that's fine; otherwise we should log the error
|
||||
if logger != nil {
|
||||
logger.Error("stapling OCSP",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
logger.Error("stapling OCSP",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
@ -372,17 +340,22 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||
// sure we apply the update to all names on the certificate if
|
||||
// the status is still Good.
|
||||
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Good && (lastNextUpdate.IsZero() || lastNextUpdate != cert.ocsp.NextUpdate) {
|
||||
if logger != nil {
|
||||
logger.Info("advancing OCSP staple",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Time("from", lastNextUpdate),
|
||||
zap.Time("to", cert.ocsp.NextUpdate))
|
||||
}
|
||||
logger.Info("advancing OCSP staple",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Time("from", lastNextUpdate),
|
||||
zap.Time("to", cert.ocsp.NextUpdate))
|
||||
updated[certHash] = ocspUpdate{rawBytes: cert.Certificate.OCSPStaple, parsed: cert.ocsp}
|
||||
}
|
||||
|
||||
// If the updated staple shows that the certificate was revoked, we should immediately renew it
|
||||
if certShouldBeForceRenewed(cert) {
|
||||
qe.cfg.emit(ctx, "cert_ocsp_revoked", map[string]any{
|
||||
"subjects": cert.Names,
|
||||
"certificate": cert,
|
||||
"reason": cert.ocsp.RevocationReason,
|
||||
"revoked_at": cert.ocsp.RevokedAt,
|
||||
})
|
||||
|
||||
renewQueue = append(renewQueue, renewQueueEntry{
|
||||
oldCert: cert,
|
||||
cfg: qe.cfg,
|
||||
@ -405,7 +378,7 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||
// Crucially, this happens OUTSIDE a lock on the certCache.
|
||||
for _, renew := range renewQueue {
|
||||
_, err := renew.cfg.forceRenew(ctx, logger, renew.oldCert)
|
||||
if err != nil && logger != nil {
|
||||
if err != nil {
|
||||
logger.Info("forcefully renewing certificate due to REVOKED status",
|
||||
zap.Strings("identifiers", renew.oldCert.Names),
|
||||
zap.Error(err))
|
||||
@ -522,7 +495,7 @@ func deleteExpiredCerts(ctx context.Context, storage Storage, gracePeriod time.D
|
||||
return fmt.Errorf("certificate file %s is malformed; error parsing PEM: %v", assetKey, err)
|
||||
}
|
||||
|
||||
if expiredTime := time.Since(cert.NotAfter); expiredTime >= gracePeriod {
|
||||
if expiredTime := time.Since(expiresAt(cert)); expiredTime >= gracePeriod {
|
||||
log.Printf("[INFO] Certificate %s expired %s ago; cleaning up", assetKey, expiredTime)
|
||||
baseName := strings.TrimSuffix(assetKey, ".crt")
|
||||
for _, relatedAsset := range []string{
|
||||
@ -560,16 +533,14 @@ func deleteExpiredCerts(ctx context.Context, storage Storage, gracePeriod time.D
|
||||
// forceRenew forcefully renews cert and replaces it in the cache, and returns the new certificate. It is intended
|
||||
// for use primarily in the case of cert revocation. This MUST NOT be called within a lock on cfg.certCacheMu.
|
||||
func (cfg *Config) forceRenew(ctx context.Context, logger *zap.Logger, cert Certificate) (Certificate, error) {
|
||||
if logger != nil {
|
||||
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Revoked {
|
||||
logger.Warn("OCSP status for managed certificate is REVOKED; attempting to replace with new certificate",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter))
|
||||
} else {
|
||||
logger.Warn("forcefully renewing certificate",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Time("expiration", cert.Leaf.NotAfter))
|
||||
}
|
||||
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Revoked {
|
||||
logger.Warn("OCSP status for managed certificate is REVOKED; attempting to replace with new certificate",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)))
|
||||
} else {
|
||||
logger.Warn("forcefully renewing certificate",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Time("expiration", expiresAt(cert.Leaf)))
|
||||
}
|
||||
|
||||
renewName := cert.Names[0]
|
||||
@ -584,7 +555,7 @@ func (cfg *Config) forceRenew(ctx context.Context, logger *zap.Logger, cert Cert
|
||||
var obtainInsteadOfRenew bool
|
||||
if cert.ocsp != nil && cert.ocsp.RevocationReason == acme.ReasonKeyCompromise {
|
||||
err := cfg.moveCompromisedPrivateKey(ctx, cert, logger)
|
||||
if err != nil && logger != nil {
|
||||
if err != nil {
|
||||
logger.Error("could not remove compromised private key from use",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.String("issuer", cert.issuerKey),
|
||||
@ -605,11 +576,9 @@ func (cfg *Config) forceRenew(ctx context.Context, logger *zap.Logger, cert Cert
|
||||
if err != nil {
|
||||
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Revoked {
|
||||
// probably better to not serve a revoked certificate at all
|
||||
if logger != nil {
|
||||
logger.Error("unable to obtain new to certificate after OCSP status of REVOKED; removing from cache",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
}
|
||||
logger.Error("unable to obtain new to certificate after OCSP status of REVOKED; removing from cache",
|
||||
zap.Strings("identifiers", cert.Names),
|
||||
zap.Error(err))
|
||||
cfg.certCache.mu.Lock()
|
||||
cfg.certCache.removeCertificate(cert)
|
||||
cfg.certCache.mu.Unlock()
|
||||
|
||||
4
vendor/github.com/caddyserver/certmagic/ocsp.go
generated
vendored
4
vendor/github.com/caddyserver/certmagic/ocsp.go
generated
vendored
@ -98,12 +98,12 @@ func stapleOCSP(ctx context.Context, ocspConfig OCSPConfig, storage Storage, cer
|
||||
gotNewOCSP = true
|
||||
}
|
||||
|
||||
if ocspResp.NextUpdate.After(cert.Leaf.NotAfter) {
|
||||
if ocspResp.NextUpdate.After(expiresAt(cert.Leaf)) {
|
||||
// uh oh, this OCSP response expires AFTER the certificate does, that's kinda bogus.
|
||||
// it was the reason a lot of Symantec-validated sites (not Caddy) went down
|
||||
// in October 2017. https://twitter.com/mattiasgeniar/status/919432824708648961
|
||||
return fmt.Errorf("invalid: OCSP response for %v valid after certificate expiration (%s)",
|
||||
cert.Names, cert.Leaf.NotAfter.Sub(ocspResp.NextUpdate))
|
||||
cert.Names, expiresAt(cert.Leaf).Sub(ocspResp.NextUpdate))
|
||||
}
|
||||
|
||||
// Attach the latest OCSP response to the certificate; this is NOT the same
|
||||
|
||||
30
vendor/github.com/caddyserver/certmagic/solvers.go
generated
vendored
30
vendor/github.com/caddyserver/certmagic/solvers.go
generated
vendored
@ -99,7 +99,7 @@ func (s *httpSolver) serve(ctx context.Context, si *solverInfo) {
|
||||
}
|
||||
|
||||
// CleanUp cleans up the HTTP server if it is the last one to finish.
|
||||
func (s *httpSolver) CleanUp(ctx context.Context, _ acme.Challenge) error {
|
||||
func (s *httpSolver) CleanUp(_ context.Context, _ acme.Challenge) error {
|
||||
solversMu.Lock()
|
||||
defer solversMu.Unlock()
|
||||
si := getSolverInfo(s.address)
|
||||
@ -220,7 +220,7 @@ func (*tlsALPNSolver) handleConn(conn net.Conn) {
|
||||
|
||||
// CleanUp removes the challenge certificate from the cache, and if
|
||||
// it is the last one to finish, stops the TLS server.
|
||||
func (s *tlsALPNSolver) CleanUp(ctx context.Context, chal acme.Challenge) error {
|
||||
func (s *tlsALPNSolver) CleanUp(_ context.Context, chal acme.Challenge) error {
|
||||
solversMu.Lock()
|
||||
defer solversMu.Unlock()
|
||||
si := getSolverInfo(s.address)
|
||||
@ -234,7 +234,6 @@ func (s *tlsALPNSolver) CleanUp(ctx context.Context, chal acme.Challenge) error
|
||||
}
|
||||
delete(solvers, s.address)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -357,7 +356,7 @@ func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error
|
||||
// timings
|
||||
timeout := s.PropagationTimeout
|
||||
if timeout == 0 {
|
||||
timeout = 2 * time.Minute
|
||||
timeout = defaultDNSPropagationTimeout
|
||||
}
|
||||
const interval = 2 * time.Second
|
||||
|
||||
@ -386,7 +385,12 @@ func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error
|
||||
}
|
||||
|
||||
// CleanUp deletes the DNS TXT record created in Present().
|
||||
func (s *DNS01Solver) CleanUp(ctx context.Context, challenge acme.Challenge) error {
|
||||
//
|
||||
// We ignore the context because cleanup is often/likely performed after
|
||||
// a context cancellation, and properly-implemented DNS providers should
|
||||
// honor cancellation, which would result in cleanup being aborted.
|
||||
// Cleanup must always occur.
|
||||
func (s *DNS01Solver) CleanUp(_ context.Context, challenge acme.Challenge) error {
|
||||
dnsName := challenge.DNS01TXTRecordName()
|
||||
if s.OverrideDomain != "" {
|
||||
dnsName = s.OverrideDomain
|
||||
@ -402,7 +406,17 @@ func (s *DNS01Solver) CleanUp(ctx context.Context, challenge acme.Challenge) err
|
||||
return err
|
||||
}
|
||||
|
||||
// clean up the record
|
||||
// clean up the record - use a different context though, since
|
||||
// one common reason cleanup is performed is because a context
|
||||
// was canceled, and if so, any HTTP requests by this provider
|
||||
// should fail if the provider is properly implemented
|
||||
// (see issue #200)
|
||||
timeout := s.PropagationTimeout
|
||||
if timeout <= 0 {
|
||||
timeout = defaultDNSPropagationTimeout
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
_, err = s.DNSProvider.DeleteRecords(ctx, memory.dnsZone, []libdns.Record{memory.rec})
|
||||
if err != nil {
|
||||
return fmt.Errorf("deleting temporary record for name %q in zone %q: %w", memory.dnsName, memory.dnsZone, err)
|
||||
@ -411,6 +425,8 @@ func (s *DNS01Solver) CleanUp(ctx context.Context, challenge acme.Challenge) err
|
||||
return nil
|
||||
}
|
||||
|
||||
const defaultDNSPropagationTimeout = 2 * time.Minute
|
||||
|
||||
type dnsPresentMemory struct {
|
||||
dnsZone string
|
||||
dnsName string
|
||||
@ -680,7 +696,7 @@ var (
|
||||
// data that can make it easier or more efficient to solve.
|
||||
type Challenge struct {
|
||||
acme.Challenge
|
||||
data interface{}
|
||||
data any
|
||||
}
|
||||
|
||||
// challengeKey returns the map key for a given challenge; it is the identifier
|
||||
|
||||
63
vendor/github.com/caddyserver/certmagic/storage.go
generated
vendored
63
vendor/github.com/caddyserver/certmagic/storage.go
generated
vendored
@ -29,19 +29,30 @@ import (
|
||||
// Keys are prefix-based, with forward slash '/' as separators
|
||||
// and without a leading slash.
|
||||
//
|
||||
// Processes running in a cluster will wish to use the
|
||||
// same Storage value (its implementation and configuration)
|
||||
// in order to share certificates and other TLS resources
|
||||
// with the cluster.
|
||||
// Processes running in a cluster should use the same Storage
|
||||
// value (with the same configuration) in order to share
|
||||
// certificates and other TLS resources with the cluster.
|
||||
//
|
||||
// The Load, Delete, List, and Stat methods should return
|
||||
// fs.ErrNotExist if the key does not exist.
|
||||
//
|
||||
// Implementations of Storage must be safe for concurrent use
|
||||
// and honor context cancellations.
|
||||
// and honor context cancellations. Methods should block until
|
||||
// their operation is complete; that is, Load() should always
|
||||
// return the value from the last call to Store() for a given
|
||||
// key, and concurrent calls to Store() should not corrupt a
|
||||
// file.
|
||||
//
|
||||
// For simplicity, this is not a streaming API and is not
|
||||
// suitable for very large files.
|
||||
type Storage interface {
|
||||
// Locker provides atomic synchronization
|
||||
// operations, making Storage safe to share.
|
||||
// The use of Locker is not expected around
|
||||
// every other method (Store, Load, etc.)
|
||||
// as those should already be thread-safe;
|
||||
// Locker is intended for custom jobs or
|
||||
// transactions that need synchronization.
|
||||
Locker
|
||||
|
||||
// Store puts value at key.
|
||||
@ -70,10 +81,11 @@ type Storage interface {
|
||||
Stat(ctx context.Context, key string) (KeyInfo, error)
|
||||
}
|
||||
|
||||
// Locker facilitates synchronization of certificate tasks across
|
||||
// machines and networks.
|
||||
// Locker facilitates synchronization across machines and networks.
|
||||
// It essentially provides a distributed named-mutex service so
|
||||
// that multiple consumers can coordinate tasks and share resources.
|
||||
type Locker interface {
|
||||
// Lock acquires the lock for key, blocking until the lock
|
||||
// Lock acquires the lock for name, blocking until the lock
|
||||
// can be obtained or an error is returned. Note that, even
|
||||
// after acquiring a lock, an idempotent operation may have
|
||||
// already been performed by another process that acquired
|
||||
@ -86,20 +98,25 @@ type Locker interface {
|
||||
// same time always results in only one caller receiving the
|
||||
// lock at any given time.
|
||||
//
|
||||
// To prevent deadlocks, all implementations (where this concern
|
||||
// is relevant) should put a reasonable expiration on the lock in
|
||||
// case Unlock is unable to be called due to some sort of network
|
||||
// failure or system crash. Additionally, implementations should
|
||||
// honor context cancellation as much as possible (in case the
|
||||
// caller wishes to give up and free resources before the lock
|
||||
// can be obtained).
|
||||
Lock(ctx context.Context, key string) error
|
||||
// To prevent deadlocks, all implementations should put a
|
||||
// reasonable expiration on the lock in case Unlock is unable
|
||||
// to be called due to some sort of network failure or system
|
||||
// crash. Additionally, implementations should honor context
|
||||
// cancellation as much as possible (in case the caller wishes
|
||||
// to give up and free resources before the lock can be obtained).
|
||||
//
|
||||
// Additionally, implementations may wish to support fencing
|
||||
// tokens (https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html)
|
||||
// in order to be robust against long process pauses, extremely
|
||||
// high network latency (or other factors that get in the way of
|
||||
// renewing lock leases).
|
||||
Lock(ctx context.Context, name string) error
|
||||
|
||||
// Unlock releases the lock for key. This method must ONLY be
|
||||
// Unlock releases the lock for name. This method must ONLY be
|
||||
// called after a successful call to Lock, and only after the
|
||||
// critical section is finished, even if it errored or timed
|
||||
// out. Unlock cleans up any resources allocated during Lock.
|
||||
Unlock(ctx context.Context, key string) error
|
||||
Unlock(ctx context.Context, name string) error
|
||||
}
|
||||
|
||||
// KeyInfo holds information about a key in storage.
|
||||
@ -220,16 +237,14 @@ func CleanUpOwnLocks(ctx context.Context, logger *zap.Logger) {
|
||||
locksMu.Lock()
|
||||
defer locksMu.Unlock()
|
||||
for lockKey, storage := range locks {
|
||||
err := storage.Unlock(ctx, lockKey)
|
||||
if err == nil {
|
||||
delete(locks, lockKey)
|
||||
} else if logger != nil {
|
||||
if err := storage.Unlock(ctx, lockKey); err != nil {
|
||||
logger.Error("unable to clean up lock in storage backend",
|
||||
zap.Any("storage", storage),
|
||||
zap.String("lock_key", lockKey),
|
||||
zap.Error(err),
|
||||
)
|
||||
zap.Error(err))
|
||||
continue
|
||||
}
|
||||
delete(locks, lockKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/datarhei/gosrt/Makefile
generated
vendored
2
vendor/github.com/datarhei/gosrt/Makefile
generated
vendored
@ -5,7 +5,7 @@ all: build
|
||||
|
||||
## test: Run all tests
|
||||
test:
|
||||
go test -race -coverprofile=/dev/null -timeout 60s -v ./...
|
||||
go test -race -coverprofile=/dev/null -v ./...
|
||||
|
||||
## vet: Analyze code for potential errors
|
||||
vet:
|
||||
|
||||
195
vendor/github.com/datarhei/gosrt/connection.go
generated
vendored
195
vendor/github.com/datarhei/gosrt/connection.go
generated
vendored
@ -53,7 +53,7 @@ type Conn interface {
|
||||
StreamId() string
|
||||
|
||||
// Stats returns accumulated and instantaneous statistics of the connection.
|
||||
Stats() Statistics
|
||||
Stats(s *Statistics)
|
||||
}
|
||||
|
||||
type connStats struct {
|
||||
@ -73,6 +73,7 @@ type connStats struct {
|
||||
pktRecvKeepalive uint64
|
||||
pktSentShutdown uint64
|
||||
pktRecvShutdown uint64
|
||||
mbpsLinkCapacity float64
|
||||
}
|
||||
|
||||
// Check if we implement the net.Conn interface
|
||||
@ -118,6 +119,8 @@ type srtConn struct {
|
||||
tsbpdTimeBaseOffset uint64 // microseconds
|
||||
tsbpdDelay uint64 // microseconds
|
||||
tsbpdDrift uint64 // microseconds
|
||||
peerTsbpdDelay uint64 // microseconds
|
||||
dropThreshold uint64 // microseconds
|
||||
|
||||
// Queue for packets that are coming from the network
|
||||
networkQueue chan packet.Packet
|
||||
@ -162,7 +165,8 @@ type srtConnConfig struct {
|
||||
socketId uint32
|
||||
peerSocketId uint32
|
||||
tsbpdTimeBase uint64 // microseconds
|
||||
tsbpdDelay uint64
|
||||
tsbpdDelay uint64 // microseconds
|
||||
peerTsbpdDelay uint64 // microseconds
|
||||
initialPacketSequenceNumber circular.Number
|
||||
crypto crypto.Crypto
|
||||
keyBaseEncryption packet.PacketEncryption
|
||||
@ -181,6 +185,7 @@ func newSRTConn(config srtConnConfig) *srtConn {
|
||||
peerSocketId: config.peerSocketId,
|
||||
tsbpdTimeBase: config.tsbpdTimeBase,
|
||||
tsbpdDelay: config.tsbpdDelay,
|
||||
peerTsbpdDelay: config.peerTsbpdDelay,
|
||||
initialPacketSequenceNumber: config.initialPacketSequenceNumber,
|
||||
crypto: config.crypto,
|
||||
keyBaseEncryption: config.keyBaseEncryption,
|
||||
@ -237,9 +242,16 @@ func newSRTConn(config srtConnConfig) *srtConn {
|
||||
})
|
||||
|
||||
// 4.6. Too-Late Packet Drop -> 125% of SRT latency, at least 1 second
|
||||
// https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#SRTO_SNDDROPDELAY
|
||||
c.dropThreshold = uint64(float64(c.peerTsbpdDelay)*1.25) + uint64(c.config.SendDropDelay.Microseconds())
|
||||
if c.dropThreshold < uint64(time.Second.Microseconds()) {
|
||||
c.dropThreshold = uint64(time.Second.Microseconds())
|
||||
}
|
||||
c.dropThreshold += 20_000
|
||||
|
||||
c.snd = congestion.NewLiveSend(congestion.SendConfig{
|
||||
InitialSequenceNumber: c.initialPacketSequenceNumber,
|
||||
DropInterval: uint64(c.config.SendDropDelay.Microseconds()),
|
||||
DropThreshold: c.dropThreshold,
|
||||
MaxBW: c.config.MaxBW,
|
||||
InputBW: c.config.InputBW,
|
||||
MinInputBW: c.config.MinInputBW,
|
||||
@ -582,6 +594,8 @@ func (c *srtConn) handlePacket(p packet.Packet) {
|
||||
|
||||
c.debug.expectedRcvPacketSequenceNumber = header.PacketSequenceNumber.Inc()
|
||||
|
||||
//fmt.Printf("%s\n", p.String())
|
||||
|
||||
// Ignore FEC filter control packets
|
||||
// https://github.com/Haivision/srt/blob/master/docs/features/packet-filtering-and-fec.md
|
||||
// "An FEC control packet is distinguished from a regular data packet by having
|
||||
@ -682,6 +696,9 @@ func (c *srtConn) handleACK(p packet.Packet) {
|
||||
// 4.10. Round-Trip Time Estimation
|
||||
c.recalculateRTT(time.Duration(int64(cif.RTT)) * time.Microsecond)
|
||||
|
||||
// Estimated Link Capacity (from packets/s to Mbps)
|
||||
c.statistics.mbpsLinkCapacity = float64(cif.EstimatedLinkCapacity) * MAX_PAYLOAD_SIZE * 8 / 1024 / 1024
|
||||
|
||||
c.sendACKACK(p.Header().TypeSpecific)
|
||||
}
|
||||
}
|
||||
@ -901,14 +918,14 @@ func (c *srtConn) sendACK(seq circular.Number, lite bool) {
|
||||
|
||||
p.Header().TypeSpecific = 0
|
||||
} else {
|
||||
pps, _ := c.recv.PacketRate()
|
||||
pps, bps, capacity := c.recv.PacketRate()
|
||||
|
||||
cif.RTT = uint32(c.rtt)
|
||||
cif.RTTVar = uint32(c.rttVar)
|
||||
cif.AvailableBufferSize = c.config.FC // TODO: available buffer size (packets)
|
||||
cif.PacketsReceivingRate = pps // packets receiving rate (packets/s)
|
||||
cif.EstimatedLinkCapacity = 0 // estimated link capacity (packets/s), not relevant for live mode
|
||||
cif.ReceivingRate = 0 // receiving rate (bytes/s), not relevant for live mode
|
||||
cif.AvailableBufferSize = c.config.FC // TODO: available buffer size (packets)
|
||||
cif.PacketsReceivingRate = uint32(pps) // packets receiving rate (packets/s)
|
||||
cif.EstimatedLinkCapacity = uint32(capacity) // estimated link capacity (packets/s), not relevant for live mode
|
||||
cif.ReceivingRate = uint32(bps) // receiving rate (bytes/s), not relevant for live mode
|
||||
|
||||
p.Header().TypeSpecific = c.nextACKNumber.Val()
|
||||
|
||||
@ -1049,63 +1066,119 @@ func (c *srtConn) SetDeadline(t time.Time) error { return nil }
|
||||
func (c *srtConn) SetReadDeadline(t time.Time) error { return nil }
|
||||
func (c *srtConn) SetWriteDeadline(t time.Time) error { return nil }
|
||||
|
||||
func (c *srtConn) Stats() Statistics {
|
||||
func (c *srtConn) Stats(s *Statistics) {
|
||||
now := uint64(time.Since(c.start).Milliseconds())
|
||||
|
||||
send := c.snd.Stats()
|
||||
recv := c.recv.Stats()
|
||||
|
||||
s := Statistics{
|
||||
MsTimeStamp: uint64(time.Since(c.start).Milliseconds()),
|
||||
previous := s.Accumulated
|
||||
interval := now - s.MsTimeStamp
|
||||
|
||||
// Accumulated
|
||||
PktSent: send.PktSent,
|
||||
PktRecv: recv.PktRecv,
|
||||
PktSentUnique: send.PktSentUnique,
|
||||
PktRecvUnique: recv.PktRecvUnique,
|
||||
PktSndLoss: send.PktSndLoss,
|
||||
PktRcvLoss: recv.PktRcvLoss,
|
||||
PktRetrans: send.PktRetrans,
|
||||
PktRcvRetrans: recv.PktRcvRetrans,
|
||||
PktSentACK: c.statistics.pktSentACK,
|
||||
PktRecvACK: c.statistics.pktRecvACK,
|
||||
PktSentNAK: c.statistics.pktSentNAK,
|
||||
PktRecvNAK: c.statistics.pktRecvNAK,
|
||||
PktSentKM: c.statistics.pktSentKM,
|
||||
PktRecvKM: c.statistics.pktRecvKM,
|
||||
UsSndDuration: send.UsSndDuration,
|
||||
PktSndDrop: send.PktSndDrop,
|
||||
PktRcvDrop: recv.PktRcvDrop,
|
||||
PktRcvUndecrypt: c.statistics.pktRecvUndecrypt,
|
||||
ByteSent: send.ByteSent + (send.PktSent * c.statistics.headerSize),
|
||||
ByteRecv: recv.ByteRecv + (recv.PktRecv * c.statistics.headerSize),
|
||||
ByteSentUnique: send.ByteSentUnique + (send.PktSentUnique * c.statistics.headerSize),
|
||||
ByteRecvUnique: recv.ByteRecvUnique + (recv.PktRecvUnique * c.statistics.headerSize),
|
||||
ByteRcvLoss: recv.ByteRcvLoss + (recv.PktRcvLoss * c.statistics.headerSize),
|
||||
ByteRetrans: send.ByteRetrans + (send.PktRetrans * c.statistics.headerSize),
|
||||
ByteSndDrop: send.ByteSndDrop + (send.PktSndDrop * c.statistics.headerSize),
|
||||
ByteRcvDrop: recv.ByteRcvDrop + (recv.PktRcvDrop * c.statistics.headerSize),
|
||||
ByteRcvUndecrypt: c.statistics.byteRecvUndecrypt + (c.statistics.pktRecvUndecrypt * c.statistics.headerSize),
|
||||
|
||||
// Instantaneous
|
||||
UsPktSndPeriod: send.UsPktSndPeriod,
|
||||
PktFlowWindow: uint64(c.config.FC),
|
||||
PktFlightSize: send.PktFlightSize,
|
||||
MsRTT: c.rtt / 1_000,
|
||||
MbpsBandwidth: 0,
|
||||
ByteAvailSndBuf: 0,
|
||||
ByteAvailRcvBuf: 0,
|
||||
MbpsMaxBW: float64(c.config.MaxBW / 1024 / 1024),
|
||||
ByteMSS: uint64(c.config.MSS),
|
||||
PktSndBuf: send.PktSndBuf,
|
||||
ByteSndBuf: send.ByteSndBuf,
|
||||
MsSndBuf: send.MsSndBuf,
|
||||
MsSndTsbPdDelay: uint64(c.config.PeerLatency),
|
||||
PktRcvBuf: recv.PktRcvBuf,
|
||||
ByteRcvBuf: recv.ByteRcvBuf,
|
||||
MsRcvBuf: recv.MsRcvBuf,
|
||||
MsRcvTsbPdDelay: uint64(c.config.ReceiverLatency),
|
||||
PktReorderTolerance: 0,
|
||||
PktRcvAvgBelatedTime: 0,
|
||||
// Accumulated
|
||||
s.Accumulated = StatisticsAccumulated{
|
||||
PktSent: send.Pkt,
|
||||
PktRecv: recv.Pkt,
|
||||
PktSentUnique: send.PktUnique,
|
||||
PktRecvUnique: recv.PktUnique,
|
||||
PktSendLoss: send.PktLoss,
|
||||
PktRecvLoss: recv.PktLoss,
|
||||
PktRetrans: send.PktRetrans,
|
||||
PktRecvRetrans: recv.PktRetrans,
|
||||
PktSentACK: c.statistics.pktSentACK,
|
||||
PktRecvACK: c.statistics.pktRecvACK,
|
||||
PktSentNAK: c.statistics.pktSentNAK,
|
||||
PktRecvNAK: c.statistics.pktRecvNAK,
|
||||
PktSentKM: c.statistics.pktSentKM,
|
||||
PktRecvKM: c.statistics.pktRecvKM,
|
||||
UsSndDuration: send.UsSndDuration,
|
||||
PktSendDrop: send.PktDrop,
|
||||
PktRecvDrop: recv.PktDrop,
|
||||
PktRecvUndecrypt: c.statistics.pktRecvUndecrypt,
|
||||
ByteSent: send.Byte + (send.Pkt * c.statistics.headerSize),
|
||||
ByteRecv: recv.Byte + (recv.Pkt * c.statistics.headerSize),
|
||||
ByteSentUnique: send.ByteUnique + (send.PktUnique * c.statistics.headerSize),
|
||||
ByteRecvUnique: recv.ByteUnique + (recv.PktUnique * c.statistics.headerSize),
|
||||
ByteRecvLoss: recv.ByteLoss + (recv.PktLoss * c.statistics.headerSize),
|
||||
ByteRetrans: send.ByteRetrans + (send.PktRetrans * c.statistics.headerSize),
|
||||
ByteRecvRetrans: recv.ByteRetrans + (recv.PktRetrans * c.statistics.headerSize),
|
||||
ByteSendDrop: send.ByteDrop + (send.PktDrop * c.statistics.headerSize),
|
||||
ByteRecvDrop: recv.ByteDrop + (recv.PktDrop * c.statistics.headerSize),
|
||||
ByteRecvUndecrypt: c.statistics.byteRecvUndecrypt + (c.statistics.pktRecvUndecrypt * c.statistics.headerSize),
|
||||
}
|
||||
|
||||
return s
|
||||
// Interval
|
||||
s.Interval = StatisticsInterval{
|
||||
MsInterval: interval,
|
||||
PktSent: s.Accumulated.PktSent - previous.PktSent,
|
||||
PktRecv: s.Accumulated.PktRecv - previous.PktRecv,
|
||||
PktSentUnique: s.Accumulated.PktSentUnique - previous.PktSentUnique,
|
||||
PktRecvUnique: s.Accumulated.PktRecvUnique - previous.PktRecvUnique,
|
||||
PktSendLoss: s.Accumulated.PktSendLoss - previous.PktSendLoss,
|
||||
PktRecvLoss: s.Accumulated.PktRecvLoss - previous.PktRecvLoss,
|
||||
PktRetrans: s.Accumulated.PktRetrans - previous.PktRetrans,
|
||||
PktRecvRetrans: s.Accumulated.PktRecvRetrans - previous.PktRecvRetrans,
|
||||
PktSentACK: s.Accumulated.PktSentACK - previous.PktSentACK,
|
||||
PktRecvACK: s.Accumulated.PktRecvACK - previous.PktRecvACK,
|
||||
PktSentNAK: s.Accumulated.PktSentNAK - previous.PktSentNAK,
|
||||
PktRecvNAK: s.Accumulated.PktRecvNAK - previous.PktRecvNAK,
|
||||
MbpsSendRate: float64(s.Accumulated.ByteSent-previous.ByteSent) * 8 / 1024 / 1024 / (float64(interval) / 1000),
|
||||
MbpsRecvRate: float64(s.Accumulated.ByteRecv-previous.ByteRecv) * 8 / 1024 / 1024 / (float64(interval) / 1000),
|
||||
UsSndDuration: s.Accumulated.UsSndDuration - previous.UsSndDuration,
|
||||
PktReorderDistance: 0,
|
||||
PktRecvBelated: s.Accumulated.PktRecvBelated - previous.PktRecvBelated,
|
||||
PktSndDrop: s.Accumulated.PktSendDrop - previous.PktSendDrop,
|
||||
PktRecvDrop: s.Accumulated.PktRecvDrop - previous.PktRecvDrop,
|
||||
PktRecvUndecrypt: s.Accumulated.PktRecvUndecrypt - previous.PktRecvUndecrypt,
|
||||
ByteSent: s.Accumulated.ByteSent - previous.ByteSent,
|
||||
ByteRecv: s.Accumulated.ByteRecv - previous.ByteRecv,
|
||||
ByteSentUnique: s.Accumulated.ByteSentUnique - previous.ByteSentUnique,
|
||||
ByteRecvUnique: s.Accumulated.ByteRecvUnique - previous.ByteRecvUnique,
|
||||
ByteRecvLoss: s.Accumulated.ByteRecvLoss - previous.ByteRecvLoss,
|
||||
ByteRetrans: s.Accumulated.ByteRetrans - previous.ByteRetrans,
|
||||
ByteRecvRetrans: s.Accumulated.ByteRecvRetrans - previous.ByteRecvRetrans,
|
||||
ByteRecvBelated: s.Accumulated.ByteRecvBelated - previous.ByteRecvBelated,
|
||||
ByteSendDrop: s.Accumulated.ByteSendDrop - previous.ByteSendDrop,
|
||||
ByteRecvDrop: s.Accumulated.ByteRecvDrop - previous.ByteRecvDrop,
|
||||
ByteRecvUndecrypt: s.Accumulated.ByteRecvUndecrypt - previous.ByteRecvUndecrypt,
|
||||
}
|
||||
|
||||
// Instantaneous
|
||||
s.Instantaneous = StatisticsInstantaneous{
|
||||
UsPktSendPeriod: send.UsPktSndPeriod,
|
||||
PktFlowWindow: uint64(c.config.FC),
|
||||
PktFlightSize: send.PktFlightSize,
|
||||
MsRTT: c.rtt / 1000,
|
||||
MbpsSentRate: send.MbpsEstimatedSentBandwidth,
|
||||
MbpsRecvRate: recv.MbpsEstimatedRecvBandwidth,
|
||||
MbpsLinkCapacity: recv.MbpsEstimatedLinkCapacity,
|
||||
ByteAvailSendBuf: 0, // unlimited
|
||||
ByteAvailRecvBuf: 0, // unlimited
|
||||
MbpsMaxBW: float64(c.config.MaxBW) / 1024 / 1024,
|
||||
ByteMSS: uint64(c.config.MSS),
|
||||
PktSendBuf: send.PktBuf,
|
||||
ByteSendBuf: send.ByteBuf,
|
||||
MsSendBuf: send.MsBuf,
|
||||
MsSendTsbPdDelay: c.peerTsbpdDelay / 1000,
|
||||
PktRecvBuf: recv.PktBuf,
|
||||
ByteRecvBuf: recv.ByteBuf,
|
||||
MsRecvBuf: recv.MsBuf,
|
||||
MsRecvTsbPdDelay: c.tsbpdDelay / 1000,
|
||||
PktReorderTolerance: uint64(c.config.LossMaxTTL),
|
||||
PktRecvAvgBelatedTime: 0,
|
||||
PktSendLossRate: send.PktLossRate,
|
||||
PktRecvLossRate: recv.PktLossRate,
|
||||
}
|
||||
|
||||
// If we're only sending, the receiver congestion control value for the link capacity is zero,
|
||||
// use the value that we got from the receiver via the ACK packets.
|
||||
if s.Instantaneous.MbpsLinkCapacity == 0 {
|
||||
s.Instantaneous.MbpsLinkCapacity = c.statistics.mbpsLinkCapacity
|
||||
}
|
||||
|
||||
if c.config.MaxBW < 0 {
|
||||
s.Instantaneous.MbpsMaxBW = -1
|
||||
}
|
||||
|
||||
s.MsTimeStamp = now
|
||||
}
|
||||
|
||||
20
vendor/github.com/datarhei/gosrt/dial.go
generated
vendored
20
vendor/github.com/datarhei/gosrt/dial.go
generated
vendored
@ -475,15 +475,16 @@ func (dl *dialer) handleHandshake(p packet.Packet) {
|
||||
return
|
||||
}
|
||||
|
||||
// Use the largest TSBPD delay as advertised by the listener, but
|
||||
// at least 120ms
|
||||
tsbpdDelay := uint16(120)
|
||||
if cif.RecvTSBPDDelay > tsbpdDelay {
|
||||
tsbpdDelay = cif.RecvTSBPDDelay
|
||||
// Select the largest TSBPD delay advertised by the listener, but at least 120ms
|
||||
recvTsbpdDelay := uint16(dl.config.ReceiverLatency.Milliseconds())
|
||||
sendTsbpdDelay := uint16(dl.config.PeerLatency.Milliseconds())
|
||||
|
||||
if cif.SendTSBPDDelay > recvTsbpdDelay {
|
||||
recvTsbpdDelay = cif.SendTSBPDDelay
|
||||
}
|
||||
|
||||
if cif.SendTSBPDDelay > tsbpdDelay {
|
||||
tsbpdDelay = cif.SendTSBPDDelay
|
||||
if cif.RecvTSBPDDelay > sendTsbpdDelay {
|
||||
sendTsbpdDelay = cif.RecvTSBPDDelay
|
||||
}
|
||||
|
||||
// If the peer has a smaller MTU size, adjust to it
|
||||
@ -512,7 +513,8 @@ func (dl *dialer) handleHandshake(p packet.Packet) {
|
||||
socketId: dl.socketId,
|
||||
peerSocketId: cif.SRTSocketId,
|
||||
tsbpdTimeBase: uint64(time.Since(dl.start).Microseconds()),
|
||||
tsbpdDelay: uint64(tsbpdDelay) * 1000,
|
||||
tsbpdDelay: uint64(recvTsbpdDelay) * 1000,
|
||||
peerTsbpdDelay: uint64(sendTsbpdDelay) * 1000,
|
||||
initialPacketSequenceNumber: cif.InitialPacketSequenceNumber,
|
||||
crypto: dl.crypto,
|
||||
keyBaseEncryption: packet.EvenKeyEncrypted,
|
||||
@ -700,7 +702,7 @@ func (dl *dialer) writePacket(p packet.Packet) error {
|
||||
func (dl *dialer) SetDeadline(t time.Time) error { return dl.conn.SetDeadline(t) }
|
||||
func (dl *dialer) SetReadDeadline(t time.Time) error { return dl.conn.SetReadDeadline(t) }
|
||||
func (dl *dialer) SetWriteDeadline(t time.Time) error { return dl.conn.SetWriteDeadline(t) }
|
||||
func (dl *dialer) Stats() Statistics { return dl.conn.Stats() }
|
||||
func (dl *dialer) Stats(s *Statistics) { dl.conn.Stats(s) }
|
||||
|
||||
func (dl *dialer) log(topic string, message func() string) {
|
||||
dl.config.Logger.Print(topic, dl.socketId, 2, message)
|
||||
|
||||
66
vendor/github.com/datarhei/gosrt/internal/congestion/congestion.go
generated
vendored
66
vendor/github.com/datarhei/gosrt/internal/congestion/congestion.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
||||
// SendConfig is the configuration for the liveSend congestion control
|
||||
type SendConfig struct {
|
||||
InitialSequenceNumber circular.Number
|
||||
DropInterval uint64
|
||||
DropThreshold uint64
|
||||
MaxBW int64
|
||||
InputBW int64
|
||||
MinInputBW int64
|
||||
@ -25,6 +25,7 @@ type Sender interface {
|
||||
Tick(now uint64)
|
||||
ACK(sequenceNumber circular.Number)
|
||||
NAK(sequenceNumbers []circular.Number)
|
||||
SetDropThreshold(threshold uint64)
|
||||
}
|
||||
|
||||
// ReceiveConfig is the configuration for the liveResv congestion control
|
||||
@ -40,7 +41,7 @@ type ReceiveConfig struct {
|
||||
// Receiver is the receiving part of the congestion control
|
||||
type Receiver interface {
|
||||
Stats() ReceiveStats
|
||||
PacketRate() (pps, bps uint32)
|
||||
PacketRate() (pps, bps, capacity float64)
|
||||
Flush()
|
||||
Push(pkt packet.Packet)
|
||||
Tick(now uint64)
|
||||
@ -49,55 +50,68 @@ type Receiver interface {
|
||||
|
||||
// SendStats are collected statistics from liveSend
|
||||
type SendStats struct {
|
||||
PktSent uint64
|
||||
ByteSent uint64
|
||||
Pkt uint64 // Sent packets in total
|
||||
Byte uint64 // Sent bytes in total
|
||||
|
||||
PktSentUnique uint64
|
||||
ByteSentUnique uint64
|
||||
PktUnique uint64
|
||||
ByteUnique uint64
|
||||
|
||||
PktSndLoss uint64
|
||||
ByteSndLoss uint64
|
||||
PktLoss uint64
|
||||
ByteLoss uint64
|
||||
|
||||
PktRetrans uint64
|
||||
ByteRetrans uint64
|
||||
|
||||
UsSndDuration uint64 // microseconds
|
||||
|
||||
PktSndDrop uint64
|
||||
ByteSndDrop uint64
|
||||
PktDrop uint64
|
||||
ByteDrop uint64
|
||||
|
||||
// instantaneous
|
||||
PktSndBuf uint64
|
||||
ByteSndBuf uint64
|
||||
MsSndBuf uint64
|
||||
PktBuf uint64
|
||||
ByteBuf uint64
|
||||
MsBuf uint64
|
||||
|
||||
PktFlightSize uint64
|
||||
|
||||
UsPktSndPeriod float64 // microseconds
|
||||
BytePayload uint64
|
||||
|
||||
MbpsEstimatedInputBandwidth float64
|
||||
MbpsEstimatedSentBandwidth float64
|
||||
|
||||
PktLossRate float64
|
||||
}
|
||||
|
||||
// ReceiveStats are collected statistics from liveRecv
|
||||
type ReceiveStats struct {
|
||||
PktRecv uint64
|
||||
ByteRecv uint64
|
||||
Pkt uint64
|
||||
Byte uint64
|
||||
|
||||
PktRecvUnique uint64
|
||||
ByteRecvUnique uint64
|
||||
PktUnique uint64
|
||||
ByteUnique uint64
|
||||
|
||||
PktRcvLoss uint64
|
||||
ByteRcvLoss uint64
|
||||
PktLoss uint64
|
||||
ByteLoss uint64
|
||||
|
||||
PktRcvRetrans uint64
|
||||
ByteRcvRetrans uint64
|
||||
PktRetrans uint64
|
||||
ByteRetrans uint64
|
||||
|
||||
PktRcvDrop uint64
|
||||
ByteRcvDrop uint64
|
||||
PktBelated uint64
|
||||
ByteBelated uint64
|
||||
|
||||
PktDrop uint64
|
||||
ByteDrop uint64
|
||||
|
||||
// instantaneous
|
||||
PktRcvBuf uint64
|
||||
ByteRcvBuf uint64
|
||||
MsRcvBuf uint64
|
||||
PktBuf uint64
|
||||
ByteBuf uint64
|
||||
MsBuf uint64
|
||||
|
||||
BytePayload uint64
|
||||
|
||||
MbpsEstimatedRecvBandwidth float64
|
||||
MbpsEstimatedLinkCapacity float64
|
||||
|
||||
PktLossRate float64
|
||||
}
|
||||
|
||||
309
vendor/github.com/datarhei/gosrt/internal/congestion/live.go
generated
vendored
309
vendor/github.com/datarhei/gosrt/internal/congestion/live.go
generated
vendored
@ -14,13 +14,12 @@ import (
|
||||
// liveSend implements the Sender interface
|
||||
type liveSend struct {
|
||||
nextSequenceNumber circular.Number
|
||||
dropThreshold uint64
|
||||
|
||||
packetList *list.List
|
||||
lossList *list.List
|
||||
lock sync.RWMutex
|
||||
|
||||
dropInterval uint64 // microseconds
|
||||
|
||||
avgPayloadSize float64 // bytes
|
||||
pktSndPeriod float64 // microseconds
|
||||
maxBW float64 // bytes/s
|
||||
@ -29,14 +28,20 @@ type liveSend struct {
|
||||
|
||||
statistics SendStats
|
||||
|
||||
rate struct {
|
||||
period time.Duration
|
||||
last time.Time
|
||||
probeTime uint64
|
||||
|
||||
bytes uint64
|
||||
prevBytes uint64
|
||||
rate struct {
|
||||
period uint64 // microseconds
|
||||
last uint64
|
||||
|
||||
bytes uint64
|
||||
bytesSent uint64
|
||||
bytesRetrans uint64
|
||||
|
||||
estimatedInputBW float64 // bytes/s
|
||||
estimatedSentBW float64 // bytes/s
|
||||
|
||||
pktLossRate float64
|
||||
}
|
||||
|
||||
deliver func(p packet.Packet)
|
||||
@ -46,12 +51,11 @@ type liveSend struct {
|
||||
func NewLiveSend(config SendConfig) Sender {
|
||||
s := &liveSend{
|
||||
nextSequenceNumber: config.InitialSequenceNumber,
|
||||
dropThreshold: config.DropThreshold,
|
||||
packetList: list.New(),
|
||||
lossList: list.New(),
|
||||
|
||||
dropInterval: config.DropInterval, // microseconds
|
||||
|
||||
avgPayloadSize: 1456, // 5.1.2. SRT's Default LiveCC Algorithm
|
||||
avgPayloadSize: packet.MAX_PAYLOAD_SIZE, // 5.1.2. SRT's Default LiveCC Algorithm
|
||||
maxBW: float64(config.MaxBW),
|
||||
inputBW: float64(config.InputBW),
|
||||
overheadBW: float64(config.OverheadBW),
|
||||
@ -66,8 +70,8 @@ func NewLiveSend(config SendConfig) Sender {
|
||||
s.maxBW = 128 * 1024 * 1024 // 1 Gbit/s
|
||||
s.pktSndPeriod = (s.avgPayloadSize + 16) * 1_000_000 / s.maxBW
|
||||
|
||||
s.rate.period = time.Second
|
||||
s.rate.last = time.Now()
|
||||
s.rate.period = uint64(time.Second.Microseconds())
|
||||
s.rate.last = 0
|
||||
|
||||
return s
|
||||
}
|
||||
@ -78,15 +82,20 @@ func (s *liveSend) Stats() SendStats {
|
||||
|
||||
s.statistics.UsPktSndPeriod = s.pktSndPeriod
|
||||
s.statistics.BytePayload = uint64(s.avgPayloadSize)
|
||||
s.statistics.MsSndBuf = 0
|
||||
s.statistics.MsBuf = 0
|
||||
|
||||
max := s.lossList.Back()
|
||||
min := s.lossList.Front()
|
||||
|
||||
if max != nil && min != nil {
|
||||
s.statistics.MsSndBuf = (max.Value.(packet.Packet).Header().PktTsbpdTime - min.Value.(packet.Packet).Header().PktTsbpdTime) / 1_000
|
||||
s.statistics.MsBuf = (max.Value.(packet.Packet).Header().PktTsbpdTime - min.Value.(packet.Packet).Header().PktTsbpdTime) / 1_000
|
||||
}
|
||||
|
||||
s.statistics.MbpsEstimatedInputBandwidth = s.rate.estimatedInputBW * 8 / 1024 / 1024
|
||||
s.statistics.MbpsEstimatedSentBandwidth = s.rate.estimatedSentBW * 8 / 1024 / 1024
|
||||
|
||||
s.statistics.PktLossRate = s.rate.pktLossRate
|
||||
|
||||
return s.statistics
|
||||
}
|
||||
|
||||
@ -112,24 +121,27 @@ func (s *liveSend) Push(p packet.Packet) {
|
||||
|
||||
pktLen := p.Len()
|
||||
|
||||
s.statistics.PktSndBuf++
|
||||
s.statistics.ByteSndBuf += pktLen
|
||||
s.statistics.PktBuf++
|
||||
s.statistics.ByteBuf += pktLen
|
||||
|
||||
// bandwidth calculation
|
||||
// input bandwidth calculation
|
||||
s.rate.bytes += pktLen
|
||||
|
||||
now := time.Now()
|
||||
tdiff := now.Sub(s.rate.last)
|
||||
|
||||
if tdiff > s.rate.period {
|
||||
s.rate.estimatedInputBW = float64(s.rate.bytes-s.rate.prevBytes) / tdiff.Seconds()
|
||||
|
||||
s.rate.prevBytes = s.rate.bytes
|
||||
s.rate.last = now
|
||||
}
|
||||
|
||||
p.Header().Timestamp = uint32(p.Header().PktTsbpdTime & uint64(packet.MAX_TIMESTAMP))
|
||||
|
||||
// Every 16th and 17th packet should be sent at the same time in order
|
||||
// for the receiver to determine the link capacity. Not really well
|
||||
// documented in the specs.
|
||||
// PktTsbpdTime is used for the timing of sending the packets. Here we
|
||||
// can modify it because it has already been used to set the packet's
|
||||
// timestamp.
|
||||
probe := p.Header().PacketSequenceNumber.Val() & 0xF
|
||||
if probe == 0 {
|
||||
s.probeTime = p.Header().PktTsbpdTime
|
||||
} else if probe == 1 {
|
||||
p.Header().PktTsbpdTime = s.probeTime
|
||||
}
|
||||
|
||||
s.packetList.PushBack(p)
|
||||
|
||||
s.statistics.PktFlightSize = uint64(s.packetList.Len())
|
||||
@ -142,16 +154,20 @@ func (s *liveSend) Tick(now uint64) {
|
||||
for e := s.packetList.Front(); e != nil; e = e.Next() {
|
||||
p := e.Value.(packet.Packet)
|
||||
if p.Header().PktTsbpdTime <= now {
|
||||
s.statistics.PktSent++
|
||||
s.statistics.PktSentUnique++
|
||||
s.statistics.Pkt++
|
||||
s.statistics.PktUnique++
|
||||
|
||||
s.statistics.ByteSent += p.Len()
|
||||
s.statistics.ByteSentUnique += p.Len()
|
||||
pktLen := p.Len()
|
||||
|
||||
s.statistics.Byte += pktLen
|
||||
s.statistics.ByteUnique += pktLen
|
||||
|
||||
s.statistics.UsSndDuration += uint64(s.pktSndPeriod)
|
||||
|
||||
// 5.1.2. SRT's Default LiveCC Algorithm
|
||||
s.avgPayloadSize = 0.875*s.avgPayloadSize + 0.125*float64(p.Len())
|
||||
s.avgPayloadSize = 0.875*s.avgPayloadSize + 0.125*float64(pktLen)
|
||||
|
||||
s.rate.bytesSent += pktLen
|
||||
|
||||
s.deliver(p)
|
||||
removeList = append(removeList, e)
|
||||
@ -171,12 +187,12 @@ func (s *liveSend) Tick(now uint64) {
|
||||
for e := s.lossList.Front(); e != nil; e = e.Next() {
|
||||
p := e.Value.(packet.Packet)
|
||||
|
||||
if p.Header().PktTsbpdTime+s.dropInterval <= now {
|
||||
if p.Header().PktTsbpdTime+s.dropThreshold <= now {
|
||||
// dropped packet because too old
|
||||
s.statistics.PktSndDrop++
|
||||
s.statistics.PktSndLoss++
|
||||
s.statistics.ByteSndDrop += p.Len()
|
||||
s.statistics.ByteSndLoss += p.Len()
|
||||
s.statistics.PktDrop++
|
||||
s.statistics.PktLoss++
|
||||
s.statistics.ByteDrop += p.Len()
|
||||
s.statistics.ByteLoss += p.Len()
|
||||
|
||||
removeList = append(removeList, e)
|
||||
}
|
||||
@ -186,8 +202,8 @@ func (s *liveSend) Tick(now uint64) {
|
||||
for _, e := range removeList {
|
||||
p := e.Value.(packet.Packet)
|
||||
|
||||
s.statistics.PktSndBuf--
|
||||
s.statistics.ByteSndBuf -= p.Len()
|
||||
s.statistics.PktBuf--
|
||||
s.statistics.ByteBuf -= p.Len()
|
||||
|
||||
s.lossList.Remove(e)
|
||||
|
||||
@ -195,6 +211,26 @@ func (s *liveSend) Tick(now uint64) {
|
||||
p.Decommission()
|
||||
}
|
||||
s.lock.Unlock()
|
||||
|
||||
s.lock.Lock()
|
||||
tdiff := now - s.rate.last
|
||||
|
||||
if tdiff > s.rate.period {
|
||||
s.rate.estimatedInputBW = float64(s.rate.bytes) / (float64(tdiff) / 1000 / 1000)
|
||||
s.rate.estimatedSentBW = float64(s.rate.bytesSent) / (float64(tdiff) / 1000 / 1000)
|
||||
if s.rate.bytesSent != 0 {
|
||||
s.rate.pktLossRate = float64(s.rate.bytesRetrans) / float64(s.rate.bytesSent) * 100
|
||||
} else {
|
||||
s.rate.pktLossRate = 0
|
||||
}
|
||||
|
||||
s.rate.bytes = 0
|
||||
s.rate.bytesSent = 0
|
||||
s.rate.bytesRetrans = 0
|
||||
|
||||
s.rate.last = now
|
||||
}
|
||||
s.lock.Unlock()
|
||||
}
|
||||
|
||||
func (s *liveSend) ACK(sequenceNumber circular.Number) {
|
||||
@ -216,8 +252,8 @@ func (s *liveSend) ACK(sequenceNumber circular.Number) {
|
||||
for _, e := range removeList {
|
||||
p := e.Value.(packet.Packet)
|
||||
|
||||
s.statistics.PktSndBuf--
|
||||
s.statistics.ByteSndBuf -= p.Len()
|
||||
s.statistics.PktBuf--
|
||||
s.statistics.ByteBuf -= p.Len()
|
||||
|
||||
s.lossList.Remove(e)
|
||||
|
||||
@ -242,16 +278,19 @@ func (s *liveSend) NAK(sequenceNumbers []circular.Number) {
|
||||
for i := 0; i < len(sequenceNumbers); i += 2 {
|
||||
if p.Header().PacketSequenceNumber.Gte(sequenceNumbers[i]) && p.Header().PacketSequenceNumber.Lte(sequenceNumbers[i+1]) {
|
||||
s.statistics.PktRetrans++
|
||||
s.statistics.PktSent++
|
||||
s.statistics.PktSndLoss++
|
||||
s.statistics.Pkt++
|
||||
s.statistics.PktLoss++
|
||||
|
||||
s.statistics.ByteRetrans += p.Len()
|
||||
s.statistics.ByteSent += p.Len()
|
||||
s.statistics.ByteSndLoss += p.Len()
|
||||
s.statistics.Byte += p.Len()
|
||||
s.statistics.ByteLoss += p.Len()
|
||||
|
||||
// 5.1.2. SRT's Default LiveCC Algorithm
|
||||
s.avgPayloadSize = 0.875*s.avgPayloadSize + 0.125*float64(p.Len())
|
||||
|
||||
s.rate.bytesSent += p.Len()
|
||||
s.rate.bytesRetrans += p.Len()
|
||||
|
||||
p.Header().RetransmittedPacketFlag = true
|
||||
s.deliver(p)
|
||||
}
|
||||
@ -259,6 +298,13 @@ func (s *liveSend) NAK(sequenceNumbers []circular.Number) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *liveSend) SetDropThreshold(threshold uint64) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
s.dropThreshold = threshold
|
||||
}
|
||||
|
||||
// liveReceive implements the Receiver interface
|
||||
type liveReceive struct {
|
||||
maxSeenSequenceNumber circular.Number
|
||||
@ -275,21 +321,26 @@ type liveReceive struct {
|
||||
lastPeriodicACK uint64
|
||||
lastPeriodicNAK uint64
|
||||
|
||||
avgPayloadSize float64 // bytes
|
||||
avgPayloadSize float64 // bytes
|
||||
avgLinkCapacity float64 // packets per second
|
||||
|
||||
probeTime time.Time
|
||||
probeNextSeq circular.Number
|
||||
|
||||
statistics ReceiveStats
|
||||
|
||||
rate struct {
|
||||
last time.Time
|
||||
period time.Duration
|
||||
last uint64 // microseconds
|
||||
period uint64
|
||||
|
||||
packets uint64
|
||||
prevPackets uint64
|
||||
bytes uint64
|
||||
prevBytes uint64
|
||||
packets uint64
|
||||
bytes uint64
|
||||
bytesRetrans uint64
|
||||
|
||||
pps uint32
|
||||
bps uint32
|
||||
packetsPerSecond float64
|
||||
bytesPerSecond float64
|
||||
|
||||
pktLossRate float64
|
||||
}
|
||||
|
||||
sendACK func(seq circular.Number, light bool)
|
||||
@ -327,8 +378,8 @@ func NewLiveReceive(config ReceiveConfig) Receiver {
|
||||
r.deliver = func(p packet.Packet) {}
|
||||
}
|
||||
|
||||
r.rate.last = time.Now()
|
||||
r.rate.period = time.Second
|
||||
r.rate.last = 0
|
||||
r.rate.period = uint64(time.Second.Microseconds())
|
||||
|
||||
return r
|
||||
}
|
||||
@ -338,34 +389,20 @@ func (r *liveReceive) Stats() ReceiveStats {
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
r.statistics.BytePayload = uint64(r.avgPayloadSize)
|
||||
r.statistics.MbpsEstimatedRecvBandwidth = r.rate.bytesPerSecond * 8 / 1024 / 1024
|
||||
r.statistics.MbpsEstimatedLinkCapacity = r.avgLinkCapacity * packet.MAX_PAYLOAD_SIZE * 8 / 1024 / 1024
|
||||
r.statistics.PktLossRate = r.rate.pktLossRate
|
||||
|
||||
return r.statistics
|
||||
}
|
||||
|
||||
func (r *liveReceive) PacketRate() (pps, bps uint32) {
|
||||
func (r *liveReceive) PacketRate() (pps, bps, capacity float64) {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
tdiff := time.Since(r.rate.last)
|
||||
|
||||
if tdiff < r.rate.period {
|
||||
pps = r.rate.pps
|
||||
bps = r.rate.bps
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
pdiff := r.rate.packets - r.rate.prevPackets
|
||||
bdiff := r.rate.bytes - r.rate.prevBytes
|
||||
|
||||
r.rate.pps = uint32(float64(pdiff) / tdiff.Seconds())
|
||||
r.rate.bps = uint32(float64(bdiff) / tdiff.Seconds())
|
||||
|
||||
r.rate.prevPackets, r.rate.prevBytes = r.rate.packets, r.rate.bytes
|
||||
r.rate.last = time.Now()
|
||||
|
||||
pps = r.rate.pps
|
||||
bps = r.rate.bps
|
||||
pps = r.rate.packetsPerSecond
|
||||
bps = r.rate.bytesPerSecond
|
||||
capacity = r.avgLinkCapacity
|
||||
|
||||
return
|
||||
}
|
||||
@ -385,6 +422,28 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||
return
|
||||
}
|
||||
|
||||
// This is not really well (not at all) described in the specs. See core.cpp and window.h
|
||||
// and search for PUMASK_SEQNO_PROBE (0xF). Every 16th and 17th packet are
|
||||
// sent in pairs. This is used as a probe for the theoretical capacity of the link.
|
||||
if !pkt.Header().RetransmittedPacketFlag {
|
||||
probe := pkt.Header().PacketSequenceNumber.Val() & 0xF
|
||||
if probe == 0 {
|
||||
r.probeTime = time.Now()
|
||||
r.probeNextSeq = pkt.Header().PacketSequenceNumber.Inc()
|
||||
} else if probe == 1 && pkt.Header().PacketSequenceNumber.Equals(r.probeNextSeq) && !r.probeTime.IsZero() && pkt.Len() != 0 {
|
||||
// The time between packets scaled to a fully loaded packet
|
||||
diff := float64(time.Since(r.probeTime).Microseconds()) * (packet.MAX_PAYLOAD_SIZE / float64(pkt.Len()))
|
||||
if diff != 0 {
|
||||
// Here we're doing an average of the measurements.
|
||||
r.avgLinkCapacity = 0.875*r.avgLinkCapacity + 0.125*1_000_000/diff
|
||||
}
|
||||
} else {
|
||||
r.probeTime = time.Time{}
|
||||
}
|
||||
} else {
|
||||
r.probeTime = time.Time{}
|
||||
}
|
||||
|
||||
r.nPackets++
|
||||
|
||||
pktLen := pkt.Len()
|
||||
@ -392,13 +451,15 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||
r.rate.packets++
|
||||
r.rate.bytes += pktLen
|
||||
|
||||
r.statistics.PktRecv++
|
||||
r.statistics.ByteRecv += pktLen
|
||||
r.statistics.Pkt++
|
||||
r.statistics.Byte += pktLen
|
||||
|
||||
//pkt.PktTsbpdTime = pkt.Timestamp + r.delay
|
||||
if pkt.Header().RetransmittedPacketFlag {
|
||||
r.statistics.PktRcvRetrans++
|
||||
r.statistics.ByteRcvRetrans += pktLen
|
||||
r.statistics.PktRetrans++
|
||||
r.statistics.ByteRetrans += pktLen
|
||||
|
||||
r.rate.bytesRetrans += pktLen
|
||||
}
|
||||
|
||||
// 5.1.2. SRT's Default LiveCC Algorithm
|
||||
@ -406,16 +467,19 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||
|
||||
if pkt.Header().PacketSequenceNumber.Lte(r.lastDeliveredSequenceNumber) {
|
||||
// too old, because up until r.lastDeliveredSequenceNumber, we already delivered
|
||||
r.statistics.PktRcvDrop++
|
||||
r.statistics.ByteRcvDrop += pktLen
|
||||
r.statistics.PktBelated++
|
||||
r.statistics.ByteBelated += pktLen
|
||||
|
||||
r.statistics.PktDrop++
|
||||
r.statistics.ByteDrop += pktLen
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if pkt.Header().PacketSequenceNumber.Lt(r.lastACKSequenceNumber) {
|
||||
// already acknowledged, ignoring
|
||||
r.statistics.PktRcvDrop++
|
||||
r.statistics.ByteRcvDrop += pktLen
|
||||
r.statistics.PktDrop++
|
||||
r.statistics.ByteDrop += pktLen
|
||||
|
||||
return
|
||||
}
|
||||
@ -430,17 +494,17 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||
|
||||
if p.Header().PacketSequenceNumber == pkt.Header().PacketSequenceNumber {
|
||||
// already received (has been sent more than once), ignoring
|
||||
r.statistics.PktRcvDrop++
|
||||
r.statistics.ByteRcvDrop += pktLen
|
||||
r.statistics.PktDrop++
|
||||
r.statistics.ByteDrop += pktLen
|
||||
|
||||
break
|
||||
} else if p.Header().PacketSequenceNumber.Gt(pkt.Header().PacketSequenceNumber) {
|
||||
// late arrival, this fills a gap
|
||||
r.statistics.PktRcvBuf++
|
||||
r.statistics.PktRecvUnique++
|
||||
r.statistics.PktBuf++
|
||||
r.statistics.PktUnique++
|
||||
|
||||
r.statistics.ByteRcvBuf += pktLen
|
||||
r.statistics.ByteRecvUnique += pktLen
|
||||
r.statistics.ByteBuf += pktLen
|
||||
r.statistics.ByteUnique += pktLen
|
||||
|
||||
r.packetList.InsertBefore(pkt, e)
|
||||
|
||||
@ -455,17 +519,17 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||
r.sendNAK(r.maxSeenSequenceNumber.Inc(), pkt.Header().PacketSequenceNumber.Dec())
|
||||
|
||||
len := uint64(pkt.Header().PacketSequenceNumber.Distance(r.maxSeenSequenceNumber))
|
||||
r.statistics.PktRcvLoss += len
|
||||
r.statistics.ByteRcvLoss += len * uint64(r.avgPayloadSize)
|
||||
r.statistics.PktLoss += len
|
||||
r.statistics.ByteLoss += len * uint64(r.avgPayloadSize)
|
||||
|
||||
r.maxSeenSequenceNumber = pkt.Header().PacketSequenceNumber
|
||||
}
|
||||
|
||||
r.statistics.PktRcvBuf++
|
||||
r.statistics.PktRecvUnique++
|
||||
r.statistics.PktBuf++
|
||||
r.statistics.PktUnique++
|
||||
|
||||
r.statistics.ByteRcvBuf += pktLen
|
||||
r.statistics.ByteRecvUnique += pktLen
|
||||
r.statistics.ByteBuf += pktLen
|
||||
r.statistics.ByteUnique += pktLen
|
||||
|
||||
r.packetList.PushBack(pkt)
|
||||
}
|
||||
@ -521,7 +585,7 @@ func (r *liveReceive) periodicACK(now uint64) (ok bool, sequenceNumber circular.
|
||||
r.lastPeriodicACK = now
|
||||
r.nPackets = 0
|
||||
|
||||
r.statistics.MsRcvBuf = (maxPktTsbpdTime - minPktTsbpdTime) / 1_000
|
||||
r.statistics.MsBuf = (maxPktTsbpdTime - minPktTsbpdTime) / 1_000
|
||||
|
||||
return
|
||||
}
|
||||
@ -572,15 +636,13 @@ func (r *liveReceive) Tick(now uint64) {
|
||||
|
||||
// deliver packets whose PktTsbpdTime is ripe
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
removeList := make([]*list.Element, 0, r.packetList.Len())
|
||||
for e := r.packetList.Front(); e != nil; e = e.Next() {
|
||||
p := e.Value.(packet.Packet)
|
||||
|
||||
if p.Header().PacketSequenceNumber.Lte(r.lastACKSequenceNumber) && p.Header().PktTsbpdTime <= now {
|
||||
r.statistics.PktRcvBuf--
|
||||
r.statistics.ByteRcvBuf -= p.Len()
|
||||
r.statistics.PktBuf--
|
||||
r.statistics.ByteBuf -= p.Len()
|
||||
|
||||
r.lastDeliveredSequenceNumber = p.Header().PacketSequenceNumber
|
||||
|
||||
@ -594,6 +656,27 @@ func (r *liveReceive) Tick(now uint64) {
|
||||
for _, e := range removeList {
|
||||
r.packetList.Remove(e)
|
||||
}
|
||||
r.lock.Unlock()
|
||||
|
||||
r.lock.Lock()
|
||||
tdiff := now - r.rate.last // microseconds
|
||||
|
||||
if tdiff > r.rate.period {
|
||||
r.rate.packetsPerSecond = float64(r.rate.packets) / (float64(tdiff) / 1000 / 1000)
|
||||
r.rate.bytesPerSecond = float64(r.rate.bytes) / (float64(tdiff) / 1000 / 1000)
|
||||
if r.rate.bytes != 0 {
|
||||
r.rate.pktLossRate = float64(r.rate.bytesRetrans) / float64(r.rate.bytes) * 100
|
||||
} else {
|
||||
r.rate.bytes = 0
|
||||
}
|
||||
|
||||
r.rate.packets = 0
|
||||
r.rate.bytes = 0
|
||||
r.rate.bytesRetrans = 0
|
||||
|
||||
r.rate.last = now
|
||||
}
|
||||
r.lock.Unlock()
|
||||
}
|
||||
|
||||
func (r *liveReceive) SetNAKInterval(nakInterval uint64) {
|
||||
@ -630,7 +713,6 @@ type fakeLiveReceive struct {
|
||||
periodicNAKInterval uint64 // config
|
||||
|
||||
lastPeriodicACK uint64
|
||||
lastPeriodicNAK uint64
|
||||
|
||||
avgPayloadSize float64 // bytes
|
||||
|
||||
@ -638,13 +720,11 @@ type fakeLiveReceive struct {
|
||||
last time.Time
|
||||
period time.Duration
|
||||
|
||||
packets uint64
|
||||
prevPackets uint64
|
||||
bytes uint64
|
||||
prevBytes uint64
|
||||
packets uint64
|
||||
bytes uint64
|
||||
|
||||
pps uint32
|
||||
bps uint32
|
||||
pps float64
|
||||
bps float64
|
||||
}
|
||||
|
||||
sendACK func(seq circular.Number, light bool)
|
||||
@ -689,7 +769,7 @@ func NewFakeLiveReceive(config ReceiveConfig) Receiver {
|
||||
}
|
||||
|
||||
func (r *fakeLiveReceive) Stats() ReceiveStats { return ReceiveStats{} }
|
||||
func (r *fakeLiveReceive) PacketRate() (pps, bps uint32) {
|
||||
func (r *fakeLiveReceive) PacketRate() (pps, bps, capacity float64) {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
@ -702,13 +782,10 @@ func (r *fakeLiveReceive) PacketRate() (pps, bps uint32) {
|
||||
return
|
||||
}
|
||||
|
||||
pdiff := r.rate.packets - r.rate.prevPackets
|
||||
bdiff := r.rate.bytes - r.rate.prevBytes
|
||||
r.rate.pps = float64(r.rate.packets) / tdiff.Seconds()
|
||||
r.rate.bps = float64(r.rate.bytes) / tdiff.Seconds()
|
||||
|
||||
r.rate.pps = uint32(float64(pdiff) / tdiff.Seconds())
|
||||
r.rate.bps = uint32(float64(bdiff) / tdiff.Seconds())
|
||||
|
||||
r.rate.prevPackets, r.rate.prevBytes = r.rate.packets, r.rate.bytes
|
||||
r.rate.packets, r.rate.bytes = 0, 0
|
||||
r.rate.last = time.Now()
|
||||
|
||||
pps = r.rate.pps
|
||||
|
||||
3
vendor/github.com/datarhei/gosrt/internal/packet/packet.go
generated
vendored
3
vendor/github.com/datarhei/gosrt/internal/packet/packet.go
generated
vendored
@ -18,6 +18,7 @@ import (
|
||||
|
||||
const MAX_SEQUENCENUMBER uint32 = 0b01111111_11111111_11111111_11111111
|
||||
const MAX_TIMESTAMP uint32 = 0b11111111_11111111_11111111_11111111
|
||||
const MAX_PAYLOAD_SIZE = 1456
|
||||
|
||||
// Table 1: SRT Control Packet Types
|
||||
const (
|
||||
@ -279,7 +280,7 @@ func (p *pkt) Decommission() {
|
||||
func (p pkt) String() string {
|
||||
var b strings.Builder
|
||||
|
||||
fmt.Fprintf(&b, "timestamp=%#08x, destId=%#08x\n", p.header.Timestamp, p.header.DestinationSocketId)
|
||||
fmt.Fprintf(&b, "timestamp=%#08x (%d), destId=%#08x\n", p.header.Timestamp, p.header.Timestamp, p.header.DestinationSocketId)
|
||||
|
||||
if p.header.IsControlPacket {
|
||||
fmt.Fprintf(&b, "control packet:\n")
|
||||
|
||||
20
vendor/github.com/datarhei/gosrt/listen.go
generated
vendored
20
vendor/github.com/datarhei/gosrt/listen.go
generated
vendored
@ -312,15 +312,16 @@ func (ln *listener) Accept(acceptFn AcceptFunc) (Conn, ConnType, error) {
|
||||
// Create a new socket ID
|
||||
socketId := uint32(time.Since(ln.start).Microseconds())
|
||||
|
||||
// Select the largest TSBPD delay advertised by the caller, but at
|
||||
// least 120ms
|
||||
tsbpdDelay := uint16(120)
|
||||
if request.handshake.RecvTSBPDDelay > tsbpdDelay {
|
||||
tsbpdDelay = request.handshake.RecvTSBPDDelay
|
||||
// Select the largest TSBPD delay advertised by the listener, but at least 120ms
|
||||
recvTsbpdDelay := uint16(ln.config.ReceiverLatency.Milliseconds())
|
||||
sendTsbpdDelay := uint16(ln.config.PeerLatency.Milliseconds())
|
||||
|
||||
if request.handshake.SendTSBPDDelay > recvTsbpdDelay {
|
||||
recvTsbpdDelay = request.handshake.SendTSBPDDelay
|
||||
}
|
||||
|
||||
if request.handshake.SendTSBPDDelay > tsbpdDelay {
|
||||
tsbpdDelay = request.handshake.SendTSBPDDelay
|
||||
if request.handshake.RecvTSBPDDelay > sendTsbpdDelay {
|
||||
sendTsbpdDelay = request.handshake.RecvTSBPDDelay
|
||||
}
|
||||
|
||||
ln.config.StreamId = request.handshake.StreamId
|
||||
@ -335,7 +336,8 @@ func (ln *listener) Accept(acceptFn AcceptFunc) (Conn, ConnType, error) {
|
||||
socketId: socketId,
|
||||
peerSocketId: request.handshake.SRTSocketId,
|
||||
tsbpdTimeBase: uint64(request.timestamp),
|
||||
tsbpdDelay: uint64(tsbpdDelay) * 1000,
|
||||
tsbpdDelay: uint64(recvTsbpdDelay) * 1000,
|
||||
peerTsbpdDelay: uint64(sendTsbpdDelay) * 1000,
|
||||
initialPacketSequenceNumber: request.handshake.InitialPacketSequenceNumber,
|
||||
crypto: request.crypto,
|
||||
keyBaseEncryption: packet.EvenKeyEncrypted,
|
||||
@ -359,6 +361,8 @@ func (ln *listener) Accept(acceptFn AcceptFunc) (Conn, ConnType, error) {
|
||||
request.handshake.SRTFlags.REXMITFLG = true
|
||||
request.handshake.SRTFlags.STREAM = false
|
||||
request.handshake.SRTFlags.PACKET_FILTER = false
|
||||
request.handshake.RecvTSBPDDelay = recvTsbpdDelay
|
||||
request.handshake.SendTSBPDDelay = sendTsbpdDelay
|
||||
|
||||
ln.accept(request)
|
||||
|
||||
|
||||
152
vendor/github.com/datarhei/gosrt/statistics.go
generated
vendored
152
vendor/github.com/datarhei/gosrt/statistics.go
generated
vendored
@ -7,55 +7,111 @@ type Statistics struct {
|
||||
MsTimeStamp uint64 // The time elapsed, in milliseconds, since the SRT socket has been created
|
||||
|
||||
// Accumulated
|
||||
Accumulated StatisticsAccumulated
|
||||
|
||||
PktSent uint64 // The total number of sent DATA packets, including retransmitted packets
|
||||
PktRecv uint64 // The total number of received DATA packets, including retransmitted packets
|
||||
PktSentUnique uint64 // The total number of unique DATA packets sent by the SRT sender
|
||||
PktRecvUnique uint64 // The total number of unique original, retransmitted or recovered by the packet filter DATA packets received in time, decrypted without errors and, as a result, scheduled for delivery to the upstream application by the SRT receiver.
|
||||
PktSndLoss uint64 // The total number of data packets considered or reported as lost at the sender side. Does not correspond to the packets detected as lost at the receiver side.
|
||||
PktRcvLoss uint64 // The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
|
||||
PktRetrans uint64 // The total number of retransmitted packets sent by the SRT sender
|
||||
PktRcvRetrans uint64 // The total number of retransmitted packets registered at the receiver side
|
||||
PktSentACK uint64 // The total number of sent ACK (Acknowledgement) control packets
|
||||
PktRecvACK uint64 // The total number of received ACK (Acknowledgement) control packets
|
||||
PktSentNAK uint64 // The total number of sent NAK (Negative Acknowledgement) control packets
|
||||
PktRecvNAK uint64 // The total number of received NAK (Negative Acknowledgement) control packets
|
||||
PktSentKM uint64 // The total number of sent KM (Key Material) control packets
|
||||
PktRecvKM uint64 // The total number of received KM (Key Material) control packets
|
||||
UsSndDuration uint64 // The total accumulated time in microseconds, during which the SRT sender has some data to transmit, including packets that have been sent, but not yet acknowledged
|
||||
PktSndDrop uint64 // The total number of dropped by the SRT sender DATA packets that have no chance to be delivered in time
|
||||
PktRcvDrop uint64 // The total number of dropped by the SRT receiver and, as a result, not delivered to the upstream application DATA packets
|
||||
PktRcvUndecrypt uint64 // The total number of packets that failed to be decrypted at the receiver side
|
||||
|
||||
ByteSent uint64 // Same as pktSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecv uint64 // Same as pktRecv, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSentUnique uint64 // Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvUnique uint64 // Same as pktRecvUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRcvLoss uint64 // Same as pktRcvLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size
|
||||
ByteRetrans uint64 // Same as pktRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSndDrop uint64 // Same as pktSndDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRcvDrop uint64 // Same as pktRcvDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRcvUndecrypt uint64 // Same as pktRcvUndecrypt, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
// Interval
|
||||
Interval StatisticsInterval
|
||||
|
||||
// Instantaneous
|
||||
|
||||
UsPktSndPeriod float64 // Current minimum time interval between which consecutive packets are sent, in microseconds
|
||||
PktFlowWindow uint64 // The maximum number of packets that can be "in flight"
|
||||
PktFlightSize uint64 // The number of packets in flight
|
||||
MsRTT float64 // Smoothed round-trip time (SRTT), an exponentially-weighted moving average (EWMA) of an endpoint's RTT samples, in milliseconds
|
||||
MbpsBandwidth float64 // Estimated bandwidth of the network link, in Mbps
|
||||
ByteAvailSndBuf uint64 // The available space in the sender's buffer, in bytes
|
||||
ByteAvailRcvBuf uint64 // The available space in the receiver's buffer, in bytes
|
||||
MbpsMaxBW float64 // Transmission bandwidth limit, in Mbps
|
||||
ByteMSS uint64 // Maximum Segment Size (MSS), in bytes
|
||||
PktSndBuf uint64 // The number of packets in the sender's buffer that are already scheduled for sending or even possibly sent, but not yet acknowledged
|
||||
ByteSndBuf uint64 // Instantaneous (current) value of pktSndBuf, but expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
MsSndBuf uint64 // The timespan (msec) of packets in the sender's buffer (unacknowledged packets)
|
||||
MsSndTsbPdDelay uint64 // Timestamp-based Packet Delivery Delay value of the peer
|
||||
PktRcvBuf uint64 // The number of acknowledged packets in receiver's buffer
|
||||
ByteRcvBuf uint64 // Instantaneous (current) value of pktRcvBuf, expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
MsRcvBuf uint64 // The timespan (msec) of acknowledged packets in the receiver's buffer
|
||||
MsRcvTsbPdDelay uint64 // Timestamp-based Packet Delivery Delay value set on the socket via SRTO_RCVLATENCY or SRTO_LATENCY
|
||||
PktReorderTolerance uint64 // Instant value of the packet reorder tolerance
|
||||
PktRcvAvgBelatedTime uint64 // Accumulated difference between the current time and the time-to-play of a packet that is received late
|
||||
Instantaneous StatisticsInstantaneous
|
||||
}
|
||||
|
||||
type StatisticsAccumulated struct {
|
||||
PktSent uint64 // The total number of sent DATA packets, including retransmitted packets
|
||||
PktRecv uint64 // The total number of received DATA packets, including retransmitted packets
|
||||
PktSentUnique uint64 // The total number of unique DATA packets sent by the SRT sender
|
||||
PktRecvUnique uint64 // The total number of unique original, retransmitted or recovered by the packet filter DATA packets received in time, decrypted without errors and, as a result, scheduled for delivery to the upstream application by the SRT receiver.
|
||||
PktSendLoss uint64 // The total number of data packets considered or reported as lost at the sender side. Does not correspond to the packets detected as lost at the receiver side.
|
||||
PktRecvLoss uint64 // The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
|
||||
PktRetrans uint64 // The total number of retransmitted packets sent by the SRT sender
|
||||
PktRecvRetrans uint64 // The total number of retransmitted packets registered at the receiver side
|
||||
PktSentACK uint64 // The total number of sent ACK (Acknowledgement) control packets
|
||||
PktRecvACK uint64 // The total number of received ACK (Acknowledgement) control packets
|
||||
PktSentNAK uint64 // The total number of sent NAK (Negative Acknowledgement) control packets
|
||||
PktRecvNAK uint64 // The total number of received NAK (Negative Acknowledgement) control packets
|
||||
PktSentKM uint64 // The total number of sent KM (Key Material) control packets
|
||||
PktRecvKM uint64 // The total number of received KM (Key Material) control packets
|
||||
UsSndDuration uint64 // The total accumulated time in microseconds, during which the SRT sender has some data to transmit, including packets that have been sent, but not yet acknowledged
|
||||
PktRecvBelated uint64
|
||||
PktSendDrop uint64 // The total number of dropped by the SRT sender DATA packets that have no chance to be delivered in time
|
||||
PktRecvDrop uint64 // The total number of dropped by the SRT receiver and, as a result, not delivered to the upstream application DATA packets
|
||||
PktRecvUndecrypt uint64 // The total number of packets that failed to be decrypted at the receiver side
|
||||
|
||||
ByteSent uint64 // Same as pktSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecv uint64 // Same as pktRecv, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSentUnique uint64 // Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvUnique uint64 // Same as pktRecvUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvLoss uint64 // Same as pktRecvLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size
|
||||
ByteRetrans uint64 // Same as pktRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvRetrans uint64 // Same as pktRecvRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvBelated uint64
|
||||
ByteSendDrop uint64 // Same as pktSendDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvDrop uint64 // Same as pktRecvDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvUndecrypt uint64 // Same as pktRecvUndecrypt, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
}
|
||||
|
||||
type StatisticsInterval struct {
|
||||
MsInterval uint64 // Length of the interval, in milliseconds
|
||||
|
||||
PktSent uint64 // Number of sent DATA packets, including retransmitted packets
|
||||
PktRecv uint64 // Number of received DATA packets, including retransmitted packets
|
||||
PktSentUnique uint64 // Number of unique DATA packets sent by the SRT sender
|
||||
PktRecvUnique uint64 // Number of unique original, retransmitted or recovered by the packet filter DATA packets received in time, decrypted without errors and, as a result, scheduled for delivery to the upstream application by the SRT receiver.
|
||||
PktSendLoss uint64 // Number of data packets considered or reported as lost at the sender side. Does not correspond to the packets detected as lost at the receiver side.
|
||||
PktRecvLoss uint64 // Number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
|
||||
PktRetrans uint64 // Number of retransmitted packets sent by the SRT sender
|
||||
PktRecvRetrans uint64 // Number of retransmitted packets registered at the receiver side
|
||||
PktSentACK uint64 // Number of sent ACK (Acknowledgement) control packets
|
||||
PktRecvACK uint64 // Number of received ACK (Acknowledgement) control packets
|
||||
PktSentNAK uint64 // Number of sent NAK (Negative Acknowledgement) control packets
|
||||
PktRecvNAK uint64 // Number of received NAK (Negative Acknowledgement) control packets
|
||||
|
||||
MbpsSendRate float64 // Sending rate, in Mbps
|
||||
MbpsRecvRate float64 // Receiving rate, in Mbps
|
||||
|
||||
UsSndDuration uint64 // Accumulated time in microseconds, during which the SRT sender has some data to transmit, including packets that have been sent, but not yet acknowledged
|
||||
|
||||
PktReorderDistance uint64
|
||||
PktRecvBelated uint64 // Number of packets that arrive too late
|
||||
PktSndDrop uint64 // Number of dropped by the SRT sender DATA packets that have no chance to be delivered in time
|
||||
PktRecvDrop uint64 // Number of dropped by the SRT receiver and, as a result, not delivered to the upstream application DATA packets
|
||||
PktRecvUndecrypt uint64 // Number of packets that failed to be decrypted at the receiver side
|
||||
|
||||
ByteSent uint64 // Same as pktSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecv uint64 // Same as pktRecv, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSentUnique uint64 // Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvUnique uint64 // Same as pktRecvUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvLoss uint64 // Same as pktRecvLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size
|
||||
ByteRetrans uint64 // Same as pktRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvRetrans uint64 // Same as pktRecvRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvBelated uint64 // Same as pktRecvBelated, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteSendDrop uint64 // Same as pktSendDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvDrop uint64 // Same as pktRecvDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
ByteRecvUndecrypt uint64 // Same as pktRecvUndecrypt, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
|
||||
}
|
||||
|
||||
type StatisticsInstantaneous struct {
|
||||
UsPktSendPeriod float64 // Current minimum time interval between which consecutive packets are sent, in microseconds
|
||||
PktFlowWindow uint64 // The maximum number of packets that can be "in flight"
|
||||
PktFlightSize uint64 // The number of packets in flight
|
||||
MsRTT float64 // Smoothed round-trip time (SRTT), an exponentially-weighted moving average (EWMA) of an endpoint's RTT samples, in milliseconds
|
||||
MbpsSentRate float64 // Current transmission bandwidth, in Mbps
|
||||
MbpsRecvRate float64 // Current receiving bandwidth, in Mbps
|
||||
MbpsLinkCapacity float64 // Estimated capacity of the network link, in Mbps
|
||||
ByteAvailSendBuf uint64 // The available space in the sender's buffer, in bytes
|
||||
ByteAvailRecvBuf uint64 // The available space in the receiver's buffer, in bytes
|
||||
MbpsMaxBW float64 // Transmission bandwidth limit, in Mbps
|
||||
ByteMSS uint64 // Maximum Segment Size (MSS), in bytes
|
||||
PktSendBuf uint64 // The number of packets in the sender's buffer that are already scheduled for sending or even possibly sent, but not yet acknowledged
|
||||
ByteSendBuf uint64 // Instantaneous (current) value of pktSndBuf, but expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
MsSendBuf uint64 // The timespan (msec) of packets in the sender's buffer (unacknowledged packets)
|
||||
MsSendTsbPdDelay uint64 // Timestamp-based Packet Delivery Delay value of the peer
|
||||
PktRecvBuf uint64 // The number of acknowledged packets in receiver's buffer
|
||||
ByteRecvBuf uint64 // Instantaneous (current) value of pktRcvBuf, expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
||||
MsRecvBuf uint64 // The timespan (msec) of acknowledged packets in the receiver's buffer
|
||||
MsRecvTsbPdDelay uint64 // Timestamp-based Packet Delivery Delay value set on the socket via SRTO_RCVLATENCY or SRTO_LATENCY
|
||||
PktReorderTolerance uint64 // Instant value of the packet reorder tolerance
|
||||
PktRecvAvgBelatedTime uint64 // Accumulated difference between the current time and the time-to-play of a packet that is received late
|
||||
PktSendLossRate float64 // Percentage of resent data vs. sent data
|
||||
PktRecvLossRate float64 // Percentage of retransmitted data vs. received data
|
||||
}
|
||||
|
||||
2
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
2
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
@ -1,7 +1,7 @@
|
||||
Package validator
|
||||
=================
|
||||
<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||

|
||||

|
||||
[](https://travis-ci.org/go-playground/validator)
|
||||
[](https://coveralls.io/github/go-playground/validator?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/go-playground/validator)
|
||||
|
||||
11
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
11
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
@ -1484,10 +1484,15 @@ func isAlphaUnicode(fl FieldLevel) bool {
|
||||
return alphaUnicodeRegex.MatchString(fl.Field().String())
|
||||
}
|
||||
|
||||
// isBoolean is the validation function for validating if the current field's value can be safely converted to a boolean.
|
||||
// isBoolean is the validation function for validating if the current field's value is a valid boolean value or can be safely converted to a boolean value.
|
||||
func isBoolean(fl FieldLevel) bool {
|
||||
_, err := strconv.ParseBool(fl.Field().String())
|
||||
return err == nil
|
||||
switch fl.Field().Kind() {
|
||||
case reflect.Bool:
|
||||
return true
|
||||
default:
|
||||
_, err := strconv.ParseBool(fl.Field().String())
|
||||
return err == nil
|
||||
}
|
||||
}
|
||||
|
||||
// isDefault is the opposite of required aka hasValue
|
||||
|
||||
121
vendor/github.com/klauspost/cpuid/v2/README.md
generated
vendored
121
vendor/github.com/klauspost/cpuid/v2/README.md
generated
vendored
@ -132,6 +132,127 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
## commandline
|
||||
|
||||
Download as binary from: https://github.com/klauspost/cpuid/releases
|
||||
|
||||
Install from source:
|
||||
|
||||
`go install github.com/klauspost/cpuid/v2/cmd/cpuid@latest`
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
λ cpuid
|
||||
Name: AMD Ryzen 9 3950X 16-Core Processor
|
||||
Vendor String: AuthenticAMD
|
||||
Vendor ID: AMD
|
||||
PhysicalCores: 16
|
||||
Threads Per Core: 2
|
||||
Logical Cores: 32
|
||||
CPU Family 23 Model: 113
|
||||
Features: ADX,AESNI,AVX,AVX2,BMI1,BMI2,CLMUL,CLZERO,CMOV,CMPXCHG8,CPBOOST,CX16,F16C,FMA3,FXSR,FXSROPT,HTT,HYPERVISOR,LAHF,LZCNT,MCAOVERFLOW,MMX,MMXEXT,MOVBE,NX,OSXSAVE,POPCNT,RDRAND,RDSEED,RDTSCP,SCE,SHA,SSE,SSE2,SSE3,SSE4,SSE42,SSE4A,SSSE3,SUCCOR,X87,XSAVE
|
||||
Microarchitecture level: 3
|
||||
Cacheline bytes: 64
|
||||
L1 Instruction Cache: 32768 bytes
|
||||
L1 Data Cache: 32768 bytes
|
||||
L2 Cache: 524288 bytes
|
||||
L3 Cache: 16777216 bytes
|
||||
|
||||
```
|
||||
### JSON Output:
|
||||
|
||||
```
|
||||
λ cpuid --json
|
||||
{
|
||||
"BrandName": "AMD Ryzen 9 3950X 16-Core Processor",
|
||||
"VendorID": 2,
|
||||
"VendorString": "AuthenticAMD",
|
||||
"PhysicalCores": 16,
|
||||
"ThreadsPerCore": 2,
|
||||
"LogicalCores": 32,
|
||||
"Family": 23,
|
||||
"Model": 113,
|
||||
"CacheLine": 64,
|
||||
"Hz": 0,
|
||||
"BoostFreq": 0,
|
||||
"Cache": {
|
||||
"L1I": 32768,
|
||||
"L1D": 32768,
|
||||
"L2": 524288,
|
||||
"L3": 16777216
|
||||
},
|
||||
"SGX": {
|
||||
"Available": false,
|
||||
"LaunchControl": false,
|
||||
"SGX1Supported": false,
|
||||
"SGX2Supported": false,
|
||||
"MaxEnclaveSizeNot64": 0,
|
||||
"MaxEnclaveSize64": 0,
|
||||
"EPCSections": null
|
||||
},
|
||||
"Features": [
|
||||
"ADX",
|
||||
"AESNI",
|
||||
"AVX",
|
||||
"AVX2",
|
||||
"BMI1",
|
||||
"BMI2",
|
||||
"CLMUL",
|
||||
"CLZERO",
|
||||
"CMOV",
|
||||
"CMPXCHG8",
|
||||
"CPBOOST",
|
||||
"CX16",
|
||||
"F16C",
|
||||
"FMA3",
|
||||
"FXSR",
|
||||
"FXSROPT",
|
||||
"HTT",
|
||||
"HYPERVISOR",
|
||||
"LAHF",
|
||||
"LZCNT",
|
||||
"MCAOVERFLOW",
|
||||
"MMX",
|
||||
"MMXEXT",
|
||||
"MOVBE",
|
||||
"NX",
|
||||
"OSXSAVE",
|
||||
"POPCNT",
|
||||
"RDRAND",
|
||||
"RDSEED",
|
||||
"RDTSCP",
|
||||
"SCE",
|
||||
"SHA",
|
||||
"SSE",
|
||||
"SSE2",
|
||||
"SSE3",
|
||||
"SSE4",
|
||||
"SSE42",
|
||||
"SSE4A",
|
||||
"SSSE3",
|
||||
"SUCCOR",
|
||||
"X87",
|
||||
"XSAVE"
|
||||
],
|
||||
"X64Level": 3
|
||||
}
|
||||
```
|
||||
|
||||
### Check CPU microarch level
|
||||
|
||||
```
|
||||
λ cpuid --check-level=3
|
||||
2022/03/18 17:04:40 AMD Ryzen 9 3950X 16-Core Processor
|
||||
2022/03/18 17:04:40 Microarchitecture level 3 is supported. Max level is 3.
|
||||
Exit Code 0
|
||||
|
||||
λ cpuid --check-level=4
|
||||
2022/03/18 17:06:18 AMD Ryzen 9 3950X 16-Core Processor
|
||||
2022/03/18 17:06:18 Microarchitecture level 4 not supported. Max level is 3.
|
||||
Exit Code 1
|
||||
```
|
||||
|
||||
# license
|
||||
|
||||
This code is published under an MIT license. See LICENSE file for more information.
|
||||
|
||||
251
vendor/github.com/klauspost/cpuid/v2/cpuid.go
generated
vendored
251
vendor/github.com/klauspost/cpuid/v2/cpuid.go
generated
vendored
@ -14,6 +14,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/bits"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
@ -92,7 +93,8 @@ const (
|
||||
AVX512VNNI // AVX-512 Vector Neural Network Instructions
|
||||
AVX512VP2INTERSECT // AVX-512 Intersect for D/Q
|
||||
AVX512VPOPCNTDQ // AVX-512 Vector Population Count Doubleword and Quadword
|
||||
AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one.
|
||||
AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one
|
||||
AVXVNNI // AVX (VEX encoded) VNNI neural network instructions
|
||||
BMI1 // Bit Manipulation Instruction Set 1
|
||||
BMI2 // Bit Manipulation Instruction Set 2
|
||||
CETIBT // Intel CET Indirect Branch Tracking
|
||||
@ -101,21 +103,28 @@ const (
|
||||
CLMUL // Carry-less Multiplication
|
||||
CLZERO // CLZERO instruction supported
|
||||
CMOV // i686 CMOV
|
||||
CMPSB_SCADBS_SHORT // Fast short CMPSB and SCASB
|
||||
CMPXCHG8 // CMPXCHG8 instruction
|
||||
CPBOOST // Core Performance Boost
|
||||
CX16 // CMPXCHG16B Instruction
|
||||
ENQCMD // Enqueue Command
|
||||
ERMS // Enhanced REP MOVSB/STOSB
|
||||
F16C // Half-precision floating-point conversion
|
||||
FLUSH_L1D // Flush L1D cache
|
||||
FMA3 // Intel FMA 3. Does not imply AVX.
|
||||
FMA4 // Bulldozer FMA4 functions
|
||||
FSRM // Fast Short Rep Mov
|
||||
FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9
|
||||
FXSROPT // FXSAVE/FXRSTOR optimizations
|
||||
GFNI // Galois Field New Instructions
|
||||
GFNI // Galois Field New Instructions. May require other features (AVX, AVX512VL,AVX512F) based on usage.
|
||||
HLE // Hardware Lock Elision
|
||||
HRESET // If set CPU supports history reset and the IA32_HRESET_ENABLE MSR
|
||||
HTT // Hyperthreading (enabled)
|
||||
HWA // Hardware assert supported. Indicates support for MSRC001_10
|
||||
HYBRID_CPU // This part has CPUs of more than one type.
|
||||
HYPERVISOR // This bit has been reserved by Intel & AMD for use by hypervisors
|
||||
IA32_ARCH_CAP // IA32_ARCH_CAPABILITIES MSR (Intel)
|
||||
IA32_CORE_CAP // IA32_CORE_CAPABILITIES MSR
|
||||
IBPB // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
|
||||
IBS // Instruction Based Sampling (AMD)
|
||||
IBSBRNTRGT // Instruction Based Sampling Feature (AMD)
|
||||
@ -126,21 +135,30 @@ const (
|
||||
IBSOPSAM // Instruction Based Sampling Feature (AMD)
|
||||
IBSRDWROPCNT // Instruction Based Sampling Feature (AMD)
|
||||
IBSRIPINVALIDCHK // Instruction Based Sampling Feature (AMD)
|
||||
IBS_PREVENTHOST // Disallowing IBS use by the host supported
|
||||
INT_WBINVD // WBINVD/WBNOINVD are interruptible.
|
||||
INVLPGB // NVLPGB and TLBSYNC instruction supported
|
||||
LAHF // LAHF/SAHF in long mode
|
||||
LAM // If set, CPU supports Linear Address Masking
|
||||
LBRVIRT // LBR virtualization
|
||||
LZCNT // LZCNT instruction
|
||||
MCAOVERFLOW // MCA overflow recovery support.
|
||||
MCDT_NO // Processor do not exhibit MXCSR Configuration Dependent Timing behavior and do not need to mitigate it.
|
||||
MCOMMIT // MCOMMIT instruction supported
|
||||
MD_CLEAR // VERW clears CPU buffers
|
||||
MMX // standard MMX
|
||||
MMXEXT // SSE integer functions or AMD MMX ext
|
||||
MOVBE // MOVBE instruction (big-endian)
|
||||
MOVDIR64B // Move 64 Bytes as Direct Store
|
||||
MOVDIRI // Move Doubleword as Direct Store
|
||||
MOVSB_ZL // Fast Zero-Length MOVSB
|
||||
MPX // Intel MPX (Memory Protection Extensions)
|
||||
MSRIRC // Instruction Retired Counter MSR available
|
||||
MSR_PAGEFLUSH // Page Flush MSR available
|
||||
NRIPS // Indicates support for NRIP save on VMEXIT
|
||||
NX // NX (No-Execute) bit
|
||||
OSXSAVE // XSAVE enabled by OS
|
||||
PCONFIG // PCONFIG for Intel Multi-Key Total Memory Encryption
|
||||
POPCNT // POPCNT instruction
|
||||
RDPRU // RDPRU instruction supported
|
||||
RDRAND // RDRAND instruction is available
|
||||
@ -148,11 +166,21 @@ const (
|
||||
RDTSCP // RDTSCP Instruction
|
||||
RTM // Restricted Transactional Memory
|
||||
RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort.
|
||||
SCE // SYSENTER and SYSEXIT instructions
|
||||
SERIALIZE // Serialize Instruction Execution
|
||||
SEV // AMD Secure Encrypted Virtualization supported
|
||||
SEV_64BIT // AMD SEV guest execution only allowed from a 64-bit host
|
||||
SEV_ALTERNATIVE // AMD SEV Alternate Injection supported
|
||||
SEV_DEBUGSWAP // Full debug state swap supported for SEV-ES guests
|
||||
SEV_ES // AMD SEV Encrypted State supported
|
||||
SEV_RESTRICTED // AMD SEV Restricted Injection supported
|
||||
SEV_SNP // AMD SEV Secure Nested Paging supported
|
||||
SGX // Software Guard Extensions
|
||||
SGXLC // Software Guard Extensions Launch Control
|
||||
SHA // Intel SHA Extensions
|
||||
SME // AMD Secure Memory Encryption supported
|
||||
SME_COHERENT // AMD Hardware cache coherency across encryption domains enforced
|
||||
SPEC_CTRL_SSBD // Speculative Store Bypass Disable
|
||||
SRBDS_CTRL // SRBDS mitigation MSR available
|
||||
SSE // SSE functions
|
||||
SSE2 // P4 SSE functions
|
||||
SSE3 // Prescott SSE3 functions
|
||||
@ -161,17 +189,38 @@ const (
|
||||
SSE4A // AMD Barcelona microarchitecture SSE4a instructions
|
||||
SSSE3 // Conroe SSSE3 functions
|
||||
STIBP // Single Thread Indirect Branch Predictors
|
||||
STOSB_SHORT // Fast short STOSB
|
||||
SUCCOR // Software uncorrectable error containment and recovery capability.
|
||||
SVM // AMD Secure Virtual Machine
|
||||
SVMDA // Indicates support for the SVM decode assists.
|
||||
SVMFBASID // SVM, Indicates that TLB flush events, including CR3 writes and CR4.PGE toggles, flush only the current ASID's TLB entries. Also indicates support for the extended VMCBTLB_Control
|
||||
SVML // AMD SVM lock. Indicates support for SVM-Lock.
|
||||
SVMNP // AMD SVM nested paging
|
||||
SVMPF // SVM pause intercept filter. Indicates support for the pause intercept filter
|
||||
SVMPFT // SVM PAUSE filter threshold. Indicates support for the PAUSE filter cycle count threshold
|
||||
SYSCALL // System-Call Extension (SCE): SYSCALL and SYSRET instructions.
|
||||
SYSEE // SYSENTER and SYSEXIT instructions
|
||||
TBM // AMD Trailing Bit Manipulation
|
||||
TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE.
|
||||
TOPEXT // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX.
|
||||
TSCRATEMSR // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104
|
||||
TSXLDTRK // Intel TSX Suspend Load Address Tracking
|
||||
VAES // Vector AES
|
||||
VAES // Vector AES. AVX(512) versions requires additional checks.
|
||||
VMCBCLEAN // VMCB clean bits. Indicates support for VMCB clean bits.
|
||||
VMPL // AMD VM Permission Levels supported
|
||||
VMSA_REGPROT // AMD VMSA Register Protection supported
|
||||
VMX // Virtual Machine Extensions
|
||||
VPCLMULQDQ // Carry-Less Multiplication Quadword
|
||||
VPCLMULQDQ // Carry-Less Multiplication Quadword. Requires AVX for 3 register versions.
|
||||
VTE // AMD Virtual Transparent Encryption supported
|
||||
WAITPKG // TPAUSE, UMONITOR, UMWAIT
|
||||
WBNOINVD // Write Back and Do Not Invalidate Cache
|
||||
X87 // FPU
|
||||
XGETBV1 // Supports XGETBV with ECX = 1
|
||||
XOP // Bulldozer XOP functions
|
||||
XSAVE // XSAVE, XRESTOR, XSETBV, XGETBV
|
||||
XSAVEC // Supports XSAVEC and the compacted form of XRSTOR.
|
||||
XSAVEOPT // XSAVEOPT available
|
||||
XSAVES // Supports XSAVES/XRSTORS and IA32_XSS
|
||||
|
||||
// ARM features:
|
||||
AESARM // AES instructions
|
||||
@ -198,7 +247,6 @@ const (
|
||||
SM3 // SM3 instructions
|
||||
SM4 // SM4 instructions
|
||||
SVE // Scalable Vector Extension
|
||||
|
||||
// Keep it last. It automatically defines the size of []flagSet
|
||||
lastID
|
||||
|
||||
@ -216,6 +264,7 @@ type CPUInfo struct {
|
||||
LogicalCores int // Number of physical cores times threads that can run on each core through the use of hyperthreading. Will be 0 if undetectable.
|
||||
Family int // CPU family number
|
||||
Model int // CPU model number
|
||||
Stepping int // CPU stepping info
|
||||
CacheLine int // Cache line size in bytes. Will be 0 if undetectable.
|
||||
Hz int64 // Clock speed, if known, 0 otherwise. Will attempt to contain base clock speed.
|
||||
BoostFreq int64 // Max clock speed, if known, 0 otherwise
|
||||
@ -322,11 +371,21 @@ func (c CPUInfo) Has(id FeatureID) bool {
|
||||
return c.featureSet.inSet(id)
|
||||
}
|
||||
|
||||
// AnyOf returns whether the CPU supports one or more of the requested features.
|
||||
func (c CPUInfo) AnyOf(ids ...FeatureID) bool {
|
||||
for _, id := range ids {
|
||||
if c.featureSet.inSet(id) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
|
||||
var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2)
|
||||
var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3)
|
||||
var level3Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE)
|
||||
var level4Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL)
|
||||
var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2)
|
||||
var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3)
|
||||
var level3Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE)
|
||||
var level4Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL)
|
||||
|
||||
// X64Level returns the microarchitecture level detected on the CPU.
|
||||
// If features are lacking or non x64 mode, 0 is returned.
|
||||
@ -369,8 +428,9 @@ func (c CPUInfo) IsVendor(v Vendor) bool {
|
||||
return c.VendorID == v
|
||||
}
|
||||
|
||||
// FeatureSet returns all available features as strings.
|
||||
func (c CPUInfo) FeatureSet() []string {
|
||||
s := make([]string, 0)
|
||||
s := make([]string, 0, c.featureSet.nEnabled())
|
||||
s = append(s, c.featureSet.Strings()...)
|
||||
return s
|
||||
}
|
||||
@ -543,6 +603,14 @@ func (s flagSet) hasSet(other flagSet) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// nEnabled will return the number of enabled flags.
|
||||
func (s flagSet) nEnabled() (n int) {
|
||||
for _, v := range s[:] {
|
||||
n += bits.OnesCount64(uint64(v))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func flagSetWith(feat ...FeatureID) flagSet {
|
||||
var res flagSet
|
||||
for _, f := range feat {
|
||||
@ -631,7 +699,7 @@ func threadsPerCore() int {
|
||||
if vend == AMD {
|
||||
// Workaround for AMD returning 0, assume 2 if >= Zen 2
|
||||
// It will be more correct than not.
|
||||
fam, _ := familyModel()
|
||||
fam, _, _ := familyModel()
|
||||
_, _, _, d := cpuid(1)
|
||||
if (d&(1<<28)) != 0 && fam >= 23 {
|
||||
return 2
|
||||
@ -669,14 +737,27 @@ func logicalCores() int {
|
||||
}
|
||||
}
|
||||
|
||||
func familyModel() (int, int) {
|
||||
func familyModel() (family, model, stepping int) {
|
||||
if maxFunctionID() < 0x1 {
|
||||
return 0, 0
|
||||
return 0, 0, 0
|
||||
}
|
||||
eax, _, _, _ := cpuid(1)
|
||||
family := ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff)
|
||||
model := ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0)
|
||||
return int(family), int(model)
|
||||
// If BaseFamily[3:0] is less than Fh then ExtendedFamily[7:0] is reserved and Family is equal to BaseFamily[3:0].
|
||||
family = int((eax >> 8) & 0xf)
|
||||
extFam := family == 0x6 // Intel is 0x6, needs extended model.
|
||||
if family == 0xf {
|
||||
// Add ExtFamily
|
||||
family += int((eax >> 20) & 0xff)
|
||||
extFam = true
|
||||
}
|
||||
// If BaseFamily[3:0] is less than 0Fh then ExtendedModel[3:0] is reserved and Model is equal to BaseModel[3:0].
|
||||
model = int((eax >> 4) & 0xf)
|
||||
if extFam {
|
||||
// Add ExtModel
|
||||
model += int((eax >> 12) & 0xf0)
|
||||
}
|
||||
stepping = int(eax & 0xf)
|
||||
return family, model, stepping
|
||||
}
|
||||
|
||||
func physicalCores() int {
|
||||
@ -811,9 +892,14 @@ func (c *CPUInfo) cacheSize() {
|
||||
c.Cache.L2 = int(((ecx >> 16) & 0xFFFF) * 1024)
|
||||
|
||||
// CPUID Fn8000_001D_EAX_x[N:0] Cache Properties
|
||||
if maxExtendedFunction() < 0x8000001D {
|
||||
if maxExtendedFunction() < 0x8000001D || !c.Has(TOPEXT) {
|
||||
return
|
||||
}
|
||||
|
||||
// Xen Hypervisor is buggy and returns the same entry no matter ECX value.
|
||||
// Hack: When we encounter the same entry 100 times we break.
|
||||
nSame := 0
|
||||
var last uint32
|
||||
for i := uint32(0); i < math.MaxUint32; i++ {
|
||||
eax, ebx, ecx, _ := cpuidex(0x8000001D, i)
|
||||
|
||||
@ -829,6 +915,16 @@ func (c *CPUInfo) cacheSize() {
|
||||
return
|
||||
}
|
||||
|
||||
// Check for the same value repeated.
|
||||
comb := eax ^ ebx ^ ecx
|
||||
if comb == last {
|
||||
nSame++
|
||||
if nSame == 100 {
|
||||
return
|
||||
}
|
||||
}
|
||||
last = comb
|
||||
|
||||
switch level {
|
||||
case 1:
|
||||
switch typ {
|
||||
@ -913,14 +1009,13 @@ func support() flagSet {
|
||||
if mfi < 0x1 {
|
||||
return fs
|
||||
}
|
||||
family, model := familyModel()
|
||||
family, model, _ := familyModel()
|
||||
|
||||
_, _, c, d := cpuid(1)
|
||||
fs.setIf((d&(1<<0)) != 0, X87)
|
||||
fs.setIf((d&(1<<8)) != 0, CMPXCHG8)
|
||||
fs.setIf((d&(1<<11)) != 0, SCE)
|
||||
fs.setIf((d&(1<<11)) != 0, SYSEE)
|
||||
fs.setIf((d&(1<<15)) != 0, CMOV)
|
||||
fs.setIf((d&(1<<22)) != 0, MMXEXT)
|
||||
fs.setIf((d&(1<<23)) != 0, MMX)
|
||||
fs.setIf((d&(1<<24)) != 0, FXSR)
|
||||
fs.setIf((d&(1<<25)) != 0, FXSROPT)
|
||||
@ -928,9 +1023,9 @@ func support() flagSet {
|
||||
fs.setIf((d&(1<<26)) != 0, SSE2)
|
||||
fs.setIf((c&1) != 0, SSE3)
|
||||
fs.setIf((c&(1<<5)) != 0, VMX)
|
||||
fs.setIf((c&0x00000200) != 0, SSSE3)
|
||||
fs.setIf((c&0x00080000) != 0, SSE4)
|
||||
fs.setIf((c&0x00100000) != 0, SSE42)
|
||||
fs.setIf((c&(1<<9)) != 0, SSSE3)
|
||||
fs.setIf((c&(1<<19)) != 0, SSE4)
|
||||
fs.setIf((c&(1<<20)) != 0, SSE42)
|
||||
fs.setIf((c&(1<<25)) != 0, AESNI)
|
||||
fs.setIf((c&(1<<1)) != 0, CLMUL)
|
||||
fs.setIf(c&(1<<22) != 0, MOVBE)
|
||||
@ -976,7 +1071,6 @@ func support() flagSet {
|
||||
// Check AVX2, AVX2 requires OS support, but BMI1/2 don't.
|
||||
if mfi >= 7 {
|
||||
_, ebx, ecx, edx := cpuidex(7, 0)
|
||||
eax1, _, _, _ := cpuidex(7, 1)
|
||||
if fs.inSet(AVX) && (ebx&0x00000020) != 0 {
|
||||
fs.set(AVX2)
|
||||
}
|
||||
@ -993,21 +1087,45 @@ func support() flagSet {
|
||||
fs.setIf(ebx&(1<<18) != 0, RDSEED)
|
||||
fs.setIf(ebx&(1<<19) != 0, ADX)
|
||||
fs.setIf(ebx&(1<<29) != 0, SHA)
|
||||
|
||||
// CPUID.(EAX=7, ECX=0).ECX
|
||||
fs.setIf(ecx&(1<<5) != 0, WAITPKG)
|
||||
fs.setIf(ecx&(1<<7) != 0, CETSS)
|
||||
fs.setIf(ecx&(1<<8) != 0, GFNI)
|
||||
fs.setIf(ecx&(1<<9) != 0, VAES)
|
||||
fs.setIf(ecx&(1<<10) != 0, VPCLMULQDQ)
|
||||
fs.setIf(ecx&(1<<13) != 0, TME)
|
||||
fs.setIf(ecx&(1<<25) != 0, CLDEMOTE)
|
||||
fs.setIf(ecx&(1<<27) != 0, MOVDIRI)
|
||||
fs.setIf(ecx&(1<<28) != 0, MOVDIR64B)
|
||||
fs.setIf(ecx&(1<<29) != 0, ENQCMD)
|
||||
fs.setIf(ecx&(1<<30) != 0, SGXLC)
|
||||
|
||||
// CPUID.(EAX=7, ECX=0).EDX
|
||||
fs.setIf(edx&(1<<4) != 0, FSRM)
|
||||
fs.setIf(edx&(1<<9) != 0, SRBDS_CTRL)
|
||||
fs.setIf(edx&(1<<10) != 0, MD_CLEAR)
|
||||
fs.setIf(edx&(1<<11) != 0, RTM_ALWAYS_ABORT)
|
||||
fs.setIf(edx&(1<<14) != 0, SERIALIZE)
|
||||
fs.setIf(edx&(1<<15) != 0, HYBRID_CPU)
|
||||
fs.setIf(edx&(1<<16) != 0, TSXLDTRK)
|
||||
fs.setIf(edx&(1<<18) != 0, PCONFIG)
|
||||
fs.setIf(edx&(1<<20) != 0, CETIBT)
|
||||
fs.setIf(edx&(1<<26) != 0, IBPB)
|
||||
fs.setIf(edx&(1<<27) != 0, STIBP)
|
||||
fs.setIf(edx&(1<<28) != 0, FLUSH_L1D)
|
||||
fs.setIf(edx&(1<<29) != 0, IA32_ARCH_CAP)
|
||||
fs.setIf(edx&(1<<30) != 0, IA32_CORE_CAP)
|
||||
fs.setIf(edx&(1<<31) != 0, SPEC_CTRL_SSBD)
|
||||
|
||||
// CPUID.(EAX=7, ECX=1)
|
||||
eax1, _, _, _ := cpuidex(7, 1)
|
||||
fs.setIf(fs.inSet(AVX) && eax1&(1<<4) != 0, AVXVNNI)
|
||||
fs.setIf(eax1&(1<<10) != 0, MOVSB_ZL)
|
||||
fs.setIf(eax1&(1<<11) != 0, STOSB_SHORT)
|
||||
fs.setIf(eax1&(1<<12) != 0, CMPSB_SCADBS_SHORT)
|
||||
fs.setIf(eax1&(1<<22) != 0, HRESET)
|
||||
fs.setIf(eax1&(1<<26) != 0, LAM)
|
||||
|
||||
// Only detect AVX-512 features if XGETBV is supported
|
||||
if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) {
|
||||
@ -1033,9 +1151,6 @@ func support() flagSet {
|
||||
// ecx
|
||||
fs.setIf(ecx&(1<<1) != 0, AVX512VBMI)
|
||||
fs.setIf(ecx&(1<<6) != 0, AVX512VBMI2)
|
||||
fs.setIf(ecx&(1<<8) != 0, GFNI)
|
||||
fs.setIf(ecx&(1<<9) != 0, VAES)
|
||||
fs.setIf(ecx&(1<<10) != 0, VPCLMULQDQ)
|
||||
fs.setIf(ecx&(1<<11) != 0, AVX512VNNI)
|
||||
fs.setIf(ecx&(1<<12) != 0, AVX512BITALG)
|
||||
fs.setIf(ecx&(1<<14) != 0, AVX512VPOPCNTDQ)
|
||||
@ -1049,29 +1164,63 @@ func support() flagSet {
|
||||
fs.setIf(eax1&(1<<5) != 0, AVX512BF16)
|
||||
}
|
||||
}
|
||||
|
||||
// CPUID.(EAX=7, ECX=2)
|
||||
_, _, _, edx = cpuidex(7, 2)
|
||||
fs.setIf(edx&(1<<5) != 0, MCDT_NO)
|
||||
}
|
||||
|
||||
// Processor Extended State Enumeration Sub-leaf (EAX = 0DH, ECX = 1)
|
||||
// EAX
|
||||
// Bit 00: XSAVEOPT is available.
|
||||
// Bit 01: Supports XSAVEC and the compacted form of XRSTOR if set.
|
||||
// Bit 02: Supports XGETBV with ECX = 1 if set.
|
||||
// Bit 03: Supports XSAVES/XRSTORS and IA32_XSS if set.
|
||||
// Bits 31 - 04: Reserved.
|
||||
// EBX
|
||||
// Bits 31 - 00: The size in bytes of the XSAVE area containing all states enabled by XCRO | IA32_XSS.
|
||||
// ECX
|
||||
// Bits 31 - 00: Reports the supported bits of the lower 32 bits of the IA32_XSS MSR. IA32_XSS[n] can be set to 1 only if ECX[n] is 1.
|
||||
// EDX?
|
||||
// Bits 07 - 00: Used for XCR0. Bit 08: PT state. Bit 09: Used for XCR0. Bits 12 - 10: Reserved. Bit 13: HWP state. Bits 31 - 14: Reserved.
|
||||
if mfi >= 0xd {
|
||||
if fs.inSet(XSAVE) {
|
||||
eax, _, _, _ := cpuidex(0xd, 1)
|
||||
fs.setIf(eax&(1<<0) != 0, XSAVEOPT)
|
||||
fs.setIf(eax&(1<<1) != 0, XSAVEC)
|
||||
fs.setIf(eax&(1<<2) != 0, XGETBV1)
|
||||
fs.setIf(eax&(1<<3) != 0, XSAVES)
|
||||
}
|
||||
}
|
||||
if maxExtendedFunction() >= 0x80000001 {
|
||||
_, _, c, d := cpuid(0x80000001)
|
||||
if (c & (1 << 5)) != 0 {
|
||||
fs.set(LZCNT)
|
||||
fs.set(POPCNT)
|
||||
}
|
||||
// ECX
|
||||
fs.setIf((c&(1<<0)) != 0, LAHF)
|
||||
fs.setIf((c&(1<<10)) != 0, IBS)
|
||||
fs.setIf((d&(1<<31)) != 0, AMD3DNOW)
|
||||
fs.setIf((d&(1<<30)) != 0, AMD3DNOWEXT)
|
||||
fs.setIf((d&(1<<23)) != 0, MMX)
|
||||
fs.setIf((d&(1<<22)) != 0, MMXEXT)
|
||||
fs.setIf((c&(1<<2)) != 0, SVM)
|
||||
fs.setIf((c&(1<<6)) != 0, SSE4A)
|
||||
fs.setIf((c&(1<<10)) != 0, IBS)
|
||||
fs.setIf((c&(1<<22)) != 0, TOPEXT)
|
||||
|
||||
// EDX
|
||||
fs.setIf(d&(1<<11) != 0, SYSCALL)
|
||||
fs.setIf(d&(1<<20) != 0, NX)
|
||||
fs.setIf(d&(1<<22) != 0, MMXEXT)
|
||||
fs.setIf(d&(1<<23) != 0, MMX)
|
||||
fs.setIf(d&(1<<24) != 0, FXSR)
|
||||
fs.setIf(d&(1<<25) != 0, FXSROPT)
|
||||
fs.setIf(d&(1<<27) != 0, RDTSCP)
|
||||
fs.setIf(d&(1<<30) != 0, AMD3DNOWEXT)
|
||||
fs.setIf(d&(1<<31) != 0, AMD3DNOW)
|
||||
|
||||
/* XOP and FMA4 use the AVX instruction coding scheme, so they can't be
|
||||
* used unless the OS has AVX support. */
|
||||
if fs.inSet(AVX) {
|
||||
fs.setIf((c&0x00000800) != 0, XOP)
|
||||
fs.setIf((c&0x00010000) != 0, FMA4)
|
||||
fs.setIf((c&(1<<11)) != 0, XOP)
|
||||
fs.setIf((c&(1<<16)) != 0, FMA4)
|
||||
}
|
||||
|
||||
}
|
||||
@ -1094,6 +1243,20 @@ func support() flagSet {
|
||||
fs.setIf((b&(1<<0)) != 0, CLZERO)
|
||||
}
|
||||
|
||||
if fs.inSet(SVM) && maxExtendedFunction() >= 0x8000000A {
|
||||
_, _, _, edx := cpuid(0x8000000A)
|
||||
fs.setIf((edx>>0)&1 == 1, SVMNP)
|
||||
fs.setIf((edx>>1)&1 == 1, LBRVIRT)
|
||||
fs.setIf((edx>>2)&1 == 1, SVML)
|
||||
fs.setIf((edx>>3)&1 == 1, NRIPS)
|
||||
fs.setIf((edx>>4)&1 == 1, TSCRATEMSR)
|
||||
fs.setIf((edx>>5)&1 == 1, VMCBCLEAN)
|
||||
fs.setIf((edx>>6)&1 == 1, SVMFBASID)
|
||||
fs.setIf((edx>>7)&1 == 1, SVMDA)
|
||||
fs.setIf((edx>>10)&1 == 1, SVMPF)
|
||||
fs.setIf((edx>>12)&1 == 1, SVMPFT)
|
||||
}
|
||||
|
||||
if maxExtendedFunction() >= 0x8000001b && fs.inSet(IBS) {
|
||||
eax, _, _, _ := cpuid(0x8000001b)
|
||||
fs.setIf((eax>>0)&1 == 1, IBSFFV)
|
||||
@ -1106,6 +1269,24 @@ func support() flagSet {
|
||||
fs.setIf((eax>>7)&1 == 1, IBSRIPINVALIDCHK)
|
||||
}
|
||||
|
||||
if maxExtendedFunction() >= 0x8000001f && vend == AMD {
|
||||
a, _, _, _ := cpuid(0x8000001f)
|
||||
fs.setIf((a>>0)&1 == 1, SME)
|
||||
fs.setIf((a>>1)&1 == 1, SEV)
|
||||
fs.setIf((a>>2)&1 == 1, MSR_PAGEFLUSH)
|
||||
fs.setIf((a>>3)&1 == 1, SEV_ES)
|
||||
fs.setIf((a>>4)&1 == 1, SEV_SNP)
|
||||
fs.setIf((a>>5)&1 == 1, VMPL)
|
||||
fs.setIf((a>>10)&1 == 1, SME_COHERENT)
|
||||
fs.setIf((a>>11)&1 == 1, SEV_64BIT)
|
||||
fs.setIf((a>>12)&1 == 1, SEV_RESTRICTED)
|
||||
fs.setIf((a>>13)&1 == 1, SEV_ALTERNATIVE)
|
||||
fs.setIf((a>>14)&1 == 1, SEV_DEBUGSWAP)
|
||||
fs.setIf((a>>15)&1 == 1, IBS_PREVENTHOST)
|
||||
fs.setIf((a>>16)&1 == 1, VTE)
|
||||
fs.setIf((a>>24)&1 == 1, VMSA_REGPROT)
|
||||
}
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/klauspost/cpuid/v2/detect_x86.go
generated
vendored
2
vendor/github.com/klauspost/cpuid/v2/detect_x86.go
generated
vendored
@ -24,7 +24,7 @@ func addInfo(c *CPUInfo, safe bool) {
|
||||
c.maxExFunc = maxExtendedFunction()
|
||||
c.BrandName = brandName()
|
||||
c.CacheLine = cacheLine()
|
||||
c.Family, c.Model = familyModel()
|
||||
c.Family, c.Model, c.Stepping = familyModel()
|
||||
c.featureSet = support()
|
||||
c.SGX = hasSGX(c.featureSet.inSet(SGX), c.featureSet.inSet(SGXLC))
|
||||
c.ThreadsPerCore = threadsPerCore()
|
||||
|
||||
260
vendor/github.com/klauspost/cpuid/v2/featureid_string.go
generated
vendored
260
vendor/github.com/klauspost/cpuid/v2/featureid_string.go
generated
vendored
@ -34,116 +34,164 @@ func _() {
|
||||
_ = x[AVX512VP2INTERSECT-24]
|
||||
_ = x[AVX512VPOPCNTDQ-25]
|
||||
_ = x[AVXSLOW-26]
|
||||
_ = x[BMI1-27]
|
||||
_ = x[BMI2-28]
|
||||
_ = x[CETIBT-29]
|
||||
_ = x[CETSS-30]
|
||||
_ = x[CLDEMOTE-31]
|
||||
_ = x[CLMUL-32]
|
||||
_ = x[CLZERO-33]
|
||||
_ = x[CMOV-34]
|
||||
_ = x[CMPXCHG8-35]
|
||||
_ = x[CPBOOST-36]
|
||||
_ = x[CX16-37]
|
||||
_ = x[ENQCMD-38]
|
||||
_ = x[ERMS-39]
|
||||
_ = x[F16C-40]
|
||||
_ = x[FMA3-41]
|
||||
_ = x[FMA4-42]
|
||||
_ = x[FXSR-43]
|
||||
_ = x[FXSROPT-44]
|
||||
_ = x[GFNI-45]
|
||||
_ = x[HLE-46]
|
||||
_ = x[HTT-47]
|
||||
_ = x[HWA-48]
|
||||
_ = x[HYPERVISOR-49]
|
||||
_ = x[IBPB-50]
|
||||
_ = x[IBS-51]
|
||||
_ = x[IBSBRNTRGT-52]
|
||||
_ = x[IBSFETCHSAM-53]
|
||||
_ = x[IBSFFV-54]
|
||||
_ = x[IBSOPCNT-55]
|
||||
_ = x[IBSOPCNTEXT-56]
|
||||
_ = x[IBSOPSAM-57]
|
||||
_ = x[IBSRDWROPCNT-58]
|
||||
_ = x[IBSRIPINVALIDCHK-59]
|
||||
_ = x[INT_WBINVD-60]
|
||||
_ = x[INVLPGB-61]
|
||||
_ = x[LAHF-62]
|
||||
_ = x[LZCNT-63]
|
||||
_ = x[MCAOVERFLOW-64]
|
||||
_ = x[MCOMMIT-65]
|
||||
_ = x[MMX-66]
|
||||
_ = x[MMXEXT-67]
|
||||
_ = x[MOVBE-68]
|
||||
_ = x[MOVDIR64B-69]
|
||||
_ = x[MOVDIRI-70]
|
||||
_ = x[MPX-71]
|
||||
_ = x[MSRIRC-72]
|
||||
_ = x[NX-73]
|
||||
_ = x[OSXSAVE-74]
|
||||
_ = x[POPCNT-75]
|
||||
_ = x[RDPRU-76]
|
||||
_ = x[RDRAND-77]
|
||||
_ = x[RDSEED-78]
|
||||
_ = x[RDTSCP-79]
|
||||
_ = x[RTM-80]
|
||||
_ = x[RTM_ALWAYS_ABORT-81]
|
||||
_ = x[SCE-82]
|
||||
_ = x[SERIALIZE-83]
|
||||
_ = x[SGX-84]
|
||||
_ = x[SGXLC-85]
|
||||
_ = x[SHA-86]
|
||||
_ = x[SSE-87]
|
||||
_ = x[SSE2-88]
|
||||
_ = x[SSE3-89]
|
||||
_ = x[SSE4-90]
|
||||
_ = x[SSE42-91]
|
||||
_ = x[SSE4A-92]
|
||||
_ = x[SSSE3-93]
|
||||
_ = x[STIBP-94]
|
||||
_ = x[SUCCOR-95]
|
||||
_ = x[TBM-96]
|
||||
_ = x[TSXLDTRK-97]
|
||||
_ = x[VAES-98]
|
||||
_ = x[VMX-99]
|
||||
_ = x[VPCLMULQDQ-100]
|
||||
_ = x[WAITPKG-101]
|
||||
_ = x[WBNOINVD-102]
|
||||
_ = x[X87-103]
|
||||
_ = x[XOP-104]
|
||||
_ = x[XSAVE-105]
|
||||
_ = x[AESARM-106]
|
||||
_ = x[ARMCPUID-107]
|
||||
_ = x[ASIMD-108]
|
||||
_ = x[ASIMDDP-109]
|
||||
_ = x[ASIMDHP-110]
|
||||
_ = x[ASIMDRDM-111]
|
||||
_ = x[ATOMICS-112]
|
||||
_ = x[CRC32-113]
|
||||
_ = x[DCPOP-114]
|
||||
_ = x[EVTSTRM-115]
|
||||
_ = x[FCMA-116]
|
||||
_ = x[FP-117]
|
||||
_ = x[FPHP-118]
|
||||
_ = x[GPA-119]
|
||||
_ = x[JSCVT-120]
|
||||
_ = x[LRCPC-121]
|
||||
_ = x[PMULL-122]
|
||||
_ = x[SHA1-123]
|
||||
_ = x[SHA2-124]
|
||||
_ = x[SHA3-125]
|
||||
_ = x[SHA512-126]
|
||||
_ = x[SM3-127]
|
||||
_ = x[SM4-128]
|
||||
_ = x[SVE-129]
|
||||
_ = x[lastID-130]
|
||||
_ = x[AVXVNNI-27]
|
||||
_ = x[BMI1-28]
|
||||
_ = x[BMI2-29]
|
||||
_ = x[CETIBT-30]
|
||||
_ = x[CETSS-31]
|
||||
_ = x[CLDEMOTE-32]
|
||||
_ = x[CLMUL-33]
|
||||
_ = x[CLZERO-34]
|
||||
_ = x[CMOV-35]
|
||||
_ = x[CMPSB_SCADBS_SHORT-36]
|
||||
_ = x[CMPXCHG8-37]
|
||||
_ = x[CPBOOST-38]
|
||||
_ = x[CX16-39]
|
||||
_ = x[ENQCMD-40]
|
||||
_ = x[ERMS-41]
|
||||
_ = x[F16C-42]
|
||||
_ = x[FLUSH_L1D-43]
|
||||
_ = x[FMA3-44]
|
||||
_ = x[FMA4-45]
|
||||
_ = x[FSRM-46]
|
||||
_ = x[FXSR-47]
|
||||
_ = x[FXSROPT-48]
|
||||
_ = x[GFNI-49]
|
||||
_ = x[HLE-50]
|
||||
_ = x[HRESET-51]
|
||||
_ = x[HTT-52]
|
||||
_ = x[HWA-53]
|
||||
_ = x[HYBRID_CPU-54]
|
||||
_ = x[HYPERVISOR-55]
|
||||
_ = x[IA32_ARCH_CAP-56]
|
||||
_ = x[IA32_CORE_CAP-57]
|
||||
_ = x[IBPB-58]
|
||||
_ = x[IBS-59]
|
||||
_ = x[IBSBRNTRGT-60]
|
||||
_ = x[IBSFETCHSAM-61]
|
||||
_ = x[IBSFFV-62]
|
||||
_ = x[IBSOPCNT-63]
|
||||
_ = x[IBSOPCNTEXT-64]
|
||||
_ = x[IBSOPSAM-65]
|
||||
_ = x[IBSRDWROPCNT-66]
|
||||
_ = x[IBSRIPINVALIDCHK-67]
|
||||
_ = x[IBS_PREVENTHOST-68]
|
||||
_ = x[INT_WBINVD-69]
|
||||
_ = x[INVLPGB-70]
|
||||
_ = x[LAHF-71]
|
||||
_ = x[LAM-72]
|
||||
_ = x[LBRVIRT-73]
|
||||
_ = x[LZCNT-74]
|
||||
_ = x[MCAOVERFLOW-75]
|
||||
_ = x[MCDT_NO-76]
|
||||
_ = x[MCOMMIT-77]
|
||||
_ = x[MD_CLEAR-78]
|
||||
_ = x[MMX-79]
|
||||
_ = x[MMXEXT-80]
|
||||
_ = x[MOVBE-81]
|
||||
_ = x[MOVDIR64B-82]
|
||||
_ = x[MOVDIRI-83]
|
||||
_ = x[MOVSB_ZL-84]
|
||||
_ = x[MPX-85]
|
||||
_ = x[MSRIRC-86]
|
||||
_ = x[MSR_PAGEFLUSH-87]
|
||||
_ = x[NRIPS-88]
|
||||
_ = x[NX-89]
|
||||
_ = x[OSXSAVE-90]
|
||||
_ = x[PCONFIG-91]
|
||||
_ = x[POPCNT-92]
|
||||
_ = x[RDPRU-93]
|
||||
_ = x[RDRAND-94]
|
||||
_ = x[RDSEED-95]
|
||||
_ = x[RDTSCP-96]
|
||||
_ = x[RTM-97]
|
||||
_ = x[RTM_ALWAYS_ABORT-98]
|
||||
_ = x[SERIALIZE-99]
|
||||
_ = x[SEV-100]
|
||||
_ = x[SEV_64BIT-101]
|
||||
_ = x[SEV_ALTERNATIVE-102]
|
||||
_ = x[SEV_DEBUGSWAP-103]
|
||||
_ = x[SEV_ES-104]
|
||||
_ = x[SEV_RESTRICTED-105]
|
||||
_ = x[SEV_SNP-106]
|
||||
_ = x[SGX-107]
|
||||
_ = x[SGXLC-108]
|
||||
_ = x[SHA-109]
|
||||
_ = x[SME-110]
|
||||
_ = x[SME_COHERENT-111]
|
||||
_ = x[SPEC_CTRL_SSBD-112]
|
||||
_ = x[SRBDS_CTRL-113]
|
||||
_ = x[SSE-114]
|
||||
_ = x[SSE2-115]
|
||||
_ = x[SSE3-116]
|
||||
_ = x[SSE4-117]
|
||||
_ = x[SSE42-118]
|
||||
_ = x[SSE4A-119]
|
||||
_ = x[SSSE3-120]
|
||||
_ = x[STIBP-121]
|
||||
_ = x[STOSB_SHORT-122]
|
||||
_ = x[SUCCOR-123]
|
||||
_ = x[SVM-124]
|
||||
_ = x[SVMDA-125]
|
||||
_ = x[SVMFBASID-126]
|
||||
_ = x[SVML-127]
|
||||
_ = x[SVMNP-128]
|
||||
_ = x[SVMPF-129]
|
||||
_ = x[SVMPFT-130]
|
||||
_ = x[SYSCALL-131]
|
||||
_ = x[SYSEE-132]
|
||||
_ = x[TBM-133]
|
||||
_ = x[TME-134]
|
||||
_ = x[TOPEXT-135]
|
||||
_ = x[TSCRATEMSR-136]
|
||||
_ = x[TSXLDTRK-137]
|
||||
_ = x[VAES-138]
|
||||
_ = x[VMCBCLEAN-139]
|
||||
_ = x[VMPL-140]
|
||||
_ = x[VMSA_REGPROT-141]
|
||||
_ = x[VMX-142]
|
||||
_ = x[VPCLMULQDQ-143]
|
||||
_ = x[VTE-144]
|
||||
_ = x[WAITPKG-145]
|
||||
_ = x[WBNOINVD-146]
|
||||
_ = x[X87-147]
|
||||
_ = x[XGETBV1-148]
|
||||
_ = x[XOP-149]
|
||||
_ = x[XSAVE-150]
|
||||
_ = x[XSAVEC-151]
|
||||
_ = x[XSAVEOPT-152]
|
||||
_ = x[XSAVES-153]
|
||||
_ = x[AESARM-154]
|
||||
_ = x[ARMCPUID-155]
|
||||
_ = x[ASIMD-156]
|
||||
_ = x[ASIMDDP-157]
|
||||
_ = x[ASIMDHP-158]
|
||||
_ = x[ASIMDRDM-159]
|
||||
_ = x[ATOMICS-160]
|
||||
_ = x[CRC32-161]
|
||||
_ = x[DCPOP-162]
|
||||
_ = x[EVTSTRM-163]
|
||||
_ = x[FCMA-164]
|
||||
_ = x[FP-165]
|
||||
_ = x[FPHP-166]
|
||||
_ = x[GPA-167]
|
||||
_ = x[JSCVT-168]
|
||||
_ = x[LRCPC-169]
|
||||
_ = x[PMULL-170]
|
||||
_ = x[SHA1-171]
|
||||
_ = x[SHA2-172]
|
||||
_ = x[SHA3-173]
|
||||
_ = x[SHA512-174]
|
||||
_ = x[SM3-175]
|
||||
_ = x[SM4-176]
|
||||
_ = x[SVE-177]
|
||||
_ = x[lastID-178]
|
||||
_ = x[firstID-0]
|
||||
}
|
||||
|
||||
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPXCHG8CPBOOSTCX16ENQCMDERMSF16CFMA3FMA4FXSRFXSROPTGFNIHLEHTTHWAHYPERVISORIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKINT_WBINVDINVLPGBLAHFLZCNTMCAOVERFLOWMCOMMITMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMPXMSRIRCNXOSXSAVEPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSCESERIALIZESGXSGXLCSHASSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSUCCORTBMTSXLDTRKVAESVMXVPCLMULQDQWAITPKGWBNOINVDX87XOPXSAVEAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
|
||||
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWAVXVNNIBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCX16ENQCMDERMSF16CFLUSH_L1DFMA3FMA4FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_PREVENTHOSTINT_WBINVDINVLPGBLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMPXMSRIRCMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
|
||||
|
||||
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 234, 238, 244, 249, 257, 262, 268, 272, 280, 287, 291, 297, 301, 305, 309, 313, 317, 324, 328, 331, 334, 337, 347, 351, 354, 364, 375, 381, 389, 400, 408, 420, 436, 446, 453, 457, 462, 473, 480, 483, 489, 494, 503, 510, 513, 519, 521, 528, 534, 539, 545, 551, 557, 560, 576, 579, 588, 591, 596, 599, 602, 606, 610, 614, 619, 624, 629, 634, 640, 643, 651, 655, 658, 668, 675, 683, 686, 689, 694, 700, 708, 713, 720, 727, 735, 742, 747, 752, 759, 763, 765, 769, 772, 777, 782, 787, 791, 795, 799, 805, 808, 811, 814, 820}
|
||||
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 237, 241, 245, 251, 256, 264, 269, 275, 279, 297, 305, 312, 316, 322, 326, 330, 339, 343, 347, 351, 355, 362, 366, 369, 375, 378, 381, 391, 401, 414, 427, 431, 434, 444, 455, 461, 469, 480, 488, 500, 516, 531, 541, 548, 552, 555, 562, 567, 578, 585, 592, 600, 603, 609, 614, 623, 630, 638, 641, 647, 660, 665, 667, 674, 681, 687, 692, 698, 704, 710, 713, 729, 738, 741, 750, 765, 778, 784, 798, 805, 808, 813, 816, 819, 831, 845, 855, 858, 862, 866, 870, 875, 880, 885, 890, 901, 907, 910, 915, 924, 928, 933, 938, 944, 951, 956, 959, 962, 968, 978, 986, 990, 999, 1003, 1015, 1018, 1028, 1031, 1038, 1046, 1049, 1056, 1059, 1064, 1070, 1078, 1084, 1090, 1098, 1103, 1110, 1117, 1125, 1132, 1137, 1142, 1149, 1153, 1155, 1159, 1162, 1167, 1172, 1177, 1181, 1185, 1189, 1195, 1198, 1201, 1204, 1210}
|
||||
|
||||
func (i FeatureID) String() string {
|
||||
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {
|
||||
|
||||
112
vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go
generated
vendored
112
vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go
generated
vendored
@ -2,18 +2,120 @@
|
||||
|
||||
package cpuid
|
||||
|
||||
import "runtime"
|
||||
import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func detectOS(c *CPUInfo) bool {
|
||||
if runtime.GOOS != "ios" {
|
||||
tryToFillCPUInfoFomSysctl(c)
|
||||
}
|
||||
// There are no hw.optional sysctl values for the below features on Mac OS 11.0
|
||||
// to detect their supported state dynamically. Assume the CPU features that
|
||||
// Apple Silicon M1 supports to be available as a minimal set of features
|
||||
// to all Go programs running on darwin/arm64.
|
||||
// TODO: Add more if we know them.
|
||||
c.featureSet.setIf(runtime.GOOS != "ios", AESARM, PMULL, SHA1, SHA2)
|
||||
c.PhysicalCores = runtime.NumCPU()
|
||||
// For now assuming 1 thread per core...
|
||||
c.ThreadsPerCore = 1
|
||||
c.LogicalCores = c.PhysicalCores
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func sysctlGetBool(name string) bool {
|
||||
value, err := unix.SysctlUint32(name)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return value != 0
|
||||
}
|
||||
|
||||
func sysctlGetString(name string) string {
|
||||
value, err := unix.Sysctl(name)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func sysctlGetInt(unknown int, names ...string) int {
|
||||
for _, name := range names {
|
||||
value, err := unix.SysctlUint32(name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if value != 0 {
|
||||
return int(value)
|
||||
}
|
||||
}
|
||||
return unknown
|
||||
}
|
||||
|
||||
func sysctlGetInt64(unknown int, names ...string) int {
|
||||
for _, name := range names {
|
||||
value64, err := unix.SysctlUint64(name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if int(value64) != unknown {
|
||||
return int(value64)
|
||||
}
|
||||
}
|
||||
return unknown
|
||||
}
|
||||
|
||||
func setFeature(c *CPUInfo, name string, feature FeatureID) {
|
||||
c.featureSet.setIf(sysctlGetBool(name), feature)
|
||||
}
|
||||
func tryToFillCPUInfoFomSysctl(c *CPUInfo) {
|
||||
c.BrandName = sysctlGetString("machdep.cpu.brand_string")
|
||||
|
||||
if len(c.BrandName) != 0 {
|
||||
c.VendorString = strings.Fields(c.BrandName)[0]
|
||||
}
|
||||
|
||||
c.PhysicalCores = sysctlGetInt(runtime.NumCPU(), "hw.physicalcpu")
|
||||
c.ThreadsPerCore = sysctlGetInt(1, "machdep.cpu.thread_count", "kern.num_threads") /
|
||||
sysctlGetInt(1, "hw.physicalcpu")
|
||||
c.LogicalCores = sysctlGetInt(runtime.NumCPU(), "machdep.cpu.core_count")
|
||||
c.Family = sysctlGetInt(0, "machdep.cpu.family", "hw.cpufamily")
|
||||
c.Model = sysctlGetInt(0, "machdep.cpu.model")
|
||||
c.CacheLine = sysctlGetInt64(0, "hw.cachelinesize")
|
||||
c.Cache.L1I = sysctlGetInt64(-1, "hw.l1icachesize")
|
||||
c.Cache.L1D = sysctlGetInt64(-1, "hw.l1icachesize")
|
||||
c.Cache.L2 = sysctlGetInt64(-1, "hw.l2cachesize")
|
||||
c.Cache.L3 = sysctlGetInt64(-1, "hw.l3cachesize")
|
||||
|
||||
// from https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile
|
||||
setFeature(c, "hw.optional.arm.FEAT_AES", AESARM)
|
||||
setFeature(c, "hw.optional.AdvSIMD", ASIMD)
|
||||
setFeature(c, "hw.optional.arm.FEAT_DotProd", ASIMDDP)
|
||||
setFeature(c, "hw.optional.arm.FEAT_RDM", ASIMDRDM)
|
||||
setFeature(c, "hw.optional.FEAT_CRC32", CRC32)
|
||||
setFeature(c, "hw.optional.arm.FEAT_DPB", DCPOP)
|
||||
// setFeature(c, "", EVTSTRM)
|
||||
setFeature(c, "hw.optional.arm.FEAT_FCMA", FCMA)
|
||||
setFeature(c, "hw.optional.arm.FEAT_FP", FP)
|
||||
setFeature(c, "hw.optional.arm.FEAT_FP16", FPHP)
|
||||
setFeature(c, "hw.optional.arm.FEAT_PAuth", GPA)
|
||||
setFeature(c, "hw.optional.arm.FEAT_JSCVT", JSCVT)
|
||||
setFeature(c, "hw.optional.arm.FEAT_LRCPC", LRCPC)
|
||||
setFeature(c, "hw.optional.arm.FEAT_PMULL", PMULL)
|
||||
setFeature(c, "hw.optional.arm.FEAT_SHA1", SHA1)
|
||||
setFeature(c, "hw.optional.arm.FEAT_SHA256", SHA2)
|
||||
setFeature(c, "hw.optional.arm.FEAT_SHA3", SHA3)
|
||||
setFeature(c, "hw.optional.arm.FEAT_SHA512", SHA512)
|
||||
// setFeature(c, "", SM3)
|
||||
// setFeature(c, "", SM4)
|
||||
setFeature(c, "hw.optional.arm.FEAT_SVE", SVE)
|
||||
|
||||
// from empirical observation
|
||||
setFeature(c, "hw.optional.AdvSIMD_HPFPCvt", ASIMDHP)
|
||||
setFeature(c, "hw.optional.armv8_1_atomics", ATOMICS)
|
||||
setFeature(c, "hw.optional.floatingpoint", FP)
|
||||
setFeature(c, "hw.optional.armv8_2_sha3", SHA3)
|
||||
setFeature(c, "hw.optional.armv8_2_sha512", SHA512)
|
||||
setFeature(c, "hw.optional.armv8_3_compnum", FCMA)
|
||||
setFeature(c, "hw.optional.armv8_crc32", CRC32)
|
||||
}
|
||||
|
||||
14
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
14
vendor/github.com/labstack/echo/v4/CHANGELOG.md
generated
vendored
@ -1,5 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
## v4.9.1 - 2022-10-12
|
||||
|
||||
**Fixes**
|
||||
|
||||
* Fix logger panicing (when template is set to empty) by bumping dependency version [#2295](https://github.com/labstack/echo/issues/2295)
|
||||
|
||||
**Enhancements**
|
||||
|
||||
* Improve CORS documentation [#2272](https://github.com/labstack/echo/pull/2272)
|
||||
* Update readme about supported Go versions [#2291](https://github.com/labstack/echo/pull/2291)
|
||||
* Tests: improve error handling on closing body [#2254](https://github.com/labstack/echo/pull/2254)
|
||||
* Tests: refactor some of the assertions in tests [#2275](https://github.com/labstack/echo/pull/2275)
|
||||
* Tests: refactor assertions [#2301](https://github.com/labstack/echo/pull/2301)
|
||||
|
||||
## v4.9.0 - 2022-09-04
|
||||
|
||||
**Security**
|
||||
|
||||
5
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
5
vendor/github.com/labstack/echo/v4/README.md
generated
vendored
@ -11,12 +11,11 @@
|
||||
|
||||
## Supported Go versions
|
||||
|
||||
Latest version of Echo supports last four Go major [releases](https://go.dev/doc/devel/release) and might work with older versions.
|
||||
|
||||
As of version 4.0.0, Echo is available as a [Go module](https://github.com/golang/go/wiki/Modules).
|
||||
Therefore a Go version capable of understanding /vN suffixed imports is required:
|
||||
|
||||
- 1.9.7+
|
||||
- 1.10.3+
|
||||
- 1.14+
|
||||
|
||||
Any of these versions will allow you to import Echo as `github.com/labstack/echo/v4` which is the recommended
|
||||
way of using Echo going forward.
|
||||
|
||||
2
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
2
vendor/github.com/labstack/echo/v4/context.go
generated
vendored
@ -181,7 +181,7 @@ type (
|
||||
// Logger returns the `Logger` instance.
|
||||
Logger() Logger
|
||||
|
||||
// Set the logger
|
||||
// SetLogger Set the logger
|
||||
SetLogger(l Logger)
|
||||
|
||||
// Echo returns the `Echo` instance.
|
||||
|
||||
88
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
88
vendor/github.com/labstack/echo/v4/middleware/cors.go
generated
vendored
@ -15,46 +15,85 @@ type (
|
||||
// Skipper defines a function to skip middleware.
|
||||
Skipper Skipper
|
||||
|
||||
// AllowOrigin defines a list of origins that may access the resource.
|
||||
// AllowOrigins determines the value of the Access-Control-Allow-Origin
|
||||
// response header. This header defines a list of origins that may access the
|
||||
// resource. The wildcard characters '*' and '?' are supported and are
|
||||
// converted to regex fragments '.*' and '.' accordingly.
|
||||
//
|
||||
// Security: use extreme caution when handling the origin, and carefully
|
||||
// validate any logic. Remember that attackers may register hostile domain names.
|
||||
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||
//
|
||||
// Optional. Default value []string{"*"}.
|
||||
//
|
||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
|
||||
AllowOrigins []string `yaml:"allow_origins"`
|
||||
|
||||
// AllowOriginFunc is a custom function to validate the origin. It takes the
|
||||
// origin as an argument and returns true if allowed or false otherwise. If
|
||||
// an error is returned, it is returned by the handler. If this option is
|
||||
// set, AllowOrigins is ignored.
|
||||
//
|
||||
// Security: use extreme caution when handling the origin, and carefully
|
||||
// validate any logic. Remember that attackers may register hostile domain names.
|
||||
// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||
//
|
||||
// Optional.
|
||||
AllowOriginFunc func(origin string) (bool, error) `yaml:"allow_origin_func"`
|
||||
|
||||
// AllowMethods defines a list methods allowed when accessing the resource.
|
||||
// This is used in response to a preflight request.
|
||||
// AllowMethods determines the value of the Access-Control-Allow-Methods
|
||||
// response header. This header specified the list of methods allowed when
|
||||
// accessing the resource. This is used in response to a preflight request.
|
||||
//
|
||||
// Optional. Default value DefaultCORSConfig.AllowMethods.
|
||||
// If `allowMethods` is left empty will fill for preflight request `Access-Control-Allow-Methods` header value
|
||||
// If `allowMethods` is left empty, this middleware will fill for preflight
|
||||
// request `Access-Control-Allow-Methods` header value
|
||||
// from `Allow` header that echo.Router set into context.
|
||||
//
|
||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
|
||||
AllowMethods []string `yaml:"allow_methods"`
|
||||
|
||||
// AllowHeaders defines a list of request headers that can be used when
|
||||
// making the actual request. This is in response to a preflight request.
|
||||
// AllowHeaders determines the value of the Access-Control-Allow-Headers
|
||||
// response header. This header is used in response to a preflight request to
|
||||
// indicate which HTTP headers can be used when making the actual request.
|
||||
//
|
||||
// Optional. Default value []string{}.
|
||||
//
|
||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
|
||||
AllowHeaders []string `yaml:"allow_headers"`
|
||||
|
||||
// AllowCredentials indicates whether or not the response to the request
|
||||
// can be exposed when the credentials flag is true. When used as part of
|
||||
// a response to a preflight request, this indicates whether or not the
|
||||
// actual request can be made using credentials.
|
||||
// Optional. Default value false.
|
||||
// AllowCredentials determines the value of the
|
||||
// Access-Control-Allow-Credentials response header. This header indicates
|
||||
// whether or not the response to the request can be exposed when the
|
||||
// credentials mode (Request.credentials) is true. When used as part of a
|
||||
// response to a preflight request, this indicates whether or not the actual
|
||||
// request can be made using credentials. See also
|
||||
// [MDN: Access-Control-Allow-Credentials].
|
||||
//
|
||||
// Optional. Default value false, in which case the header is not set.
|
||||
//
|
||||
// Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`.
|
||||
// See http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||
// See "Exploiting CORS misconfigurations for Bitcoins and bounties",
|
||||
// https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||
//
|
||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
|
||||
AllowCredentials bool `yaml:"allow_credentials"`
|
||||
|
||||
// ExposeHeaders defines a whitelist headers that clients are allowed to
|
||||
// access.
|
||||
// Optional. Default value []string{}.
|
||||
// ExposeHeaders determines the value of Access-Control-Expose-Headers, which
|
||||
// defines a list of headers that clients are allowed to access.
|
||||
//
|
||||
// Optional. Default value []string{}, in which case the header is not set.
|
||||
//
|
||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Header
|
||||
ExposeHeaders []string `yaml:"expose_headers"`
|
||||
|
||||
// MaxAge indicates how long (in seconds) the results of a preflight request
|
||||
// can be cached.
|
||||
// Optional. Default value 0.
|
||||
// MaxAge determines the value of the Access-Control-Max-Age response header.
|
||||
// This header indicates how long (in seconds) the results of a preflight
|
||||
// request can be cached.
|
||||
//
|
||||
// Optional. Default value 0. The header is set only if MaxAge > 0.
|
||||
//
|
||||
// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
|
||||
MaxAge int `yaml:"max_age"`
|
||||
}
|
||||
)
|
||||
@ -69,13 +108,22 @@ var (
|
||||
)
|
||||
|
||||
// CORS returns a Cross-Origin Resource Sharing (CORS) middleware.
|
||||
// See: https://developer.mozilla.org/en/docs/Web/HTTP/Access_control_CORS
|
||||
// See also [MDN: Cross-Origin Resource Sharing (CORS)].
|
||||
//
|
||||
// Security: Poorly configured CORS can compromise security because it allows
|
||||
// relaxation of the browser's Same-Origin policy. See [Exploiting CORS
|
||||
// misconfigurations for Bitcoins and bounties] and [Portswigger: Cross-origin
|
||||
// resource sharing (CORS)] for more details.
|
||||
//
|
||||
// [MDN: Cross-Origin Resource Sharing (CORS)]: https://developer.mozilla.org/en/docs/Web/HTTP/Access_control_CORS
|
||||
// [Exploiting CORS misconfigurations for Bitcoins and bounties]: https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
|
||||
// [Portswigger: Cross-origin resource sharing (CORS)]: https://portswigger.net/web-security/cors
|
||||
func CORS() echo.MiddlewareFunc {
|
||||
return CORSWithConfig(DefaultCORSConfig)
|
||||
}
|
||||
|
||||
// CORSWithConfig returns a CORS middleware with config.
|
||||
// See: `CORS()`.
|
||||
// See: [CORS].
|
||||
func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
||||
// Defaults
|
||||
if config.Skipper == nil {
|
||||
|
||||
185
vendor/github.com/labstack/gommon/bytes/bytes.go
generated
vendored
185
vendor/github.com/labstack/gommon/bytes/bytes.go
generated
vendored
@ -12,19 +12,31 @@ type (
|
||||
Bytes struct{}
|
||||
)
|
||||
|
||||
// binary units (IEC 60027)
|
||||
const (
|
||||
_ = 1.0 << (10 * iota) // ignore first value by assigning to blank identifier
|
||||
KB
|
||||
MB
|
||||
GB
|
||||
TB
|
||||
PB
|
||||
EB
|
||||
KiB
|
||||
MiB
|
||||
GiB
|
||||
TiB
|
||||
PiB
|
||||
EiB
|
||||
)
|
||||
|
||||
// decimal units (SI international system of units)
|
||||
const (
|
||||
KB = 1000
|
||||
MB = KB * 1000
|
||||
GB = MB * 1000
|
||||
TB = GB * 1000
|
||||
PB = TB * 1000
|
||||
EB = PB * 1000
|
||||
)
|
||||
|
||||
var (
|
||||
pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]B?|B?)$`)
|
||||
global = New()
|
||||
patternBinary = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]iB?)$`)
|
||||
patternDecimal = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]B?|B?)$`)
|
||||
global = New()
|
||||
)
|
||||
|
||||
// New creates a Bytes instance.
|
||||
@ -32,44 +44,97 @@ func New() *Bytes {
|
||||
return &Bytes{}
|
||||
}
|
||||
|
||||
// Format formats bytes integer to human readable string.
|
||||
// Format formats bytes integer to human readable string according to IEC 60027.
|
||||
// For example, 31323 bytes will return 30.59KB.
|
||||
func (*Bytes) Format(b int64) string {
|
||||
func (b *Bytes) Format(value int64) string {
|
||||
return b.FormatBinary(value)
|
||||
}
|
||||
|
||||
// FormatBinary formats bytes integer to human readable string according to IEC 60027.
|
||||
// For example, 31323 bytes will return 30.59KB.
|
||||
func (*Bytes) FormatBinary(value int64) string {
|
||||
multiple := ""
|
||||
value := float64(b)
|
||||
val := float64(value)
|
||||
|
||||
switch {
|
||||
case b >= EB:
|
||||
value /= EB
|
||||
multiple = "EB"
|
||||
case b >= PB:
|
||||
value /= PB
|
||||
multiple = "PB"
|
||||
case b >= TB:
|
||||
value /= TB
|
||||
multiple = "TB"
|
||||
case b >= GB:
|
||||
value /= GB
|
||||
multiple = "GB"
|
||||
case b >= MB:
|
||||
value /= MB
|
||||
multiple = "MB"
|
||||
case b >= KB:
|
||||
value /= KB
|
||||
multiple = "KB"
|
||||
case b == 0:
|
||||
case value >= EiB:
|
||||
val /= EiB
|
||||
multiple = "EiB"
|
||||
case value >= PiB:
|
||||
val /= PiB
|
||||
multiple = "PiB"
|
||||
case value >= TiB:
|
||||
val /= TiB
|
||||
multiple = "TiB"
|
||||
case value >= GiB:
|
||||
val /= GiB
|
||||
multiple = "GiB"
|
||||
case value >= MiB:
|
||||
val /= MiB
|
||||
multiple = "MiB"
|
||||
case value >= KiB:
|
||||
val /= KiB
|
||||
multiple = "KiB"
|
||||
case value == 0:
|
||||
return "0"
|
||||
default:
|
||||
return strconv.FormatInt(b, 10) + "B"
|
||||
return strconv.FormatInt(value, 10) + "B"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%.2f%s", value, multiple)
|
||||
return fmt.Sprintf("%.2f%s", val, multiple)
|
||||
}
|
||||
|
||||
// FormatDecimal formats bytes integer to human readable string according to SI international system of units.
|
||||
// For example, 31323 bytes will return 31.32KB.
|
||||
func (*Bytes) FormatDecimal(value int64) string {
|
||||
multiple := ""
|
||||
val := float64(value)
|
||||
|
||||
switch {
|
||||
case value >= EB:
|
||||
val /= EB
|
||||
multiple = "EB"
|
||||
case value >= PB:
|
||||
val /= PB
|
||||
multiple = "PB"
|
||||
case value >= TB:
|
||||
val /= TB
|
||||
multiple = "TB"
|
||||
case value >= GB:
|
||||
val /= GB
|
||||
multiple = "GB"
|
||||
case value >= MB:
|
||||
val /= MB
|
||||
multiple = "MB"
|
||||
case value >= KB:
|
||||
val /= KB
|
||||
multiple = "KB"
|
||||
case value == 0:
|
||||
return "0"
|
||||
default:
|
||||
return strconv.FormatInt(value, 10) + "B"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%.2f%s", val, multiple)
|
||||
}
|
||||
|
||||
// Parse parses human readable bytes string to bytes integer.
|
||||
// For example, 6GB (6G is also valid) will return 6442450944.
|
||||
func (*Bytes) Parse(value string) (i int64, err error) {
|
||||
parts := pattern.FindStringSubmatch(value)
|
||||
// For example, 6GiB (6Gi is also valid) will return 6442450944, and
|
||||
// 6GB (6G is also valid) will return 6000000000.
|
||||
func (b *Bytes) Parse(value string) (int64, error) {
|
||||
|
||||
i, err := b.ParseBinary(value)
|
||||
if err == nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
return b.ParseDecimal(value)
|
||||
}
|
||||
|
||||
// ParseBinary parses human readable bytes string to bytes integer.
|
||||
// For example, 6GiB (6Gi is also valid) will return 6442450944.
|
||||
func (*Bytes) ParseBinary(value string) (i int64, err error) {
|
||||
parts := patternBinary.FindStringSubmatch(value)
|
||||
if len(parts) < 3 {
|
||||
return 0, fmt.Errorf("error parsing value=%s", value)
|
||||
}
|
||||
@ -81,8 +146,38 @@ func (*Bytes) Parse(value string) (i int64, err error) {
|
||||
}
|
||||
|
||||
switch multiple {
|
||||
case "KI", "KIB":
|
||||
return int64(bytes * KiB), nil
|
||||
case "MI", "MIB":
|
||||
return int64(bytes * MiB), nil
|
||||
case "GI", "GIB":
|
||||
return int64(bytes * GiB), nil
|
||||
case "TI", "TIB":
|
||||
return int64(bytes * TiB), nil
|
||||
case "PI", "PIB":
|
||||
return int64(bytes * PiB), nil
|
||||
case "EI", "EIB":
|
||||
return int64(bytes * EiB), nil
|
||||
default:
|
||||
return int64(bytes), nil
|
||||
}
|
||||
}
|
||||
|
||||
// ParseDecimal parses human readable bytes string to bytes integer.
|
||||
// For example, 6GB (6G is also valid) will return 6000000000.
|
||||
func (*Bytes) ParseDecimal(value string) (i int64, err error) {
|
||||
parts := patternDecimal.FindStringSubmatch(value)
|
||||
if len(parts) < 3 {
|
||||
return 0, fmt.Errorf("error parsing value=%s", value)
|
||||
}
|
||||
bytesString := parts[1]
|
||||
multiple := strings.ToUpper(parts[2])
|
||||
bytes, err := strconv.ParseFloat(bytesString, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch multiple {
|
||||
case "K", "KB":
|
||||
return int64(bytes * KB), nil
|
||||
case "M", "MB":
|
||||
@ -95,15 +190,27 @@ func (*Bytes) Parse(value string) (i int64, err error) {
|
||||
return int64(bytes * PB), nil
|
||||
case "E", "EB":
|
||||
return int64(bytes * EB), nil
|
||||
default:
|
||||
return int64(bytes), nil
|
||||
}
|
||||
}
|
||||
|
||||
// Format wraps global Bytes's Format function.
|
||||
func Format(b int64) string {
|
||||
return global.Format(b)
|
||||
func Format(value int64) string {
|
||||
return global.Format(value)
|
||||
}
|
||||
|
||||
// FormatBinary wraps global Bytes's FormatBinary function.
|
||||
func FormatBinary(value int64) string {
|
||||
return global.FormatBinary(value)
|
||||
}
|
||||
|
||||
// FormatDecimal wraps global Bytes's FormatDecimal function.
|
||||
func FormatDecimal(value int64) string {
|
||||
return global.FormatDecimal(value)
|
||||
}
|
||||
|
||||
// Parse wraps global Bytes's Parse function.
|
||||
func Parse(val string) (int64, error) {
|
||||
return global.Parse(val)
|
||||
func Parse(value string) (int64, error) {
|
||||
return global.Parse(value)
|
||||
}
|
||||
|
||||
6
vendor/github.com/labstack/gommon/log/log.go
generated
vendored
6
vendor/github.com/labstack/gommon/log/log.go
generated
vendored
@ -391,7 +391,7 @@ func (l *Logger) log(level Lvl, format string, args ...interface{}) {
|
||||
if err == nil {
|
||||
s := buf.String()
|
||||
i := buf.Len() - 1
|
||||
if s[i] == '}' {
|
||||
if i >= 0 && s[i] == '}' {
|
||||
// JSON header
|
||||
buf.Truncate(i)
|
||||
buf.WriteByte(',')
|
||||
@ -404,7 +404,9 @@ func (l *Logger) log(level Lvl, format string, args ...interface{}) {
|
||||
}
|
||||
} else {
|
||||
// Text header
|
||||
buf.WriteByte(' ')
|
||||
if len(s) > 0 {
|
||||
buf.WriteByte(' ')
|
||||
}
|
||||
buf.WriteString(message)
|
||||
}
|
||||
buf.WriteByte('\n')
|
||||
|
||||
6
vendor/github.com/miekg/dns/client.go
generated
vendored
6
vendor/github.com/miekg/dns/client.go
generated
vendored
@ -24,7 +24,7 @@ func isPacketConn(c net.Conn) bool {
|
||||
}
|
||||
|
||||
if ua, ok := c.LocalAddr().(*net.UnixAddr); ok {
|
||||
return ua.Net == "unixgram"
|
||||
return ua.Net == "unixgram" || ua.Net == "unixpacket"
|
||||
}
|
||||
|
||||
return true
|
||||
@ -280,7 +280,7 @@ func (co *Conn) ReadMsg() (*Msg, error) {
|
||||
}
|
||||
if t := m.IsTsig(); t != nil {
|
||||
// Need to work on the original message p, as that was used to calculate the tsig.
|
||||
err = tsigVerifyProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
|
||||
err = TsigVerifyWithProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
|
||||
}
|
||||
return m, err
|
||||
}
|
||||
@ -358,7 +358,7 @@ func (co *Conn) WriteMsg(m *Msg) (err error) {
|
||||
var out []byte
|
||||
if t := m.IsTsig(); t != nil {
|
||||
// Set tsigRequestMAC for the next read, although only used in zone transfers.
|
||||
out, co.tsigRequestMAC, err = tsigGenerateProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
|
||||
out, co.tsigRequestMAC, err = TsigGenerateWithProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
|
||||
} else {
|
||||
out, err = m.Pack()
|
||||
}
|
||||
|
||||
5
vendor/github.com/miekg/dns/defaults.go
generated
vendored
5
vendor/github.com/miekg/dns/defaults.go
generated
vendored
@ -218,6 +218,11 @@ func IsDomainName(s string) (labels int, ok bool) {
|
||||
|
||||
wasDot = false
|
||||
case '.':
|
||||
if i == 0 && len(s) > 1 {
|
||||
// leading dots are not legal except for the root zone
|
||||
return labels, false
|
||||
}
|
||||
|
||||
if wasDot {
|
||||
// two dots back to back is not legal
|
||||
return labels, false
|
||||
|
||||
48
vendor/github.com/miekg/dns/dnssec.go
generated
vendored
48
vendor/github.com/miekg/dns/dnssec.go
generated
vendored
@ -65,6 +65,9 @@ var AlgorithmToString = map[uint8]string{
|
||||
}
|
||||
|
||||
// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
|
||||
// For newer algorithm that do their own hashing (i.e. ED25519) the returned value
|
||||
// is 0, implying no (external) hashing should occur. The non-exported identityHash is then
|
||||
// used.
|
||||
var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
|
||||
DSA: crypto.SHA1,
|
||||
@ -74,7 +77,7 @@ var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||
ECDSAP256SHA256: crypto.SHA256,
|
||||
ECDSAP384SHA384: crypto.SHA384,
|
||||
RSASHA512: crypto.SHA512,
|
||||
ED25519: crypto.Hash(0),
|
||||
ED25519: 0,
|
||||
}
|
||||
|
||||
// DNSSEC hashing algorithm codes.
|
||||
@ -137,12 +140,12 @@ func (k *DNSKEY) KeyTag() uint16 {
|
||||
var keytag int
|
||||
switch k.Algorithm {
|
||||
case RSAMD5:
|
||||
// Look at the bottom two bytes of the modules, which the last
|
||||
// item in the pubkey.
|
||||
// This algorithm has been deprecated, but keep this key-tag calculation.
|
||||
// Look at the bottom two bytes of the modules, which the last item in the pubkey.
|
||||
// See https://www.rfc-editor.org/errata/eid193 .
|
||||
modulus, _ := fromBase64([]byte(k.PublicKey))
|
||||
if len(modulus) > 1 {
|
||||
x := binary.BigEndian.Uint16(modulus[len(modulus)-2:])
|
||||
x := binary.BigEndian.Uint16(modulus[len(modulus)-3:])
|
||||
keytag = int(x)
|
||||
}
|
||||
default:
|
||||
@ -296,35 +299,20 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
||||
return err
|
||||
}
|
||||
|
||||
hash, ok := AlgorithmToHash[rr.Algorithm]
|
||||
if !ok {
|
||||
return ErrAlg
|
||||
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch rr.Algorithm {
|
||||
case ED25519:
|
||||
// ed25519 signs the raw message and performs hashing internally.
|
||||
// All other supported signature schemes operate over the pre-hashed
|
||||
// message, and thus ed25519 must be handled separately here.
|
||||
//
|
||||
// The raw message is passed directly into sign and crypto.Hash(0) is
|
||||
// used to signal to the crypto.Signer that the data has not been hashed.
|
||||
signature, err := sign(k, append(signdata, wire...), crypto.Hash(0), rr.Algorithm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rr.Signature = toBase64(signature)
|
||||
return nil
|
||||
case RSAMD5, DSA, DSANSEC3SHA1:
|
||||
// See RFC 6944.
|
||||
return ErrAlg
|
||||
default:
|
||||
h := hash.New()
|
||||
h.Write(signdata)
|
||||
h.Write(wire)
|
||||
|
||||
signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm)
|
||||
signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -341,7 +329,7 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
|
||||
}
|
||||
|
||||
switch alg {
|
||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
|
||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519:
|
||||
return signature, nil
|
||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||
ecdsaSignature := &struct {
|
||||
@ -362,8 +350,6 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
|
||||
signature := intToBytes(ecdsaSignature.R, intlen)
|
||||
signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
|
||||
return signature, nil
|
||||
case ED25519:
|
||||
return signature, nil
|
||||
default:
|
||||
return nil, ErrAlg
|
||||
}
|
||||
@ -437,9 +423,9 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||
// remove the domain name and assume its ours?
|
||||
}
|
||||
|
||||
hash, ok := AlgorithmToHash[rr.Algorithm]
|
||||
if !ok {
|
||||
return ErrAlg
|
||||
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch rr.Algorithm {
|
||||
@ -450,10 +436,9 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||
return ErrKey
|
||||
}
|
||||
|
||||
h := hash.New()
|
||||
h.Write(signeddata)
|
||||
h.Write(wire)
|
||||
return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf)
|
||||
return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf)
|
||||
|
||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||
pubkey := k.publicKeyECDSA()
|
||||
@ -465,7 +450,6 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||
r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
|
||||
s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:])
|
||||
|
||||
h := hash.New()
|
||||
h.Write(signeddata)
|
||||
h.Write(wire)
|
||||
if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
|
||||
|
||||
16
vendor/github.com/miekg/dns/edns.go
generated
vendored
16
vendor/github.com/miekg/dns/edns.go
generated
vendored
@ -584,14 +584,17 @@ func (e *EDNS0_N3U) copy() EDNS0 { return &EDNS0_N3U{e.Code, e.AlgCode} }
|
||||
type EDNS0_EXPIRE struct {
|
||||
Code uint16 // Always EDNS0EXPIRE
|
||||
Expire uint32
|
||||
Empty bool // Empty is used to signal an empty Expire option in a backwards compatible way, it's not used on the wire.
|
||||
}
|
||||
|
||||
// Option implements the EDNS0 interface.
|
||||
func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
|
||||
func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
|
||||
func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire} }
|
||||
func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire, e.Empty} }
|
||||
|
||||
func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
||||
if e.Empty {
|
||||
return []byte{}, nil
|
||||
}
|
||||
b := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(b, e.Expire)
|
||||
return b, nil
|
||||
@ -600,15 +603,24 @@ func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
||||
func (e *EDNS0_EXPIRE) unpack(b []byte) error {
|
||||
if len(b) == 0 {
|
||||
// zero-length EXPIRE query, see RFC 7314 Section 2
|
||||
e.Empty = true
|
||||
return nil
|
||||
}
|
||||
if len(b) < 4 {
|
||||
return ErrBuf
|
||||
}
|
||||
e.Expire = binary.BigEndian.Uint32(b)
|
||||
e.Empty = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EDNS0_EXPIRE) String() (s string) {
|
||||
if e.Empty {
|
||||
return ""
|
||||
}
|
||||
return strconv.FormatUint(uint64(e.Expire), 10)
|
||||
}
|
||||
|
||||
// The EDNS0_LOCAL option is used for local/experimental purposes. The option
|
||||
// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
|
||||
// (RFC6891), although any unassigned code can actually be used. The content of
|
||||
|
||||
31
vendor/github.com/miekg/dns/hash.go
generated
vendored
Normal file
31
vendor/github.com/miekg/dns/hash.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// identityHash will not hash, it only buffers the data written into it and returns it as-is.
|
||||
type identityHash struct {
|
||||
b *bytes.Buffer
|
||||
}
|
||||
|
||||
// Implement the hash.Hash interface.
|
||||
|
||||
func (i identityHash) Write(b []byte) (int, error) { return i.b.Write(b) }
|
||||
func (i identityHash) Size() int { return i.b.Len() }
|
||||
func (i identityHash) BlockSize() int { return 1024 }
|
||||
func (i identityHash) Reset() { i.b.Reset() }
|
||||
func (i identityHash) Sum(b []byte) []byte { return append(b, i.b.Bytes()...) }
|
||||
|
||||
func hashFromAlgorithm(alg uint8) (hash.Hash, crypto.Hash, error) {
|
||||
hashnumber, ok := AlgorithmToHash[alg]
|
||||
if !ok {
|
||||
return nil, 0, ErrAlg
|
||||
}
|
||||
if hashnumber == 0 {
|
||||
return identityHash{b: &bytes.Buffer{}}, hashnumber, nil
|
||||
}
|
||||
return hashnumber.New(), hashnumber, nil
|
||||
}
|
||||
5
vendor/github.com/miekg/dns/msg.go
generated
vendored
5
vendor/github.com/miekg/dns/msg.go
generated
vendored
@ -265,6 +265,11 @@ loop:
|
||||
|
||||
wasDot = false
|
||||
case '.':
|
||||
if i == 0 && len(s) > 1 {
|
||||
// leading dots are not legal except for the root zone
|
||||
return len(msg), ErrRdata
|
||||
}
|
||||
|
||||
if wasDot {
|
||||
// two dots back to back is not legal
|
||||
return len(msg), ErrRdata
|
||||
|
||||
20
vendor/github.com/miekg/dns/msg_helpers.go
generated
vendored
20
vendor/github.com/miekg/dns/msg_helpers.go
generated
vendored
@ -476,7 +476,7 @@ func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
|
||||
length, window, lastwindow := 0, 0, -1
|
||||
for off < len(msg) {
|
||||
if off+2 > len(msg) {
|
||||
return nsec, len(msg), &Error{err: "overflow unpacking nsecx"}
|
||||
return nsec, len(msg), &Error{err: "overflow unpacking NSEC(3)"}
|
||||
}
|
||||
window = int(msg[off])
|
||||
length = int(msg[off+1])
|
||||
@ -484,17 +484,17 @@ func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
|
||||
if window <= lastwindow {
|
||||
// RFC 4034: Blocks are present in the NSEC RR RDATA in
|
||||
// increasing numerical order.
|
||||
return nsec, len(msg), &Error{err: "out of order NSEC block"}
|
||||
return nsec, len(msg), &Error{err: "out of order NSEC(3) block in type bitmap"}
|
||||
}
|
||||
if length == 0 {
|
||||
// RFC 4034: Blocks with no types present MUST NOT be included.
|
||||
return nsec, len(msg), &Error{err: "empty NSEC block"}
|
||||
return nsec, len(msg), &Error{err: "empty NSEC(3) block in type bitmap"}
|
||||
}
|
||||
if length > 32 {
|
||||
return nsec, len(msg), &Error{err: "NSEC block too long"}
|
||||
return nsec, len(msg), &Error{err: "NSEC(3) block too long in type bitmap"}
|
||||
}
|
||||
if off+length > len(msg) {
|
||||
return nsec, len(msg), &Error{err: "overflowing NSEC block"}
|
||||
return nsec, len(msg), &Error{err: "overflowing NSEC(3) block in type bitmap"}
|
||||
}
|
||||
|
||||
// Walk the bytes in the window and extract the type bits
|
||||
@ -558,6 +558,16 @@ func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
|
||||
if len(bitmap) == 0 {
|
||||
return off, nil
|
||||
}
|
||||
if off > len(msg) {
|
||||
return off, &Error{err: "overflow packing nsec"}
|
||||
}
|
||||
toZero := msg[off:]
|
||||
if maxLen := typeBitMapLen(bitmap); maxLen < len(toZero) {
|
||||
toZero = toZero[:maxLen]
|
||||
}
|
||||
for i := range toZero {
|
||||
toZero[i] = 0
|
||||
}
|
||||
var lastwindow, lastlength uint16
|
||||
for _, t := range bitmap {
|
||||
window := t / 256
|
||||
|
||||
4
vendor/github.com/miekg/dns/server.go
generated
vendored
4
vendor/github.com/miekg/dns/server.go
generated
vendored
@ -646,7 +646,7 @@ func (srv *Server) serveDNS(m []byte, w *response) {
|
||||
w.tsigStatus = nil
|
||||
if w.tsigProvider != nil {
|
||||
if t := req.IsTsig(); t != nil {
|
||||
w.tsigStatus = tsigVerifyProvider(m, w.tsigProvider, "", false)
|
||||
w.tsigStatus = TsigVerifyWithProvider(m, w.tsigProvider, "", false)
|
||||
w.tsigTimersOnly = false
|
||||
w.tsigRequestMAC = t.MAC
|
||||
}
|
||||
@ -728,7 +728,7 @@ func (w *response) WriteMsg(m *Msg) (err error) {
|
||||
var data []byte
|
||||
if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check)
|
||||
if t := m.IsTsig(); t != nil {
|
||||
data, w.tsigRequestMAC, err = tsigGenerateProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
|
||||
data, w.tsigRequestMAC, err = TsigGenerateWithProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
51
vendor/github.com/miekg/dns/sig0.go
generated
vendored
51
vendor/github.com/miekg/dns/sig0.go
generated
vendored
@ -3,6 +3,7 @@ package dns
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
"math/big"
|
||||
@ -38,18 +39,17 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
|
||||
}
|
||||
buf = buf[:off:cap(buf)]
|
||||
|
||||
hash, ok := AlgorithmToHash[rr.Algorithm]
|
||||
if !ok {
|
||||
return nil, ErrAlg
|
||||
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasher := hash.New()
|
||||
// Write SIG rdata
|
||||
hasher.Write(buf[len(mbuf)+1+2+2+4+2:])
|
||||
h.Write(buf[len(mbuf)+1+2+2+4+2:])
|
||||
// Write message
|
||||
hasher.Write(buf[:len(mbuf)])
|
||||
h.Write(buf[:len(mbuf)])
|
||||
|
||||
signature, err := sign(k, hasher.Sum(nil), hash, rr.Algorithm)
|
||||
signature, err := sign(k, h.Sum(nil), cryptohash, rr.Algorithm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -82,20 +82,10 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||
return ErrKey
|
||||
}
|
||||
|
||||
var hash crypto.Hash
|
||||
switch rr.Algorithm {
|
||||
case RSASHA1:
|
||||
hash = crypto.SHA1
|
||||
case RSASHA256, ECDSAP256SHA256:
|
||||
hash = crypto.SHA256
|
||||
case ECDSAP384SHA384:
|
||||
hash = crypto.SHA384
|
||||
case RSASHA512:
|
||||
hash = crypto.SHA512
|
||||
default:
|
||||
return ErrAlg
|
||||
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hasher := hash.New()
|
||||
|
||||
buflen := len(buf)
|
||||
qdc := binary.BigEndian.Uint16(buf[4:])
|
||||
@ -103,7 +93,6 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||
auc := binary.BigEndian.Uint16(buf[8:])
|
||||
adc := binary.BigEndian.Uint16(buf[10:])
|
||||
offset := headerSize
|
||||
var err error
|
||||
for i := uint16(0); i < qdc && offset < buflen; i++ {
|
||||
_, offset, err = UnpackDomainName(buf, offset)
|
||||
if err != nil {
|
||||
@ -166,21 +155,21 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||
return &Error{err: "signer name doesn't match key name"}
|
||||
}
|
||||
sigend := offset
|
||||
hasher.Write(buf[sigstart:sigend])
|
||||
hasher.Write(buf[:10])
|
||||
hasher.Write([]byte{
|
||||
h.Write(buf[sigstart:sigend])
|
||||
h.Write(buf[:10])
|
||||
h.Write([]byte{
|
||||
byte((adc - 1) << 8),
|
||||
byte(adc - 1),
|
||||
})
|
||||
hasher.Write(buf[12:bodyend])
|
||||
h.Write(buf[12:bodyend])
|
||||
|
||||
hashed := hasher.Sum(nil)
|
||||
hashed := h.Sum(nil)
|
||||
sig := buf[sigend:]
|
||||
switch k.Algorithm {
|
||||
case RSASHA1, RSASHA256, RSASHA512:
|
||||
pk := k.publicKeyRSA()
|
||||
if pk != nil {
|
||||
return rsa.VerifyPKCS1v15(pk, hash, hashed, sig)
|
||||
return rsa.VerifyPKCS1v15(pk, cryptohash, hashed, sig)
|
||||
}
|
||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||
pk := k.publicKeyECDSA()
|
||||
@ -192,6 +181,14 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||
}
|
||||
return ErrSig
|
||||
}
|
||||
case ED25519:
|
||||
pk := k.publicKeyED25519()
|
||||
if pk != nil {
|
||||
if ed25519.Verify(pk, hashed, sig) {
|
||||
return nil
|
||||
}
|
||||
return ErrSig
|
||||
}
|
||||
}
|
||||
return ErrKeyAlg
|
||||
}
|
||||
|
||||
330
vendor/github.com/miekg/dns/svcb.go
generated
vendored
330
vendor/github.com/miekg/dns/svcb.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -13,16 +14,18 @@ import (
|
||||
// SVCBKey is the type of the keys used in the SVCB RR.
|
||||
type SVCBKey uint16
|
||||
|
||||
// Keys defined in draft-ietf-dnsop-svcb-https-01 Section 12.3.2.
|
||||
// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2.
|
||||
const (
|
||||
SVCB_MANDATORY SVCBKey = 0
|
||||
SVCB_ALPN SVCBKey = 1
|
||||
SVCB_NO_DEFAULT_ALPN SVCBKey = 2
|
||||
SVCB_PORT SVCBKey = 3
|
||||
SVCB_IPV4HINT SVCBKey = 4
|
||||
SVCB_ECHCONFIG SVCBKey = 5
|
||||
SVCB_IPV6HINT SVCBKey = 6
|
||||
svcb_RESERVED SVCBKey = 65535
|
||||
SVCB_MANDATORY SVCBKey = iota
|
||||
SVCB_ALPN
|
||||
SVCB_NO_DEFAULT_ALPN
|
||||
SVCB_PORT
|
||||
SVCB_IPV4HINT
|
||||
SVCB_ECHCONFIG
|
||||
SVCB_IPV6HINT
|
||||
SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9
|
||||
|
||||
svcb_RESERVED SVCBKey = 65535
|
||||
)
|
||||
|
||||
var svcbKeyToStringMap = map[SVCBKey]string{
|
||||
@ -31,8 +34,9 @@ var svcbKeyToStringMap = map[SVCBKey]string{
|
||||
SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
|
||||
SVCB_PORT: "port",
|
||||
SVCB_IPV4HINT: "ipv4hint",
|
||||
SVCB_ECHCONFIG: "echconfig",
|
||||
SVCB_ECHCONFIG: "ech",
|
||||
SVCB_IPV6HINT: "ipv6hint",
|
||||
SVCB_DOHPATH: "dohpath",
|
||||
}
|
||||
|
||||
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
|
||||
@ -167,10 +171,14 @@ func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
|
||||
}
|
||||
l, _ = c.Next()
|
||||
}
|
||||
|
||||
// "In AliasMode, records SHOULD NOT include any SvcParams, and recipients MUST
|
||||
// ignore any SvcParams that are present."
|
||||
// However, we don't check rr.Priority == 0 && len(xs) > 0 here
|
||||
// It is the responsibility of the user of the library to check this.
|
||||
// This is to encourage the fixing of the source of this error.
|
||||
|
||||
rr.Value = xs
|
||||
if rr.Priority == 0 && len(xs) > 0 {
|
||||
return &ParseError{l.token, "SVCB aliasform can't have values", l}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -191,6 +199,8 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
||||
return new(SVCBECHConfig)
|
||||
case SVCB_IPV6HINT:
|
||||
return new(SVCBIPv6Hint)
|
||||
case SVCB_DOHPATH:
|
||||
return new(SVCBDoHPath)
|
||||
case svcb_RESERVED:
|
||||
return nil
|
||||
default:
|
||||
@ -200,16 +210,24 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
||||
}
|
||||
}
|
||||
|
||||
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-01).
|
||||
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-08).
|
||||
//
|
||||
// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
|
||||
// The API, including constants and types related to SVCBKeyValues, may
|
||||
// change in future versions in accordance with the latest drafts.
|
||||
type SVCB struct {
|
||||
Hdr RR_Header
|
||||
Priority uint16
|
||||
Priority uint16 // If zero, Value must be empty or discarded by the user of this library
|
||||
Target string `dns:"domain-name"`
|
||||
Value []SVCBKeyValue `dns:"pairs"` // Value must be empty if Priority is zero.
|
||||
Value []SVCBKeyValue `dns:"pairs"`
|
||||
}
|
||||
|
||||
// HTTPS RR. Everything valid for SVCB applies to HTTPS as well.
|
||||
// Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
|
||||
//
|
||||
// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
|
||||
// The API, including constants and types related to SVCBKeyValues, may
|
||||
// change in future versions in accordance with the latest drafts.
|
||||
type HTTPS struct {
|
||||
SVCB
|
||||
}
|
||||
@ -235,15 +253,29 @@ type SVCBKeyValue interface {
|
||||
}
|
||||
|
||||
// SVCBMandatory pair adds to required keys that must be interpreted for the RR
|
||||
// to be functional.
|
||||
// to be functional. If ignored, the whole RRSet must be ignored.
|
||||
// "port" and "no-default-alpn" are mandatory by default if present,
|
||||
// so they shouldn't be included here.
|
||||
//
|
||||
// It is incumbent upon the user of this library to reject the RRSet if
|
||||
// or avoid constructing such an RRSet that:
|
||||
// - "mandatory" is included as one of the keys of mandatory
|
||||
// - no key is listed multiple times in mandatory
|
||||
// - all keys listed in mandatory are present
|
||||
// - escape sequences are not used in mandatory
|
||||
// - mandatory, when present, lists at least one key
|
||||
//
|
||||
// Basic use pattern for creating a mandatory option:
|
||||
//
|
||||
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||
// e := new(dns.SVCBMandatory)
|
||||
// e.Code = []uint16{65403}
|
||||
// e.Code = []uint16{dns.SVCB_ALPN}
|
||||
// s.Value = append(s.Value, e)
|
||||
// t := new(dns.SVCBAlpn)
|
||||
// t.Alpn = []string{"xmpp-client"}
|
||||
// s.Value = append(s.Value, t)
|
||||
type SVCBMandatory struct {
|
||||
Code []SVCBKey // Must not include mandatory
|
||||
Code []SVCBKey
|
||||
}
|
||||
|
||||
func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
|
||||
@ -302,7 +334,8 @@ func (s *SVCBMandatory) copy() SVCBKeyValue {
|
||||
}
|
||||
|
||||
// SVCBAlpn pair is used to list supported connection protocols.
|
||||
// Protocol ids can be found at:
|
||||
// The user of this library must ensure that at least one protocol is listed when alpn is present.
|
||||
// Protocol IDs can be found at:
|
||||
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||
// Basic use pattern for creating an alpn option:
|
||||
//
|
||||
@ -310,13 +343,57 @@ func (s *SVCBMandatory) copy() SVCBKeyValue {
|
||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||
// e := new(dns.SVCBAlpn)
|
||||
// e.Alpn = []string{"h2", "http/1.1"}
|
||||
// h.Value = append(o.Value, e)
|
||||
// h.Value = append(h.Value, e)
|
||||
type SVCBAlpn struct {
|
||||
Alpn []string
|
||||
}
|
||||
|
||||
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
||||
func (s *SVCBAlpn) String() string { return strings.Join(s.Alpn, ",") }
|
||||
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
||||
|
||||
func (s *SVCBAlpn) String() string {
|
||||
// An ALPN value is a comma-separated list of values, each of which can be
|
||||
// an arbitrary binary value. In order to allow parsing, the comma and
|
||||
// backslash characters are themselves excaped.
|
||||
//
|
||||
// However, this escaping is done in addition to the normal escaping which
|
||||
// happens in zone files, meaning that these values must be
|
||||
// double-escaped. This looks terrible, so if you see a never-ending
|
||||
// sequence of backslash in a zone file this may be why.
|
||||
//
|
||||
// https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-08#appendix-A.1
|
||||
var str strings.Builder
|
||||
for i, alpn := range s.Alpn {
|
||||
// 4*len(alpn) is the worst case where we escape every character in the alpn as \123, plus 1 byte for the ',' separating the alpn from others
|
||||
str.Grow(4*len(alpn) + 1)
|
||||
if i > 0 {
|
||||
str.WriteByte(',')
|
||||
}
|
||||
for j := 0; j < len(alpn); j++ {
|
||||
e := alpn[j]
|
||||
if ' ' > e || e > '~' {
|
||||
str.WriteString(escapeByte(e))
|
||||
continue
|
||||
}
|
||||
switch e {
|
||||
// We escape a few characters which may confuse humans or parsers.
|
||||
case '"', ';', ' ':
|
||||
str.WriteByte('\\')
|
||||
str.WriteByte(e)
|
||||
// The comma and backslash characters themselves must be
|
||||
// doubly-escaped. We use `\\` for the first backslash and
|
||||
// the escaped numeric value for the other value. We especially
|
||||
// don't want a comma in the output.
|
||||
case ',':
|
||||
str.WriteString(`\\\044`)
|
||||
case '\\':
|
||||
str.WriteString(`\\\092`)
|
||||
default:
|
||||
str.WriteByte(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
return str.String()
|
||||
}
|
||||
|
||||
func (s *SVCBAlpn) pack() ([]byte, error) {
|
||||
// Liberally estimate the size of an alpn as 10 octets
|
||||
@ -351,7 +428,47 @@ func (s *SVCBAlpn) unpack(b []byte) error {
|
||||
}
|
||||
|
||||
func (s *SVCBAlpn) parse(b string) error {
|
||||
s.Alpn = strings.Split(b, ",")
|
||||
if len(b) == 0 {
|
||||
s.Alpn = []string{}
|
||||
return nil
|
||||
}
|
||||
|
||||
alpn := []string{}
|
||||
a := []byte{}
|
||||
for p := 0; p < len(b); {
|
||||
c, q := nextByte(b, p)
|
||||
if q == 0 {
|
||||
return errors.New("dns: svcbalpn: unterminated escape")
|
||||
}
|
||||
p += q
|
||||
// If we find a comma, we have finished reading an alpn.
|
||||
if c == ',' {
|
||||
if len(a) == 0 {
|
||||
return errors.New("dns: svcbalpn: empty protocol identifier")
|
||||
}
|
||||
alpn = append(alpn, string(a))
|
||||
a = []byte{}
|
||||
continue
|
||||
}
|
||||
// If it's a backslash, we need to handle a comma-separated list.
|
||||
if c == '\\' {
|
||||
dc, dq := nextByte(b, p)
|
||||
if dq == 0 {
|
||||
return errors.New("dns: svcbalpn: unterminated escape decoding comma-separated list")
|
||||
}
|
||||
if dc != '\\' && dc != ',' {
|
||||
return errors.New("dns: svcbalpn: bad escaped character decoding comma-separated list")
|
||||
}
|
||||
p += dq
|
||||
c = dc
|
||||
}
|
||||
a = append(a, c)
|
||||
}
|
||||
// Add the final alpn.
|
||||
if len(a) == 0 {
|
||||
return errors.New("dns: svcbalpn: last protocol identifier empty")
|
||||
}
|
||||
s.Alpn = append(alpn, string(a))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -370,9 +487,13 @@ func (s *SVCBAlpn) copy() SVCBKeyValue {
|
||||
}
|
||||
|
||||
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
|
||||
// Should be used in conjunction with alpn.
|
||||
// Basic use pattern for creating a no-default-alpn option:
|
||||
//
|
||||
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||
// t := new(dns.SVCBAlpn)
|
||||
// t.Alpn = []string{"xmpp-client"}
|
||||
// s.Value = append(s.Value, t)
|
||||
// e := new(dns.SVCBNoDefaultAlpn)
|
||||
// s.Value = append(s.Value, e)
|
||||
type SVCBNoDefaultAlpn struct{}
|
||||
@ -385,14 +506,14 @@ func (*SVCBNoDefaultAlpn) len() int { return 0 }
|
||||
|
||||
func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
|
||||
if len(b) != 0 {
|
||||
return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value")
|
||||
return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SVCBNoDefaultAlpn) parse(b string) error {
|
||||
if b != "" {
|
||||
return errors.New("dns: svcbnodefaultalpn: no_default_alpn must have no value")
|
||||
return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -523,7 +644,7 @@ func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
|
||||
}
|
||||
|
||||
// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
|
||||
// Basic use pattern for creating an echconfig option:
|
||||
// Basic use pattern for creating an ech option:
|
||||
//
|
||||
// h := new(dns.HTTPS)
|
||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||
@ -531,7 +652,7 @@ func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
|
||||
// e.ECH = []byte{0xfe, 0x08, ...}
|
||||
// h.Value = append(h.Value, e)
|
||||
type SVCBECHConfig struct {
|
||||
ECH []byte
|
||||
ECH []byte // Specifically ECHConfigList including the redundant length prefix
|
||||
}
|
||||
|
||||
func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG }
|
||||
@ -555,7 +676,7 @@ func (s *SVCBECHConfig) unpack(b []byte) error {
|
||||
func (s *SVCBECHConfig) parse(b string) error {
|
||||
x, err := fromBase64([]byte(b))
|
||||
if err != nil {
|
||||
return errors.New("dns: svcbechconfig: bad base64 echconfig")
|
||||
return errors.New("dns: svcbech: bad base64 ech")
|
||||
}
|
||||
s.ECH = x
|
||||
return nil
|
||||
@ -618,9 +739,6 @@ func (s *SVCBIPv6Hint) String() string {
|
||||
}
|
||||
|
||||
func (s *SVCBIPv6Hint) parse(b string) error {
|
||||
if strings.Contains(b, ".") {
|
||||
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
|
||||
}
|
||||
str := strings.Split(b, ",")
|
||||
dst := make([]net.IP, len(str))
|
||||
for i, e := range str {
|
||||
@ -628,6 +746,9 @@ func (s *SVCBIPv6Hint) parse(b string) error {
|
||||
if ip == nil {
|
||||
return errors.New("dns: svcbipv6hint: bad ip")
|
||||
}
|
||||
if ip.To4() != nil {
|
||||
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4-mapped-ipv6")
|
||||
}
|
||||
dst[i] = ip
|
||||
}
|
||||
s.Hint = dst
|
||||
@ -645,6 +766,54 @@ func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
|
||||
}
|
||||
}
|
||||
|
||||
// SVCBDoHPath pair is used to indicate the URI template that the
|
||||
// clients may use to construct a DNS over HTTPS URI.
|
||||
//
|
||||
// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02)
|
||||
// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06).
|
||||
//
|
||||
// A basic example of using the dohpath option together with the alpn
|
||||
// option to indicate support for DNS over HTTPS on a certain path:
|
||||
//
|
||||
// s := new(dns.SVCB)
|
||||
// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}
|
||||
// e := new(dns.SVCBAlpn)
|
||||
// e.Alpn = []string{"h2", "h3"}
|
||||
// p := new(dns.SVCBDoHPath)
|
||||
// p.Template = "/dns-query{?dns}"
|
||||
// s.Value = append(s.Value, e, p)
|
||||
//
|
||||
// The parsing currently doesn't validate that Template is a valid
|
||||
// RFC 6570 URI template.
|
||||
type SVCBDoHPath struct {
|
||||
Template string
|
||||
}
|
||||
|
||||
func (*SVCBDoHPath) Key() SVCBKey { return SVCB_DOHPATH }
|
||||
func (s *SVCBDoHPath) String() string { return svcbParamToStr([]byte(s.Template)) }
|
||||
func (s *SVCBDoHPath) len() int { return len(s.Template) }
|
||||
func (s *SVCBDoHPath) pack() ([]byte, error) { return []byte(s.Template), nil }
|
||||
|
||||
func (s *SVCBDoHPath) unpack(b []byte) error {
|
||||
s.Template = string(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBDoHPath) parse(b string) error {
|
||||
template, err := svcbParseParam(b)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dns: svcbdohpath: %w", err)
|
||||
}
|
||||
s.Template = string(template)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBDoHPath) copy() SVCBKeyValue {
|
||||
return &SVCBDoHPath{
|
||||
Template: s.Template,
|
||||
}
|
||||
}
|
||||
|
||||
// SVCBLocal pair is intended for experimental/private use. The key is recommended
|
||||
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
||||
// Basic use pattern for creating a keyNNNNN option:
|
||||
@ -661,6 +830,7 @@ type SVCBLocal struct {
|
||||
}
|
||||
|
||||
func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode }
|
||||
func (s *SVCBLocal) String() string { return svcbParamToStr(s.Data) }
|
||||
func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil }
|
||||
func (s *SVCBLocal) len() int { return len(s.Data) }
|
||||
|
||||
@ -669,50 +839,10 @@ func (s *SVCBLocal) unpack(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SVCBLocal) String() string {
|
||||
var str strings.Builder
|
||||
str.Grow(4 * len(s.Data))
|
||||
for _, e := range s.Data {
|
||||
if ' ' <= e && e <= '~' {
|
||||
switch e {
|
||||
case '"', ';', ' ', '\\':
|
||||
str.WriteByte('\\')
|
||||
str.WriteByte(e)
|
||||
default:
|
||||
str.WriteByte(e)
|
||||
}
|
||||
} else {
|
||||
str.WriteString(escapeByte(e))
|
||||
}
|
||||
}
|
||||
return str.String()
|
||||
}
|
||||
|
||||
func (s *SVCBLocal) parse(b string) error {
|
||||
data := make([]byte, 0, len(b))
|
||||
for i := 0; i < len(b); {
|
||||
if b[i] != '\\' {
|
||||
data = append(data, b[i])
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if i+1 == len(b) {
|
||||
return errors.New("dns: svcblocal: svcb private/experimental key escape unterminated")
|
||||
}
|
||||
if isDigit(b[i+1]) {
|
||||
if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
|
||||
a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
|
||||
if err == nil {
|
||||
i += 4
|
||||
data = append(data, byte(a))
|
||||
continue
|
||||
}
|
||||
}
|
||||
return errors.New("dns: svcblocal: svcb private/experimental key bad escaped octet")
|
||||
} else {
|
||||
data = append(data, b[i+1])
|
||||
i += 2
|
||||
}
|
||||
data, err := svcbParseParam(b)
|
||||
if err != nil {
|
||||
return fmt.Errorf("dns: svcblocal: svcb private/experimental key %w", err)
|
||||
}
|
||||
s.Data = data
|
||||
return nil
|
||||
@ -753,3 +883,53 @@ func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// svcbParamStr converts the value of an SVCB parameter into a DNS presentation-format string.
|
||||
func svcbParamToStr(s []byte) string {
|
||||
var str strings.Builder
|
||||
str.Grow(4 * len(s))
|
||||
for _, e := range s {
|
||||
if ' ' <= e && e <= '~' {
|
||||
switch e {
|
||||
case '"', ';', ' ', '\\':
|
||||
str.WriteByte('\\')
|
||||
str.WriteByte(e)
|
||||
default:
|
||||
str.WriteByte(e)
|
||||
}
|
||||
} else {
|
||||
str.WriteString(escapeByte(e))
|
||||
}
|
||||
}
|
||||
return str.String()
|
||||
}
|
||||
|
||||
// svcbParseParam parses a DNS presentation-format string into an SVCB parameter value.
|
||||
func svcbParseParam(b string) ([]byte, error) {
|
||||
data := make([]byte, 0, len(b))
|
||||
for i := 0; i < len(b); {
|
||||
if b[i] != '\\' {
|
||||
data = append(data, b[i])
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if i+1 == len(b) {
|
||||
return nil, errors.New("escape unterminated")
|
||||
}
|
||||
if isDigit(b[i+1]) {
|
||||
if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
|
||||
a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
|
||||
if err == nil {
|
||||
i += 4
|
||||
data = append(data, byte(a))
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil, errors.New("bad escaped octet")
|
||||
} else {
|
||||
data = append(data, b[i+1])
|
||||
i += 2
|
||||
}
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
26
vendor/github.com/miekg/dns/tsig.go
generated
vendored
26
vendor/github.com/miekg/dns/tsig.go
generated
vendored
@ -158,18 +158,17 @@ type timerWireFmt struct {
|
||||
}
|
||||
|
||||
// TsigGenerate fills out the TSIG record attached to the message.
|
||||
// The message should contain
|
||||
// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
|
||||
// time fudge (defaults to 300 seconds) and the current time
|
||||
// The TSIG MAC is saved in that Tsig RR.
|
||||
// When TsigGenerate is called for the first time requestMAC is set to the empty string and
|
||||
// timersOnly is false.
|
||||
// If something goes wrong an error is returned, otherwise it is nil.
|
||||
// The message should contain a "stub" TSIG RR with the algorithm, key name
|
||||
// (owner name of the RR), time fudge (defaults to 300 seconds) and the current
|
||||
// time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for
|
||||
// the first time requestMAC should be set to the empty string and timersOnly to
|
||||
// false.
|
||||
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
|
||||
return tsigGenerateProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
|
||||
return TsigGenerateWithProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
|
||||
}
|
||||
|
||||
func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
|
||||
// TsigGenerateWithProvider is similar to TsigGenerate, but allows for a custom TsigProvider.
|
||||
func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
|
||||
if m.IsTsig() == nil {
|
||||
panic("dns: TSIG not last RR in additional")
|
||||
}
|
||||
@ -216,14 +215,15 @@ func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, time
|
||||
return mbuf, t.MAC, nil
|
||||
}
|
||||
|
||||
// TsigVerify verifies the TSIG on a message.
|
||||
// If the signature does not validate err contains the
|
||||
// error, otherwise it is nil.
|
||||
// TsigVerify verifies the TSIG on a message. If the signature does not
|
||||
// validate the returned error contains the cause. If the signature is OK, the
|
||||
// error is nil.
|
||||
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
|
||||
return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
|
||||
}
|
||||
|
||||
func tsigVerifyProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
|
||||
// TsigVerifyWithProvider is similar to TsigVerify, but allows for a custom TsigProvider.
|
||||
func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
|
||||
return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix()))
|
||||
}
|
||||
|
||||
|
||||
2
vendor/github.com/miekg/dns/version.go
generated
vendored
2
vendor/github.com/miekg/dns/version.go
generated
vendored
@ -3,7 +3,7 @@ package dns
|
||||
import "fmt"
|
||||
|
||||
// Version is current version of this library.
|
||||
var Version = v{1, 1, 46}
|
||||
var Version = v{1, 1, 50}
|
||||
|
||||
// v holds the version of this library.
|
||||
type v struct {
|
||||
|
||||
4
vendor/github.com/miekg/dns/xfr.go
generated
vendored
4
vendor/github.com/miekg/dns/xfr.go
generated
vendored
@ -237,7 +237,7 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
|
||||
}
|
||||
if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
|
||||
// Need to work on the original message p, as that was used to calculate the tsig.
|
||||
err = tsigVerifyProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
|
||||
err = TsigVerifyWithProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
|
||||
t.tsigRequestMAC = ts.MAC
|
||||
}
|
||||
return m, err
|
||||
@ -247,7 +247,7 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
|
||||
func (t *Transfer) WriteMsg(m *Msg) (err error) {
|
||||
var out []byte
|
||||
if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
|
||||
out, t.tsigRequestMAC, err = tsigGenerateProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
|
||||
out, t.tsigRequestMAC, err = TsigGenerateWithProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
|
||||
} else {
|
||||
out, err = m.Pack()
|
||||
}
|
||||
|
||||
333
vendor/github.com/prometheus/client_model/go/metrics.pb.go
generated
vendored
333
vendor/github.com/prometheus/client_model/go/metrics.pb.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: metrics.proto
|
||||
// source: io/prometheus/client/metrics.proto
|
||||
|
||||
package io_prometheus_client
|
||||
|
||||
@ -24,11 +24,18 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
type MetricType int32
|
||||
|
||||
const (
|
||||
MetricType_COUNTER MetricType = 0
|
||||
MetricType_GAUGE MetricType = 1
|
||||
MetricType_SUMMARY MetricType = 2
|
||||
MetricType_UNTYPED MetricType = 3
|
||||
// COUNTER must use the Metric field "counter".
|
||||
MetricType_COUNTER MetricType = 0
|
||||
// GAUGE must use the Metric field "gauge".
|
||||
MetricType_GAUGE MetricType = 1
|
||||
// SUMMARY must use the Metric field "summary".
|
||||
MetricType_SUMMARY MetricType = 2
|
||||
// UNTYPED must use the Metric field "untyped".
|
||||
MetricType_UNTYPED MetricType = 3
|
||||
// HISTOGRAM must use the Metric field "histogram".
|
||||
MetricType_HISTOGRAM MetricType = 4
|
||||
// GAUGE_HISTOGRAM must use the Metric field "histogram".
|
||||
MetricType_GAUGE_HISTOGRAM MetricType = 5
|
||||
)
|
||||
|
||||
var MetricType_name = map[int32]string{
|
||||
@ -37,14 +44,16 @@ var MetricType_name = map[int32]string{
|
||||
2: "SUMMARY",
|
||||
3: "UNTYPED",
|
||||
4: "HISTOGRAM",
|
||||
5: "GAUGE_HISTOGRAM",
|
||||
}
|
||||
|
||||
var MetricType_value = map[string]int32{
|
||||
"COUNTER": 0,
|
||||
"GAUGE": 1,
|
||||
"SUMMARY": 2,
|
||||
"UNTYPED": 3,
|
||||
"HISTOGRAM": 4,
|
||||
"COUNTER": 0,
|
||||
"GAUGE": 1,
|
||||
"SUMMARY": 2,
|
||||
"UNTYPED": 3,
|
||||
"HISTOGRAM": 4,
|
||||
"GAUGE_HISTOGRAM": 5,
|
||||
}
|
||||
|
||||
func (x MetricType) Enum() *MetricType {
|
||||
@ -67,7 +76,7 @@ func (x *MetricType) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
func (MetricType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{0}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{0}
|
||||
}
|
||||
|
||||
type LabelPair struct {
|
||||
@ -82,7 +91,7 @@ func (m *LabelPair) Reset() { *m = LabelPair{} }
|
||||
func (m *LabelPair) String() string { return proto.CompactTextString(m) }
|
||||
func (*LabelPair) ProtoMessage() {}
|
||||
func (*LabelPair) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{0}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{0}
|
||||
}
|
||||
|
||||
func (m *LabelPair) XXX_Unmarshal(b []byte) error {
|
||||
@ -128,7 +137,7 @@ func (m *Gauge) Reset() { *m = Gauge{} }
|
||||
func (m *Gauge) String() string { return proto.CompactTextString(m) }
|
||||
func (*Gauge) ProtoMessage() {}
|
||||
func (*Gauge) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{1}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{1}
|
||||
}
|
||||
|
||||
func (m *Gauge) XXX_Unmarshal(b []byte) error {
|
||||
@ -168,7 +177,7 @@ func (m *Counter) Reset() { *m = Counter{} }
|
||||
func (m *Counter) String() string { return proto.CompactTextString(m) }
|
||||
func (*Counter) ProtoMessage() {}
|
||||
func (*Counter) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{2}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{2}
|
||||
}
|
||||
|
||||
func (m *Counter) XXX_Unmarshal(b []byte) error {
|
||||
@ -215,7 +224,7 @@ func (m *Quantile) Reset() { *m = Quantile{} }
|
||||
func (m *Quantile) String() string { return proto.CompactTextString(m) }
|
||||
func (*Quantile) ProtoMessage() {}
|
||||
func (*Quantile) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{3}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{3}
|
||||
}
|
||||
|
||||
func (m *Quantile) XXX_Unmarshal(b []byte) error {
|
||||
@ -263,7 +272,7 @@ func (m *Summary) Reset() { *m = Summary{} }
|
||||
func (m *Summary) String() string { return proto.CompactTextString(m) }
|
||||
func (*Summary) ProtoMessage() {}
|
||||
func (*Summary) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{4}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{4}
|
||||
}
|
||||
|
||||
func (m *Summary) XXX_Unmarshal(b []byte) error {
|
||||
@ -316,7 +325,7 @@ func (m *Untyped) Reset() { *m = Untyped{} }
|
||||
func (m *Untyped) String() string { return proto.CompactTextString(m) }
|
||||
func (*Untyped) ProtoMessage() {}
|
||||
func (*Untyped) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{5}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{5}
|
||||
}
|
||||
|
||||
func (m *Untyped) XXX_Unmarshal(b []byte) error {
|
||||
@ -345,9 +354,34 @@ func (m *Untyped) GetValue() float64 {
|
||||
}
|
||||
|
||||
type Histogram struct {
|
||||
SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"`
|
||||
SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"`
|
||||
Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"`
|
||||
SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"`
|
||||
SampleCountFloat *float64 `protobuf:"fixed64,4,opt,name=sample_count_float,json=sampleCountFloat" json:"sample_count_float,omitempty"`
|
||||
SampleSum *float64 `protobuf:"fixed64,2,opt,name=sample_sum,json=sampleSum" json:"sample_sum,omitempty"`
|
||||
// Buckets for the conventional histogram.
|
||||
Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,omitempty"`
|
||||
// schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.
|
||||
// They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and
|
||||
// then each power of two is divided into 2^n logarithmic buckets.
|
||||
// Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).
|
||||
// In the future, more bucket schemas may be added using numbers < -4 or > 8.
|
||||
Schema *int32 `protobuf:"zigzag32,5,opt,name=schema" json:"schema,omitempty"`
|
||||
ZeroThreshold *float64 `protobuf:"fixed64,6,opt,name=zero_threshold,json=zeroThreshold" json:"zero_threshold,omitempty"`
|
||||
ZeroCount *uint64 `protobuf:"varint,7,opt,name=zero_count,json=zeroCount" json:"zero_count,omitempty"`
|
||||
ZeroCountFloat *float64 `protobuf:"fixed64,8,opt,name=zero_count_float,json=zeroCountFloat" json:"zero_count_float,omitempty"`
|
||||
// Negative buckets for the native histogram.
|
||||
NegativeSpan []*BucketSpan `protobuf:"bytes,9,rep,name=negative_span,json=negativeSpan" json:"negative_span,omitempty"`
|
||||
// Use either "negative_delta" or "negative_count", the former for
|
||||
// regular histograms with integer counts, the latter for float
|
||||
// histograms.
|
||||
NegativeDelta []int64 `protobuf:"zigzag64,10,rep,name=negative_delta,json=negativeDelta" json:"negative_delta,omitempty"`
|
||||
NegativeCount []float64 `protobuf:"fixed64,11,rep,name=negative_count,json=negativeCount" json:"negative_count,omitempty"`
|
||||
// Positive buckets for the native histogram.
|
||||
PositiveSpan []*BucketSpan `protobuf:"bytes,12,rep,name=positive_span,json=positiveSpan" json:"positive_span,omitempty"`
|
||||
// Use either "positive_delta" or "positive_count", the former for
|
||||
// regular histograms with integer counts, the latter for float
|
||||
// histograms.
|
||||
PositiveDelta []int64 `protobuf:"zigzag64,13,rep,name=positive_delta,json=positiveDelta" json:"positive_delta,omitempty"`
|
||||
PositiveCount []float64 `protobuf:"fixed64,14,rep,name=positive_count,json=positiveCount" json:"positive_count,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@ -357,7 +391,7 @@ func (m *Histogram) Reset() { *m = Histogram{} }
|
||||
func (m *Histogram) String() string { return proto.CompactTextString(m) }
|
||||
func (*Histogram) ProtoMessage() {}
|
||||
func (*Histogram) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{6}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{6}
|
||||
}
|
||||
|
||||
func (m *Histogram) XXX_Unmarshal(b []byte) error {
|
||||
@ -385,6 +419,13 @@ func (m *Histogram) GetSampleCount() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Histogram) GetSampleCountFloat() float64 {
|
||||
if m != nil && m.SampleCountFloat != nil {
|
||||
return *m.SampleCountFloat
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Histogram) GetSampleSum() float64 {
|
||||
if m != nil && m.SampleSum != nil {
|
||||
return *m.SampleSum
|
||||
@ -399,8 +440,81 @@ func (m *Histogram) GetBucket() []*Bucket {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Histogram) GetSchema() int32 {
|
||||
if m != nil && m.Schema != nil {
|
||||
return *m.Schema
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Histogram) GetZeroThreshold() float64 {
|
||||
if m != nil && m.ZeroThreshold != nil {
|
||||
return *m.ZeroThreshold
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Histogram) GetZeroCount() uint64 {
|
||||
if m != nil && m.ZeroCount != nil {
|
||||
return *m.ZeroCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Histogram) GetZeroCountFloat() float64 {
|
||||
if m != nil && m.ZeroCountFloat != nil {
|
||||
return *m.ZeroCountFloat
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Histogram) GetNegativeSpan() []*BucketSpan {
|
||||
if m != nil {
|
||||
return m.NegativeSpan
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Histogram) GetNegativeDelta() []int64 {
|
||||
if m != nil {
|
||||
return m.NegativeDelta
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Histogram) GetNegativeCount() []float64 {
|
||||
if m != nil {
|
||||
return m.NegativeCount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Histogram) GetPositiveSpan() []*BucketSpan {
|
||||
if m != nil {
|
||||
return m.PositiveSpan
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Histogram) GetPositiveDelta() []int64 {
|
||||
if m != nil {
|
||||
return m.PositiveDelta
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Histogram) GetPositiveCount() []float64 {
|
||||
if m != nil {
|
||||
return m.PositiveCount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A Bucket of a conventional histogram, each of which is treated as
|
||||
// an individual counter-like time series by Prometheus.
|
||||
type Bucket struct {
|
||||
CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"`
|
||||
CumulativeCountFloat *float64 `protobuf:"fixed64,4,opt,name=cumulative_count_float,json=cumulativeCountFloat" json:"cumulative_count_float,omitempty"`
|
||||
UpperBound *float64 `protobuf:"fixed64,2,opt,name=upper_bound,json=upperBound" json:"upper_bound,omitempty"`
|
||||
Exemplar *Exemplar `protobuf:"bytes,3,opt,name=exemplar" json:"exemplar,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
@ -412,7 +526,7 @@ func (m *Bucket) Reset() { *m = Bucket{} }
|
||||
func (m *Bucket) String() string { return proto.CompactTextString(m) }
|
||||
func (*Bucket) ProtoMessage() {}
|
||||
func (*Bucket) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{7}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{7}
|
||||
}
|
||||
|
||||
func (m *Bucket) XXX_Unmarshal(b []byte) error {
|
||||
@ -440,6 +554,13 @@ func (m *Bucket) GetCumulativeCount() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Bucket) GetCumulativeCountFloat() float64 {
|
||||
if m != nil && m.CumulativeCountFloat != nil {
|
||||
return *m.CumulativeCountFloat
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Bucket) GetUpperBound() float64 {
|
||||
if m != nil && m.UpperBound != nil {
|
||||
return *m.UpperBound
|
||||
@ -454,6 +575,59 @@ func (m *Bucket) GetExemplar() *Exemplar {
|
||||
return nil
|
||||
}
|
||||
|
||||
// A BucketSpan defines a number of consecutive buckets in a native
|
||||
// histogram with their offset. Logically, it would be more
|
||||
// straightforward to include the bucket counts in the Span. However,
|
||||
// the protobuf representation is more compact in the way the data is
|
||||
// structured here (with all the buckets in a single array separate
|
||||
// from the Spans).
|
||||
type BucketSpan struct {
|
||||
Offset *int32 `protobuf:"zigzag32,1,opt,name=offset" json:"offset,omitempty"`
|
||||
Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *BucketSpan) Reset() { *m = BucketSpan{} }
|
||||
func (m *BucketSpan) String() string { return proto.CompactTextString(m) }
|
||||
func (*BucketSpan) ProtoMessage() {}
|
||||
func (*BucketSpan) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{8}
|
||||
}
|
||||
|
||||
func (m *BucketSpan) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_BucketSpan.Unmarshal(m, b)
|
||||
}
|
||||
func (m *BucketSpan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_BucketSpan.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *BucketSpan) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BucketSpan.Merge(m, src)
|
||||
}
|
||||
func (m *BucketSpan) XXX_Size() int {
|
||||
return xxx_messageInfo_BucketSpan.Size(m)
|
||||
}
|
||||
func (m *BucketSpan) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BucketSpan.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BucketSpan proto.InternalMessageInfo
|
||||
|
||||
func (m *BucketSpan) GetOffset() int32 {
|
||||
if m != nil && m.Offset != nil {
|
||||
return *m.Offset
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *BucketSpan) GetLength() uint32 {
|
||||
if m != nil && m.Length != nil {
|
||||
return *m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Exemplar struct {
|
||||
Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
|
||||
Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,omitempty"`
|
||||
@ -467,7 +641,7 @@ func (m *Exemplar) Reset() { *m = Exemplar{} }
|
||||
func (m *Exemplar) String() string { return proto.CompactTextString(m) }
|
||||
func (*Exemplar) ProtoMessage() {}
|
||||
func (*Exemplar) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{8}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{9}
|
||||
}
|
||||
|
||||
func (m *Exemplar) XXX_Unmarshal(b []byte) error {
|
||||
@ -526,7 +700,7 @@ func (m *Metric) Reset() { *m = Metric{} }
|
||||
func (m *Metric) String() string { return proto.CompactTextString(m) }
|
||||
func (*Metric) ProtoMessage() {}
|
||||
func (*Metric) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{9}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{10}
|
||||
}
|
||||
|
||||
func (m *Metric) XXX_Unmarshal(b []byte) error {
|
||||
@ -610,7 +784,7 @@ func (m *MetricFamily) Reset() { *m = MetricFamily{} }
|
||||
func (m *MetricFamily) String() string { return proto.CompactTextString(m) }
|
||||
func (*MetricFamily) ProtoMessage() {}
|
||||
func (*MetricFamily) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6039342a2ba47b72, []int{10}
|
||||
return fileDescriptor_d1e5ddb18987a258, []int{11}
|
||||
}
|
||||
|
||||
func (m *MetricFamily) XXX_Unmarshal(b []byte) error {
|
||||
@ -669,55 +843,72 @@ func init() {
|
||||
proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped")
|
||||
proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram")
|
||||
proto.RegisterType((*Bucket)(nil), "io.prometheus.client.Bucket")
|
||||
proto.RegisterType((*BucketSpan)(nil), "io.prometheus.client.BucketSpan")
|
||||
proto.RegisterType((*Exemplar)(nil), "io.prometheus.client.Exemplar")
|
||||
proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric")
|
||||
proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72) }
|
||||
|
||||
var fileDescriptor_6039342a2ba47b72 = []byte{
|
||||
// 665 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcd, 0x6e, 0xd3, 0x4c,
|
||||
0x14, 0xfd, 0xdc, 0x38, 0x3f, 0xbe, 0x69, 0x3f, 0xa2, 0x51, 0x17, 0x56, 0xa1, 0x24, 0x78, 0x55,
|
||||
0x58, 0x38, 0xa2, 0x6a, 0x05, 0x2a, 0xb0, 0x68, 0x4b, 0x48, 0x91, 0x48, 0x5b, 0x26, 0xc9, 0xa2,
|
||||
0xb0, 0x88, 0x1c, 0x77, 0x70, 0x2c, 0x3c, 0xb1, 0xb1, 0x67, 0x2a, 0xb2, 0x66, 0xc1, 0x16, 0x5e,
|
||||
0x81, 0x17, 0x05, 0xcd, 0x8f, 0x6d, 0x2a, 0xb9, 0x95, 0x40, 0xec, 0x66, 0xee, 0x3d, 0xe7, 0xfa,
|
||||
0xcc, 0xf8, 0x9c, 0x81, 0x0d, 0x4a, 0x58, 0x1a, 0xfa, 0x99, 0x9b, 0xa4, 0x31, 0x8b, 0xd1, 0x66,
|
||||
0x18, 0x8b, 0x15, 0x25, 0x6c, 0x41, 0x78, 0xe6, 0xfa, 0x51, 0x48, 0x96, 0x6c, 0xab, 0x1b, 0xc4,
|
||||
0x71, 0x10, 0x91, 0xbe, 0xc4, 0xcc, 0xf9, 0x87, 0x3e, 0x0b, 0x29, 0xc9, 0x98, 0x47, 0x13, 0x45,
|
||||
0x73, 0xf6, 0xc1, 0x7a, 0xe3, 0xcd, 0x49, 0x74, 0xee, 0x85, 0x29, 0x42, 0x60, 0x2e, 0x3d, 0x4a,
|
||||
0x6c, 0xa3, 0x67, 0xec, 0x58, 0x58, 0xae, 0xd1, 0x26, 0xd4, 0xaf, 0xbc, 0x88, 0x13, 0x7b, 0x4d,
|
||||
0x16, 0xd5, 0xc6, 0xd9, 0x86, 0xfa, 0xd0, 0xe3, 0xc1, 0x6f, 0x6d, 0xc1, 0x31, 0xf2, 0xf6, 0x7b,
|
||||
0x68, 0x1e, 0xc7, 0x7c, 0xc9, 0x48, 0x5a, 0x0d, 0x40, 0x07, 0xd0, 0x22, 0x9f, 0x09, 0x4d, 0x22,
|
||||
0x2f, 0x95, 0x83, 0xdb, 0xbb, 0xf7, 0xdd, 0xaa, 0x03, 0xb8, 0x03, 0x8d, 0xc2, 0x05, 0xde, 0x79,
|
||||
0x0e, 0xad, 0xb7, 0xdc, 0x5b, 0xb2, 0x30, 0x22, 0x68, 0x0b, 0x5a, 0x9f, 0xf4, 0x5a, 0x7f, 0xa0,
|
||||
0xd8, 0x5f, 0x57, 0x5e, 0x48, 0xfb, 0x6a, 0x40, 0x73, 0xcc, 0x29, 0xf5, 0xd2, 0x15, 0x7a, 0x00,
|
||||
0xeb, 0x99, 0x47, 0x93, 0x88, 0xcc, 0x7c, 0xa1, 0x56, 0x4e, 0x30, 0x71, 0x5b, 0xd5, 0xe4, 0x01,
|
||||
0xd0, 0x36, 0x80, 0x86, 0x64, 0x9c, 0xea, 0x49, 0x96, 0xaa, 0x8c, 0x39, 0x15, 0xe7, 0x28, 0xbe,
|
||||
0x5f, 0xeb, 0xd5, 0x6e, 0x3e, 0x47, 0xae, 0xb8, 0xd4, 0xe7, 0x74, 0xa1, 0x39, 0x5d, 0xb2, 0x55,
|
||||
0x42, 0x2e, 0x6f, 0xb8, 0xc5, 0x2f, 0x06, 0x58, 0x27, 0x61, 0xc6, 0xe2, 0x20, 0xf5, 0xe8, 0x3f,
|
||||
0x10, 0xbb, 0x07, 0x8d, 0x39, 0xf7, 0x3f, 0x12, 0xa6, 0xa5, 0xde, 0xab, 0x96, 0x7a, 0x24, 0x31,
|
||||
0x58, 0x63, 0x9d, 0x6f, 0x06, 0x34, 0x54, 0x09, 0x3d, 0x84, 0x8e, 0xcf, 0x29, 0x8f, 0x3c, 0x16,
|
||||
0x5e, 0x5d, 0x97, 0x71, 0xa7, 0xac, 0x2b, 0x29, 0x5d, 0x68, 0xf3, 0x24, 0x21, 0xe9, 0x6c, 0x1e,
|
||||
0xf3, 0xe5, 0xa5, 0xd6, 0x02, 0xb2, 0x74, 0x24, 0x2a, 0xd7, 0x1c, 0x50, 0xfb, 0x43, 0x07, 0x7c,
|
||||
0x37, 0xa0, 0x95, 0x97, 0xd1, 0x3e, 0xd4, 0x23, 0xe1, 0x60, 0xdb, 0x90, 0x87, 0xea, 0x56, 0x4f,
|
||||
0x29, 0x4c, 0x8e, 0x15, 0xba, 0xda, 0x1d, 0xe8, 0x29, 0x58, 0x45, 0x42, 0xb4, 0xac, 0x2d, 0x57,
|
||||
0x65, 0xc8, 0xcd, 0x33, 0xe4, 0x4e, 0x72, 0x04, 0x2e, 0xc1, 0xce, 0xcf, 0x35, 0x68, 0x8c, 0x64,
|
||||
0x22, 0xff, 0x56, 0xd1, 0x63, 0xa8, 0x07, 0x22, 0x53, 0x3a, 0x10, 0x77, 0xab, 0x69, 0x32, 0x76,
|
||||
0x58, 0x21, 0xd1, 0x13, 0x68, 0xfa, 0x2a, 0x67, 0x5a, 0xec, 0x76, 0x35, 0x49, 0x87, 0x11, 0xe7,
|
||||
0x68, 0x41, 0xcc, 0x54, 0x08, 0x6c, 0xf3, 0x36, 0xa2, 0x4e, 0x0a, 0xce, 0xd1, 0x82, 0xc8, 0x95,
|
||||
0x69, 0xed, 0xfa, 0x6d, 0x44, 0xed, 0x6c, 0x9c, 0xa3, 0xd1, 0x0b, 0xb0, 0x16, 0xb9, 0x97, 0xed,
|
||||
0xa6, 0xa4, 0xde, 0x70, 0x31, 0x85, 0xe5, 0x71, 0xc9, 0x10, 0xee, 0x2f, 0xee, 0x7a, 0x46, 0x33,
|
||||
0xbb, 0xd1, 0x33, 0x76, 0x6a, 0xb8, 0x5d, 0xd4, 0x46, 0x99, 0xf3, 0xc3, 0x80, 0x75, 0xf5, 0x07,
|
||||
0x5e, 0x79, 0x34, 0x8c, 0x56, 0x95, 0xcf, 0x19, 0x02, 0x73, 0x41, 0xa2, 0x44, 0xbf, 0x66, 0x72,
|
||||
0x8d, 0xf6, 0xc0, 0x14, 0x1a, 0xe5, 0x15, 0xfe, 0xbf, 0xdb, 0xab, 0x56, 0xa5, 0x26, 0x4f, 0x56,
|
||||
0x09, 0xc1, 0x12, 0x2d, 0xd2, 0xa4, 0x5e, 0x60, 0xdb, 0xbc, 0x2d, 0x4d, 0x8a, 0x87, 0x35, 0xf6,
|
||||
0xd1, 0x08, 0xa0, 0x9c, 0x84, 0xda, 0xd0, 0x3c, 0x3e, 0x9b, 0x9e, 0x4e, 0x06, 0xb8, 0xf3, 0x1f,
|
||||
0xb2, 0xa0, 0x3e, 0x3c, 0x9c, 0x0e, 0x07, 0x1d, 0x43, 0xd4, 0xc7, 0xd3, 0xd1, 0xe8, 0x10, 0x5f,
|
||||
0x74, 0xd6, 0xc4, 0x66, 0x7a, 0x3a, 0xb9, 0x38, 0x1f, 0xbc, 0xec, 0xd4, 0xd0, 0x06, 0x58, 0x27,
|
||||
0xaf, 0xc7, 0x93, 0xb3, 0x21, 0x3e, 0x1c, 0x75, 0xcc, 0x23, 0x0c, 0x95, 0xef, 0xfe, 0xbb, 0x83,
|
||||
0x20, 0x64, 0x0b, 0x3e, 0x77, 0xfd, 0x98, 0xf6, 0xcb, 0x6e, 0x5f, 0x75, 0x67, 0x34, 0xbe, 0x24,
|
||||
0x51, 0x3f, 0x88, 0x9f, 0x85, 0xf1, 0xac, 0xec, 0xce, 0x54, 0xf7, 0x57, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0xd0, 0x84, 0x91, 0x73, 0x59, 0x06, 0x00, 0x00,
|
||||
func init() {
|
||||
proto.RegisterFile("io/prometheus/client/metrics.proto", fileDescriptor_d1e5ddb18987a258)
|
||||
}
|
||||
|
||||
var fileDescriptor_d1e5ddb18987a258 = []byte{
|
||||
// 896 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x8e, 0xdb, 0x44,
|
||||
0x18, 0xc5, 0x9b, 0x5f, 0x7f, 0xd9, 0x6c, 0xd3, 0x61, 0x55, 0x59, 0x0b, 0xcb, 0x06, 0x4b, 0x48,
|
||||
0x0b, 0x42, 0x8e, 0x40, 0x5b, 0x81, 0x0a, 0x5c, 0xec, 0xb6, 0xe9, 0x16, 0x89, 0xb4, 0x65, 0x92,
|
||||
0x5c, 0x14, 0x2e, 0xac, 0x49, 0x32, 0xeb, 0x58, 0x78, 0x3c, 0xc6, 0x1e, 0x57, 0x2c, 0x2f, 0xc0,
|
||||
0x35, 0xaf, 0xc0, 0xc3, 0xf0, 0x22, 0x3c, 0x08, 0x68, 0xfe, 0xec, 0xdd, 0xe2, 0x94, 0xd2, 0x3b,
|
||||
0x7f, 0x67, 0xce, 0xf7, 0xcd, 0x39, 0xe3, 0xc9, 0x71, 0xc0, 0x8f, 0xf9, 0x24, 0xcb, 0x39, 0xa3,
|
||||
0x62, 0x4b, 0xcb, 0x62, 0xb2, 0x4e, 0x62, 0x9a, 0x8a, 0x09, 0xa3, 0x22, 0x8f, 0xd7, 0x45, 0x90,
|
||||
0xe5, 0x5c, 0x70, 0x74, 0x18, 0xf3, 0xa0, 0xe6, 0x04, 0x9a, 0x73, 0x74, 0x12, 0x71, 0x1e, 0x25,
|
||||
0x74, 0xa2, 0x38, 0xab, 0xf2, 0x6a, 0x22, 0x62, 0x46, 0x0b, 0x41, 0x58, 0xa6, 0xdb, 0xfc, 0xfb,
|
||||
0xe0, 0x7e, 0x47, 0x56, 0x34, 0x79, 0x4e, 0xe2, 0x1c, 0x21, 0x68, 0xa7, 0x84, 0x51, 0xcf, 0x19,
|
||||
0x3b, 0xa7, 0x2e, 0x56, 0xcf, 0xe8, 0x10, 0x3a, 0x2f, 0x49, 0x52, 0x52, 0x6f, 0x4f, 0x81, 0xba,
|
||||
0xf0, 0x8f, 0xa1, 0x73, 0x49, 0xca, 0xe8, 0xc6, 0xb2, 0xec, 0x71, 0xec, 0xf2, 0x8f, 0xd0, 0x7b,
|
||||
0xc8, 0xcb, 0x54, 0xd0, 0xbc, 0x99, 0x80, 0x1e, 0x40, 0x9f, 0xfe, 0x42, 0x59, 0x96, 0x90, 0x5c,
|
||||
0x0d, 0x1e, 0x7c, 0xfe, 0x41, 0xd0, 0x64, 0x20, 0x98, 0x1a, 0x16, 0xae, 0xf8, 0xfe, 0xd7, 0xd0,
|
||||
0xff, 0xbe, 0x24, 0xa9, 0x88, 0x13, 0x8a, 0x8e, 0xa0, 0xff, 0xb3, 0x79, 0x36, 0x1b, 0x54, 0xf5,
|
||||
0x6d, 0xe5, 0x95, 0xb4, 0xdf, 0x1c, 0xe8, 0xcd, 0x4b, 0xc6, 0x48, 0x7e, 0x8d, 0x3e, 0x84, 0xfd,
|
||||
0x82, 0xb0, 0x2c, 0xa1, 0xe1, 0x5a, 0xaa, 0x55, 0x13, 0xda, 0x78, 0xa0, 0x31, 0x65, 0x00, 0x1d,
|
||||
0x03, 0x18, 0x4a, 0x51, 0x32, 0x33, 0xc9, 0xd5, 0xc8, 0xbc, 0x64, 0xd2, 0x47, 0xb5, 0x7f, 0x6b,
|
||||
0xdc, 0xda, 0xed, 0xc3, 0x2a, 0xae, 0xf5, 0xf9, 0x27, 0xd0, 0x5b, 0xa6, 0xe2, 0x3a, 0xa3, 0x9b,
|
||||
0x1d, 0xa7, 0xf8, 0x57, 0x1b, 0xdc, 0x27, 0x71, 0x21, 0x78, 0x94, 0x13, 0xf6, 0x26, 0x62, 0x3f,
|
||||
0x05, 0x74, 0x93, 0x12, 0x5e, 0x25, 0x9c, 0x08, 0xaf, 0xad, 0x66, 0x8e, 0x6e, 0x10, 0x1f, 0x4b,
|
||||
0xfc, 0xbf, 0xac, 0x9d, 0x41, 0x77, 0x55, 0xae, 0x7f, 0xa2, 0xc2, 0x18, 0x7b, 0xbf, 0xd9, 0xd8,
|
||||
0x85, 0xe2, 0x60, 0xc3, 0x45, 0xf7, 0xa0, 0x5b, 0xac, 0xb7, 0x94, 0x11, 0xaf, 0x33, 0x76, 0x4e,
|
||||
0xef, 0x62, 0x53, 0xa1, 0x8f, 0xe0, 0xe0, 0x57, 0x9a, 0xf3, 0x50, 0x6c, 0x73, 0x5a, 0x6c, 0x79,
|
||||
0xb2, 0xf1, 0xba, 0x6a, 0xc3, 0xa1, 0x44, 0x17, 0x16, 0x94, 0x9a, 0x14, 0x4d, 0x5b, 0xec, 0x29,
|
||||
0x8b, 0xae, 0x44, 0xb4, 0xc1, 0x53, 0x18, 0xd5, 0xcb, 0xc6, 0x5e, 0x5f, 0xcd, 0x39, 0xa8, 0x48,
|
||||
0xda, 0xdc, 0x14, 0x86, 0x29, 0x8d, 0x88, 0x88, 0x5f, 0xd2, 0xb0, 0xc8, 0x48, 0xea, 0xb9, 0xca,
|
||||
0xc4, 0xf8, 0x75, 0x26, 0xe6, 0x19, 0x49, 0xf1, 0xbe, 0x6d, 0x93, 0x95, 0x94, 0x5d, 0x8d, 0xd9,
|
||||
0xd0, 0x44, 0x10, 0x0f, 0xc6, 0xad, 0x53, 0x84, 0xab, 0xe1, 0x8f, 0x24, 0x78, 0x8b, 0xa6, 0xa5,
|
||||
0x0f, 0xc6, 0x2d, 0xe9, 0xce, 0xa2, 0x5a, 0xfe, 0x14, 0x86, 0x19, 0x2f, 0xe2, 0x5a, 0xd4, 0xfe,
|
||||
0x9b, 0x8a, 0xb2, 0x6d, 0x56, 0x54, 0x35, 0x46, 0x8b, 0x1a, 0x6a, 0x51, 0x16, 0xad, 0x44, 0x55,
|
||||
0x34, 0x2d, 0xea, 0x40, 0x8b, 0xb2, 0xa8, 0x12, 0xe5, 0xff, 0xe9, 0x40, 0x57, 0x6f, 0x85, 0x3e,
|
||||
0x86, 0xd1, 0xba, 0x64, 0x65, 0x72, 0xd3, 0x88, 0xbe, 0x66, 0x77, 0x6a, 0x5c, 0x5b, 0x39, 0x83,
|
||||
0x7b, 0xaf, 0x52, 0x6f, 0x5d, 0xb7, 0xc3, 0x57, 0x1a, 0xf4, 0x5b, 0x39, 0x81, 0x41, 0x99, 0x65,
|
||||
0x34, 0x0f, 0x57, 0xbc, 0x4c, 0x37, 0xe6, 0xce, 0x81, 0x82, 0x2e, 0x24, 0x72, 0x2b, 0x17, 0x5a,
|
||||
0xff, 0x3b, 0x17, 0xa0, 0x3e, 0x32, 0x79, 0x11, 0xf9, 0xd5, 0x55, 0x41, 0xb5, 0x83, 0xbb, 0xd8,
|
||||
0x54, 0x12, 0x4f, 0x68, 0x1a, 0x89, 0xad, 0xda, 0x7d, 0x88, 0x4d, 0xe5, 0xff, 0xee, 0x40, 0xdf,
|
||||
0x0e, 0x45, 0xf7, 0xa1, 0x93, 0xc8, 0x54, 0xf4, 0x1c, 0xf5, 0x82, 0x4e, 0x9a, 0x35, 0x54, 0xc1,
|
||||
0x89, 0x35, 0xbb, 0x39, 0x71, 0xd0, 0x97, 0xe0, 0x56, 0xa9, 0x6b, 0x4c, 0x1d, 0x05, 0x3a, 0x97,
|
||||
0x03, 0x9b, 0xcb, 0xc1, 0xc2, 0x32, 0x70, 0x4d, 0xf6, 0xff, 0xde, 0x83, 0xee, 0x4c, 0xa5, 0xfc,
|
||||
0xdb, 0x2a, 0xfa, 0x0c, 0x3a, 0x91, 0xcc, 0x69, 0x13, 0xb2, 0xef, 0x35, 0xb7, 0xa9, 0x28, 0xc7,
|
||||
0x9a, 0x89, 0xbe, 0x80, 0xde, 0x5a, 0x67, 0xb7, 0x11, 0x7b, 0xdc, 0xdc, 0x64, 0x02, 0x1e, 0x5b,
|
||||
0xb6, 0x6c, 0x2c, 0x74, 0xb0, 0xaa, 0x3b, 0xb0, 0xb3, 0xd1, 0xa4, 0x2f, 0xb6, 0x6c, 0xd9, 0x58,
|
||||
0xea, 0x20, 0x54, 0xa1, 0xb1, 0xb3, 0xd1, 0xa4, 0x25, 0xb6, 0x6c, 0xf4, 0x0d, 0xb8, 0x5b, 0x9b,
|
||||
0x8f, 0x2a, 0x2c, 0x76, 0x1e, 0x4c, 0x15, 0xa3, 0xb8, 0xee, 0x90, 0x89, 0x5a, 0x9d, 0x75, 0xc8,
|
||||
0x0a, 0x95, 0x48, 0x2d, 0x3c, 0xa8, 0xb0, 0x59, 0xe1, 0xff, 0xe1, 0xc0, 0xbe, 0x7e, 0x03, 0x8f,
|
||||
0x09, 0x8b, 0x93, 0xeb, 0xc6, 0x4f, 0x24, 0x82, 0xf6, 0x96, 0x26, 0x99, 0xf9, 0x42, 0xaa, 0x67,
|
||||
0x74, 0x06, 0x6d, 0xa9, 0x51, 0x1d, 0xe1, 0xc1, 0xae, 0x5f, 0xb8, 0x9e, 0xbc, 0xb8, 0xce, 0x28,
|
||||
0x56, 0x6c, 0x99, 0xb9, 0xfa, 0xab, 0xee, 0xb5, 0x5f, 0x97, 0xb9, 0xba, 0x0f, 0x1b, 0xee, 0x27,
|
||||
0x2b, 0x80, 0x7a, 0x12, 0x1a, 0x40, 0xef, 0xe1, 0xb3, 0xe5, 0xd3, 0xc5, 0x14, 0x8f, 0xde, 0x41,
|
||||
0x2e, 0x74, 0x2e, 0xcf, 0x97, 0x97, 0xd3, 0x91, 0x23, 0xf1, 0xf9, 0x72, 0x36, 0x3b, 0xc7, 0x2f,
|
||||
0x46, 0x7b, 0xb2, 0x58, 0x3e, 0x5d, 0xbc, 0x78, 0x3e, 0x7d, 0x34, 0x6a, 0xa1, 0x21, 0xb8, 0x4f,
|
||||
0xbe, 0x9d, 0x2f, 0x9e, 0x5d, 0xe2, 0xf3, 0xd9, 0xa8, 0x8d, 0xde, 0x85, 0x3b, 0xaa, 0x27, 0xac,
|
||||
0xc1, 0xce, 0x05, 0x86, 0xc6, 0x3f, 0x18, 0x3f, 0x3c, 0x88, 0x62, 0xb1, 0x2d, 0x57, 0xc1, 0x9a,
|
||||
0xb3, 0x7f, 0xff, 0x45, 0x09, 0x19, 0xdf, 0xd0, 0x64, 0x12, 0xf1, 0xaf, 0x62, 0x1e, 0xd6, 0xab,
|
||||
0xa1, 0x5e, 0xfd, 0x27, 0x00, 0x00, 0xff, 0xff, 0x16, 0x77, 0x81, 0x98, 0xd7, 0x08, 0x00, 0x00,
|
||||
}
|
||||
|
||||
70
vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_nocgo.go
generated
vendored
70
vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_nocgo.go
generated
vendored
@ -5,14 +5,78 @@ package disk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"github.com/shirou/gopsutil/v3/internal/common"
|
||||
)
|
||||
|
||||
var whiteSpaces = regexp.MustCompile(`\s+`)
|
||||
var startBlank = regexp.MustCompile(`^\s+`)
|
||||
|
||||
var ignoreFSType = map[string]bool{"procfs": true}
|
||||
var FSType = map[int]string{
|
||||
0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc",
|
||||
16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs",
|
||||
33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs",
|
||||
39: "ahafs", 40: "sterm-nfs", 41: "asmfs",
|
||||
}
|
||||
|
||||
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
||||
return []PartitionStat{}, common.ErrNotImplementedError
|
||||
var ret []PartitionStat
|
||||
|
||||
out, err := invoke.CommandWithContext(ctx, "mount")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse head lines for column names
|
||||
colidx := make(map[string]int)
|
||||
lines := strings.Split(string(out), "\n")
|
||||
if len(lines) < 3 {
|
||||
return nil, common.ErrNotImplementedError
|
||||
}
|
||||
|
||||
idx := 0
|
||||
start := 0
|
||||
finished := false
|
||||
for pos, ch := range lines[1] {
|
||||
if ch == ' ' && ! finished {
|
||||
name := strings.TrimSpace(lines[0][start:pos])
|
||||
colidx[name] = idx
|
||||
finished = true
|
||||
} else if ch == '-' && finished {
|
||||
idx++
|
||||
start = pos
|
||||
finished = false
|
||||
}
|
||||
}
|
||||
name := strings.TrimSpace(lines[0][start:len(lines[1])])
|
||||
colidx[name] = idx
|
||||
|
||||
for idx := 2; idx < len(lines); idx++ {
|
||||
line := lines[idx]
|
||||
if startBlank.MatchString(line) {
|
||||
line = "localhost" + line
|
||||
}
|
||||
p := whiteSpaces.Split(lines[idx], 6)
|
||||
if len(p) < 5 || ignoreFSType[p[colidx["vfs"]]] {
|
||||
continue
|
||||
}
|
||||
d := PartitionStat{
|
||||
Device: p[colidx["mounted"]],
|
||||
Mountpoint: p[colidx["mounted over"]],
|
||||
Fstype: p[colidx["vfs"]],
|
||||
Opts: strings.Split(p[colidx["options"]], ","),
|
||||
}
|
||||
|
||||
ret = append(ret, d)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||
return nil, common.ErrNotImplementedError
|
||||
func getFsType(stat unix.Statfs_t) string {
|
||||
return FSType[int(stat.Vfstype)]
|
||||
}
|
||||
|
||||
29
vendor/github.com/shirou/gopsutil/v3/disk/disk_unix.go
generated
vendored
29
vendor/github.com/shirou/gopsutil/v3/disk/disk_unix.go
generated
vendored
@ -1,5 +1,5 @@
|
||||
//go:build freebsd || linux || darwin
|
||||
// +build freebsd linux darwin
|
||||
//go:build freebsd || linux || darwin || (aix && !cgo)
|
||||
// +build freebsd linux darwin aix,!cgo
|
||||
|
||||
package disk
|
||||
|
||||
@ -27,20 +27,8 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||
InodesFree: (uint64(stat.Ffree)),
|
||||
}
|
||||
|
||||
// if could not get InodesTotal, return empty
|
||||
if ret.InodesTotal < ret.InodesFree {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
ret.InodesUsed = (ret.InodesTotal - ret.InodesFree)
|
||||
ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize)
|
||||
|
||||
if ret.InodesTotal == 0 {
|
||||
ret.InodesUsedPercent = 0
|
||||
} else {
|
||||
ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0
|
||||
}
|
||||
|
||||
if (ret.Used + ret.Free) == 0 {
|
||||
ret.UsedPercent = 0
|
||||
} else {
|
||||
@ -49,6 +37,19 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||
ret.UsedPercent = (float64(ret.Used) / float64(ret.Used+ret.Free)) * 100.0
|
||||
}
|
||||
|
||||
// if could not get InodesTotal, return empty
|
||||
if ret.InodesTotal < ret.InodesFree {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
ret.InodesUsed = (ret.InodesTotal - ret.InodesFree)
|
||||
|
||||
if ret.InodesTotal == 0 {
|
||||
ret.InodesUsedPercent = 0
|
||||
} else {
|
||||
ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
|
||||
4
vendor/github.com/shirou/gopsutil/v3/internal/common/common.go
generated
vendored
4
vendor/github.com/shirou/gopsutil/v3/internal/common/common.go
generated
vendored
@ -114,8 +114,8 @@ func ReadLines(filename string) ([]string, error) {
|
||||
// ReadLinesOffsetN reads contents from file and splits them by new line.
|
||||
// The offset tells at which line number to start.
|
||||
// The count determines the number of lines to read (starting from offset):
|
||||
// n >= 0: at most n lines
|
||||
// n < 0: whole file
|
||||
// n >= 0: at most n lines
|
||||
// n < 0: whole file
|
||||
func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
|
||||
3
vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go
generated
vendored
3
vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go
generated
vendored
@ -149,6 +149,9 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) {
|
||||
if StringsContains(contents, "kvm") {
|
||||
system = "kvm"
|
||||
role = "host"
|
||||
} else if StringsContains(contents, "hv_util") {
|
||||
system = "hyperv"
|
||||
role = "guest"
|
||||
} else if StringsContains(contents, "vboxdrv") {
|
||||
system = "vbox"
|
||||
role = "host"
|
||||
|
||||
2
vendor/github.com/shirou/gopsutil/v3/net/net_linux.go
generated
vendored
2
vendor/github.com/shirou/gopsutil/v3/net/net_linux.go
generated
vendored
@ -161,7 +161,7 @@ var netProtocols = []string{
|
||||
// If protocols is empty then all protocols are returned, otherwise
|
||||
// just the protocols in the list are returned.
|
||||
// Available protocols:
|
||||
// ip,icmp,icmpmsg,tcp,udp,udplite
|
||||
// [ip,icmp,icmpmsg,tcp,udp,udplite]
|
||||
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
|
||||
return ProtoCountersWithContext(context.Background(), protocols)
|
||||
}
|
||||
|
||||
2
vendor/github.com/shirou/gopsutil/v3/process/process_windows.go
generated
vendored
2
vendor/github.com/shirou/gopsutil/v3/process/process_windows.go
generated
vendored
@ -408,7 +408,7 @@ func (p *Process) CwdWithContext(_ context.Context) (string, error) {
|
||||
}
|
||||
if userProcParams.CurrentDirectoryPathNameLength > 0 {
|
||||
cwd := readProcessMemory(syscall.Handle(h), procIs32Bits, uint64(userProcParams.CurrentDirectoryPathAddress), uint(userProcParams.CurrentDirectoryPathNameLength))
|
||||
if len(cwd) != int(userProcParams.CurrentDirectoryPathAddress) {
|
||||
if len(cwd) != int(userProcParams.CurrentDirectoryPathNameLength) {
|
||||
return "", errors.New("cannot read current working directory")
|
||||
}
|
||||
|
||||
|
||||
10
vendor/github.com/swaggo/echo-swagger/swagger.go
generated
vendored
10
vendor/github.com/swaggo/echo-swagger/swagger.go
generated
vendored
@ -22,6 +22,7 @@ type Config struct {
|
||||
InstanceName string
|
||||
DeepLinking bool
|
||||
PersistAuthorization bool
|
||||
SyntaxHighlight bool
|
||||
|
||||
// The information for OAuth2 integration, if any.
|
||||
OAuth *OAuthConfig
|
||||
@ -54,6 +55,13 @@ func DeepLinking(deepLinking bool) func(*Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// SyntaxHighlight true, false.
|
||||
func SyntaxHighlight(syntaxHighlight bool) func(*Config) {
|
||||
return func(c *Config) {
|
||||
c.SyntaxHighlight = syntaxHighlight
|
||||
}
|
||||
}
|
||||
|
||||
// DocExpansion list, full, none.
|
||||
func DocExpansion(docExpansion string) func(*Config) {
|
||||
return func(c *Config) {
|
||||
@ -97,6 +105,7 @@ func newConfig(configFns ...func(*Config)) *Config {
|
||||
InstanceName: "swagger",
|
||||
DeepLinking: true,
|
||||
PersistAuthorization: false,
|
||||
SyntaxHighlight: true,
|
||||
}
|
||||
|
||||
for _, fn := range configFns {
|
||||
@ -257,6 +266,7 @@ window.onload = function() {
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "{{.URL}}",
|
||||
syntaxHighlight: {{.SyntaxHighlight}},
|
||||
deepLinking: {{.DeepLinking}},
|
||||
docExpansion: "{{.DocExpansion}}",
|
||||
persistAuthorization: {{.PersistAuthorization}},
|
||||
|
||||
5
vendor/github.com/swaggo/swag/README.md
generated
vendored
5
vendor/github.com/swaggo/swag/README.md
generated
vendored
@ -52,12 +52,9 @@ Swag converts Go annotations to Swagger Documentation 2.0. We've created a varie
|
||||
|
||||
2. Download swag by using:
|
||||
```sh
|
||||
$ go get -u github.com/swaggo/swag/cmd/swag
|
||||
|
||||
# 1.16 or newer
|
||||
$ go install github.com/swaggo/swag/cmd/swag@latest
|
||||
```
|
||||
To build from source you need [Go](https://golang.org/dl/) (1.15 or newer).
|
||||
To build from source you need [Go](https://golang.org/dl/) (1.16 or newer).
|
||||
|
||||
Or download a pre-compiled binary from the [release page](https://github.com/swaggo/swag/releases).
|
||||
|
||||
|
||||
5
vendor/github.com/swaggo/swag/README_zh-CN.md
generated
vendored
5
vendor/github.com/swaggo/swag/README_zh-CN.md
generated
vendored
@ -47,13 +47,10 @@ Swag将Go的注释转换为Swagger2.0文档。我们为流行的 [Go Web Framewo
|
||||
2. 使用如下命令下载swag:
|
||||
|
||||
```bash
|
||||
$ go get -u github.com/swaggo/swag/cmd/swag
|
||||
|
||||
# 1.16 及以上版本
|
||||
$ go install github.com/swaggo/swag/cmd/swag@latest
|
||||
```
|
||||
|
||||
从源码开始构建的话,需要有Go环境(1.15及以上版本)。
|
||||
从源码开始构建的话,需要有Go环境(1.16及以上版本)。
|
||||
|
||||
或者从github的release页面下载预编译好的二进制文件。
|
||||
|
||||
|
||||
98
vendor/github.com/swaggo/swag/formatter.go
generated
vendored
98
vendor/github.com/swaggo/swag/formatter.go
generated
vendored
@ -2,21 +2,18 @@ package swag
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
goparser "go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
)
|
||||
|
||||
const splitTag = "&*"
|
||||
|
||||
// Check of @Param @Success @Failure @Response @Header
|
||||
var specialTagForSplit = map[string]bool{
|
||||
paramAttr: true,
|
||||
@ -55,48 +52,93 @@ func (f *Formatter) Format(fileName string, contents []byte) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
formattedComments := bytes.Buffer{}
|
||||
oldComments := map[string]string{}
|
||||
|
||||
if ast.Comments != nil {
|
||||
for _, comment := range ast.Comments {
|
||||
formatFuncDoc(comment.List, &formattedComments, oldComments)
|
||||
}
|
||||
// Formatting changes are described as an edit list of byte range
|
||||
// replacements. We make these content-level edits directly rather than
|
||||
// changing the AST nodes and writing those out (via [go/printer] or
|
||||
// [go/format]) so that we only change the formatting of Swag attribute
|
||||
// comments. This won't touch the formatting of any other comments, or of
|
||||
// functions, etc.
|
||||
maxEdits := 0
|
||||
for _, comment := range ast.Comments {
|
||||
maxEdits += len(comment.List)
|
||||
}
|
||||
return formatComments(fileName, contents, formattedComments.Bytes(), oldComments), nil
|
||||
edits := make(edits, 0, maxEdits)
|
||||
|
||||
for _, comment := range ast.Comments {
|
||||
formatFuncDoc(fileSet, comment.List, &edits)
|
||||
}
|
||||
|
||||
return edits.apply(contents), nil
|
||||
}
|
||||
|
||||
func formatComments(fileName string, contents []byte, formattedComments []byte, oldComments map[string]string) []byte {
|
||||
for _, comment := range bytes.Split(formattedComments, []byte("\n")) {
|
||||
splits := bytes.SplitN(comment, []byte(splitTag), 2)
|
||||
if len(splits) == 2 {
|
||||
hash, line := splits[0], splits[1]
|
||||
contents = bytes.Replace(contents, []byte(oldComments[string(hash)]), line, 1)
|
||||
}
|
||||
type edit struct {
|
||||
begin int
|
||||
end int
|
||||
replacement []byte
|
||||
}
|
||||
|
||||
type edits []edit
|
||||
|
||||
func (edits edits) apply(contents []byte) []byte {
|
||||
// Apply the edits with the highest offset first, so that earlier edits
|
||||
// don't affect the offsets of later edits.
|
||||
sort.Slice(edits, func(i, j int) bool {
|
||||
return edits[i].begin > edits[j].begin
|
||||
})
|
||||
|
||||
for _, edit := range edits {
|
||||
prefix := contents[:edit.begin]
|
||||
suffix := contents[edit.end:]
|
||||
contents = append(prefix, append(edit.replacement, suffix...)...)
|
||||
}
|
||||
|
||||
return contents
|
||||
}
|
||||
|
||||
func formatFuncDoc(commentList []*ast.Comment, formattedComments io.Writer, oldCommentsMap map[string]string) {
|
||||
w := tabwriter.NewWriter(formattedComments, 0, 0, 1, ' ', 0)
|
||||
// formatFuncDoc reformats the comment lines in commentList, and appends any
|
||||
// changes to the edit list.
|
||||
func formatFuncDoc(fileSet *token.FileSet, commentList []*ast.Comment, edits *edits) {
|
||||
// Building the edit list to format a comment block is a two-step process.
|
||||
// First, we iterate over each comment line looking for Swag attributes. In
|
||||
// each one we find, we replace alignment whitespace with a tab character,
|
||||
// then write the result into a tab writer.
|
||||
|
||||
for _, comment := range commentList {
|
||||
linesToComments := make(map[int]int, len(commentList))
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
w := tabwriter.NewWriter(buffer, 0, 0, 1, ' ', 0)
|
||||
|
||||
for commentIndex, comment := range commentList {
|
||||
text := comment.Text
|
||||
if attr, body, found := swagComment(text); found {
|
||||
cmd5 := fmt.Sprintf("%x", md5.Sum([]byte(text)))
|
||||
oldCommentsMap[cmd5] = text
|
||||
|
||||
formatted := "// " + attr
|
||||
if body != "" {
|
||||
formatted += "\t" + splitComment2(attr, body)
|
||||
}
|
||||
// md5 + splitTag + srcCommentLine
|
||||
// eg. xxx&*@Description get struct array
|
||||
_, _ = fmt.Fprintln(w, cmd5+splitTag+formatted)
|
||||
_, _ = fmt.Fprintln(w, formatted)
|
||||
linesToComments[len(linesToComments)] = commentIndex
|
||||
}
|
||||
}
|
||||
// format by tabwriter
|
||||
|
||||
// Once we've loaded all of the comment lines to be aligned into the tab
|
||||
// writer, flushing it causes the aligned text to be written out to the
|
||||
// backing buffer.
|
||||
_ = w.Flush()
|
||||
|
||||
// Now the second step: we iterate over the aligned comment lines that were
|
||||
// written into the backing buffer, pair each one up to its original
|
||||
// comment line, and use the combination to describe the edit that needs to
|
||||
// be made to the original input.
|
||||
formattedComments := bytes.Split(buffer.Bytes(), []byte("\n"))
|
||||
for lineIndex, commentIndex := range linesToComments {
|
||||
comment := commentList[commentIndex]
|
||||
*edits = append(*edits, edit{
|
||||
begin: fileSet.Position(comment.Pos()).Offset,
|
||||
end: fileSet.Position(comment.End()).Offset,
|
||||
replacement: formattedComments[lineIndex],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func splitComment2(attr, body string) string {
|
||||
|
||||
263
vendor/github.com/swaggo/swag/generics.go
generated
vendored
263
vendor/github.com/swaggo/swag/generics.go
generated
vendored
@ -6,10 +6,14 @@ package swag
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-openapi/spec"
|
||||
"go/ast"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var genericDefinitionsMutex = &sync.RWMutex{}
|
||||
var genericsDefinitions = map[*TypeSpecDef]map[string]*TypeSpecDef{}
|
||||
|
||||
type genericTypeSpec struct {
|
||||
@ -55,9 +59,12 @@ func typeSpecFullName(typeSpecDef *TypeSpecDef) string {
|
||||
return fullName
|
||||
}
|
||||
|
||||
func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, fullGenericForm string, parseDependency bool) *TypeSpecDef {
|
||||
if spec, ok := genericsDefinitions[original][fullGenericForm]; ok {
|
||||
return spec
|
||||
func (pkgDefs *PackagesDefinitions) parametrizeGenericType(file *ast.File, original *TypeSpecDef, fullGenericForm string, parseDependency bool) *TypeSpecDef {
|
||||
genericDefinitionsMutex.RLock()
|
||||
tSpec, ok := genericsDefinitions[original][fullGenericForm]
|
||||
genericDefinitionsMutex.RUnlock()
|
||||
if ok {
|
||||
return tSpec
|
||||
}
|
||||
|
||||
pkgName := strings.Split(fullGenericForm, ".")[0]
|
||||
@ -81,7 +88,11 @@ func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, ful
|
||||
arrayDepth++
|
||||
}
|
||||
|
||||
tdef := pkgDefs.FindTypeSpec(genericParam, original.File, parseDependency)
|
||||
tdef := pkgDefs.FindTypeSpec(genericParam, file, parseDependency)
|
||||
if tdef != nil && !strings.Contains(genericParam, ".") {
|
||||
genericParam = fullTypeName(file.Name.Name, genericParam)
|
||||
}
|
||||
|
||||
genericParamTypeDefs[original.TypeSpec.TypeParams.List[i].Names[0].Name] = &genericTypeSpec{
|
||||
ArrayDepth: arrayDepth,
|
||||
TypeSpec: tdef,
|
||||
@ -132,31 +143,12 @@ func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, ful
|
||||
ident.Name = string(IgnoreNameOverridePrefix) + ident.Name
|
||||
|
||||
parametrizedTypeSpec.TypeSpec.Name = ident
|
||||
origStructType := original.TypeSpec.Type.(*ast.StructType)
|
||||
|
||||
newStructTypeDef := &ast.StructType{
|
||||
Struct: origStructType.Struct,
|
||||
Incomplete: origStructType.Incomplete,
|
||||
Fields: &ast.FieldList{
|
||||
Opening: origStructType.Fields.Opening,
|
||||
Closing: origStructType.Fields.Closing,
|
||||
},
|
||||
}
|
||||
newType := pkgDefs.resolveGenericType(original.File, original.TypeSpec.Type, genericParamTypeDefs, parseDependency)
|
||||
|
||||
for _, field := range origStructType.Fields.List {
|
||||
newField := &ast.Field{
|
||||
Doc: field.Doc,
|
||||
Names: field.Names,
|
||||
Tag: field.Tag,
|
||||
Comment: field.Comment,
|
||||
}
|
||||
|
||||
newField.Type = resolveType(field.Type, field, genericParamTypeDefs)
|
||||
|
||||
newStructTypeDef.Fields.List = append(newStructTypeDef.Fields.List, newField)
|
||||
}
|
||||
|
||||
parametrizedTypeSpec.TypeSpec.Type = newStructTypeDef
|
||||
genericDefinitionsMutex.Lock()
|
||||
defer genericDefinitionsMutex.Unlock()
|
||||
parametrizedTypeSpec.TypeSpec.Type = newType
|
||||
if genericsDefinitions[original] == nil {
|
||||
genericsDefinitions[original] = map[string]*TypeSpecDef{}
|
||||
}
|
||||
@ -166,12 +158,20 @@ func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, ful
|
||||
|
||||
// splitStructName splits a generic struct name in his parts
|
||||
func splitStructName(fullGenericForm string) (string, []string) {
|
||||
//remove all spaces character
|
||||
fullGenericForm = strings.Map(func(r rune) rune {
|
||||
if unicode.IsSpace(r) {
|
||||
return -1
|
||||
}
|
||||
return r
|
||||
}, fullGenericForm)
|
||||
|
||||
// split only at the first '[' and remove the last ']'
|
||||
if fullGenericForm[len(fullGenericForm)-1] != ']' {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
genericParams := strings.SplitN(strings.TrimSpace(fullGenericForm)[:len(fullGenericForm)-1], "[", 2)
|
||||
genericParams := strings.SplitN(fullGenericForm[:len(fullGenericForm)-1], "[", 2)
|
||||
if len(genericParams) == 1 {
|
||||
return "", nil
|
||||
}
|
||||
@ -179,73 +179,121 @@ func splitStructName(fullGenericForm string) (string, []string) {
|
||||
// generic type name
|
||||
genericTypeName := genericParams[0]
|
||||
|
||||
// generic params
|
||||
insideBrackets := 0
|
||||
lastParam := ""
|
||||
params := strings.Split(genericParams[1], ",")
|
||||
genericParams = []string{}
|
||||
for _, p := range params {
|
||||
numOpened := strings.Count(p, "[")
|
||||
numClosed := strings.Count(p, "]")
|
||||
if numOpened == numClosed && insideBrackets == 0 {
|
||||
genericParams = append(genericParams, strings.TrimSpace(p))
|
||||
continue
|
||||
}
|
||||
|
||||
insideBrackets += numOpened - numClosed
|
||||
lastParam += p + ","
|
||||
|
||||
if insideBrackets == 0 {
|
||||
genericParams = append(genericParams, strings.TrimSpace(strings.TrimRight(lastParam, ",")))
|
||||
lastParam = ""
|
||||
depth := 0
|
||||
genericParams = strings.FieldsFunc(genericParams[1], func(r rune) bool {
|
||||
if r == '[' {
|
||||
depth++
|
||||
} else if r == ']' {
|
||||
depth--
|
||||
} else if r == ',' && depth == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
if depth != 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return genericTypeName, genericParams
|
||||
}
|
||||
|
||||
func resolveType(expr ast.Expr, field *ast.Field, genericParamTypeDefs map[string]*genericTypeSpec) ast.Expr {
|
||||
func (pkgDefs *PackagesDefinitions) resolveGenericType(file *ast.File, expr ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec, parseDependency bool) ast.Expr {
|
||||
switch astExpr := expr.(type) {
|
||||
case *ast.Ident:
|
||||
if genTypeSpec, ok := genericParamTypeDefs[astExpr.Name]; ok {
|
||||
if genTypeSpec.ArrayDepth > 0 {
|
||||
genTypeSpec.ArrayDepth--
|
||||
return &ast.ArrayType{Elt: resolveType(expr, field, genericParamTypeDefs)}
|
||||
retType := genTypeSpec.Type()
|
||||
for i := 0; i < genTypeSpec.ArrayDepth; i++ {
|
||||
retType = &ast.ArrayType{Elt: retType}
|
||||
}
|
||||
return genTypeSpec.Type()
|
||||
return retType
|
||||
}
|
||||
case *ast.ArrayType:
|
||||
return &ast.ArrayType{
|
||||
Elt: resolveType(astExpr.Elt, field, genericParamTypeDefs),
|
||||
Elt: pkgDefs.resolveGenericType(file, astExpr.Elt, genericParamTypeDefs, parseDependency),
|
||||
Len: astExpr.Len,
|
||||
Lbrack: astExpr.Lbrack,
|
||||
}
|
||||
}
|
||||
case *ast.StarExpr:
|
||||
return &ast.StarExpr{
|
||||
Star: astExpr.Star,
|
||||
X: pkgDefs.resolveGenericType(file, astExpr.X, genericParamTypeDefs, parseDependency),
|
||||
}
|
||||
case *ast.IndexExpr, *ast.IndexListExpr:
|
||||
fullGenericName, _ := getGenericFieldType(file, expr, genericParamTypeDefs)
|
||||
typeDef := pkgDefs.findGenericTypeSpec(fullGenericName, file, parseDependency)
|
||||
if typeDef != nil {
|
||||
return typeDef.TypeSpec.Type
|
||||
}
|
||||
case *ast.StructType:
|
||||
newStructTypeDef := &ast.StructType{
|
||||
Struct: astExpr.Struct,
|
||||
Incomplete: astExpr.Incomplete,
|
||||
Fields: &ast.FieldList{
|
||||
Opening: astExpr.Fields.Opening,
|
||||
Closing: astExpr.Fields.Closing,
|
||||
},
|
||||
}
|
||||
|
||||
return field.Type
|
||||
for _, field := range astExpr.Fields.List {
|
||||
newField := &ast.Field{
|
||||
Type: field.Type,
|
||||
Doc: field.Doc,
|
||||
Names: field.Names,
|
||||
Tag: field.Tag,
|
||||
Comment: field.Comment,
|
||||
}
|
||||
|
||||
newField.Type = pkgDefs.resolveGenericType(file, field.Type, genericParamTypeDefs, parseDependency)
|
||||
|
||||
newStructTypeDef.Fields.List = append(newStructTypeDef.Fields.List, newField)
|
||||
}
|
||||
return newStructTypeDef
|
||||
}
|
||||
return expr
|
||||
}
|
||||
|
||||
func getGenericFieldType(file *ast.File, field ast.Expr) (string, error) {
|
||||
func getExtendedGenericFieldType(file *ast.File, field ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) (string, error) {
|
||||
switch fieldType := field.(type) {
|
||||
case *ast.ArrayType:
|
||||
fieldName, err := getExtendedGenericFieldType(file, fieldType.Elt, genericParamTypeDefs)
|
||||
return "[]" + fieldName, err
|
||||
case *ast.StarExpr:
|
||||
return getExtendedGenericFieldType(file, fieldType.X, genericParamTypeDefs)
|
||||
case *ast.Ident:
|
||||
if genericParamTypeDefs != nil {
|
||||
if typeSpec, ok := genericParamTypeDefs[fieldType.Name]; ok {
|
||||
return typeSpec.Name, nil
|
||||
}
|
||||
}
|
||||
if fieldType.Obj == nil {
|
||||
return fieldType.Name, nil
|
||||
}
|
||||
|
||||
tSpec := &TypeSpecDef{
|
||||
File: file,
|
||||
TypeSpec: fieldType.Obj.Decl.(*ast.TypeSpec),
|
||||
PkgPath: file.Name.Name,
|
||||
}
|
||||
return tSpec.FullName(), nil
|
||||
default:
|
||||
return getFieldType(file, field)
|
||||
}
|
||||
}
|
||||
|
||||
func getGenericFieldType(file *ast.File, field ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) (string, error) {
|
||||
var fullName string
|
||||
var baseName string
|
||||
var err error
|
||||
switch fieldType := field.(type) {
|
||||
case *ast.IndexListExpr:
|
||||
fullName, err := getGenericTypeName(file, fieldType.X)
|
||||
baseName, err = getGenericTypeName(file, fieldType.X)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fullName += "["
|
||||
fullName = baseName + "["
|
||||
|
||||
for _, index := range fieldType.Indices {
|
||||
var fieldName string
|
||||
var err error
|
||||
|
||||
switch item := index.(type) {
|
||||
case *ast.ArrayType:
|
||||
fieldName, err = getFieldType(file, item.Elt)
|
||||
fieldName = "[]" + fieldName
|
||||
default:
|
||||
fieldName, err = getFieldType(file, index)
|
||||
}
|
||||
|
||||
fieldName, err := getExtendedGenericFieldType(file, index, genericParamTypeDefs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -253,50 +301,85 @@ func getGenericFieldType(file *ast.File, field ast.Expr) (string, error) {
|
||||
fullName += fieldName + ","
|
||||
}
|
||||
|
||||
return strings.TrimRight(fullName, ",") + "]", nil
|
||||
fullName = strings.TrimRight(fullName, ",") + "]"
|
||||
case *ast.IndexExpr:
|
||||
x, err := getFieldType(file, fieldType.X)
|
||||
baseName, err = getGenericTypeName(file, fieldType.X)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
i, err := getFieldType(file, fieldType.Index)
|
||||
indexName, err := getExtendedGenericFieldType(file, fieldType.Index, genericParamTypeDefs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
packageName := ""
|
||||
if !strings.Contains(x, ".") {
|
||||
if file.Name == nil {
|
||||
return "", errors.New("file name is nil")
|
||||
}
|
||||
packageName, _ = getFieldType(file, file.Name)
|
||||
}
|
||||
|
||||
return strings.TrimLeft(fmt.Sprintf("%s.%s[%s]", packageName, x, i), "."), nil
|
||||
fullName = fmt.Sprintf("%s[%s]", baseName, indexName)
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("unknown field type %#v", field)
|
||||
if fullName == "" {
|
||||
return "", fmt.Errorf("unknown field type %#v", field)
|
||||
}
|
||||
|
||||
var packageName string
|
||||
if !strings.Contains(baseName, ".") {
|
||||
if file.Name == nil {
|
||||
return "", errors.New("file name is nil")
|
||||
}
|
||||
packageName, _ = getFieldType(file, file.Name)
|
||||
}
|
||||
|
||||
return strings.TrimLeft(fmt.Sprintf("%s.%s", packageName, fullName), "."), nil
|
||||
}
|
||||
|
||||
func getGenericTypeName(file *ast.File, field ast.Expr) (string, error) {
|
||||
switch indexType := field.(type) {
|
||||
switch fieldType := field.(type) {
|
||||
case *ast.Ident:
|
||||
spec := &TypeSpecDef{
|
||||
if fieldType.Obj == nil {
|
||||
return fieldType.Name, nil
|
||||
}
|
||||
|
||||
tSpec := &TypeSpecDef{
|
||||
File: file,
|
||||
TypeSpec: indexType.Obj.Decl.(*ast.TypeSpec),
|
||||
TypeSpec: fieldType.Obj.Decl.(*ast.TypeSpec),
|
||||
PkgPath: file.Name.Name,
|
||||
}
|
||||
return spec.FullName(), nil
|
||||
return tSpec.FullName(), nil
|
||||
case *ast.ArrayType:
|
||||
spec := &TypeSpecDef{
|
||||
tSpec := &TypeSpecDef{
|
||||
File: file,
|
||||
TypeSpec: indexType.Elt.(*ast.Ident).Obj.Decl.(*ast.TypeSpec),
|
||||
TypeSpec: fieldType.Elt.(*ast.Ident).Obj.Decl.(*ast.TypeSpec),
|
||||
PkgPath: file.Name.Name,
|
||||
}
|
||||
return spec.FullName(), nil
|
||||
return tSpec.FullName(), nil
|
||||
case *ast.SelectorExpr:
|
||||
return fmt.Sprintf("%s.%s", indexType.X.(*ast.Ident).Name, indexType.Sel.Name), nil
|
||||
return fmt.Sprintf("%s.%s", fieldType.X.(*ast.Ident).Name, fieldType.Sel.Name), nil
|
||||
}
|
||||
return "", fmt.Errorf("unknown type %#v", field)
|
||||
}
|
||||
|
||||
func (parser *Parser) parseGenericTypeExpr(file *ast.File, typeExpr ast.Expr) (*spec.Schema, error) {
|
||||
switch expr := typeExpr.(type) {
|
||||
// suppress debug messages for these types
|
||||
case *ast.InterfaceType:
|
||||
case *ast.StructType:
|
||||
case *ast.Ident:
|
||||
case *ast.StarExpr:
|
||||
case *ast.SelectorExpr:
|
||||
case *ast.ArrayType:
|
||||
case *ast.MapType:
|
||||
case *ast.FuncType:
|
||||
case *ast.IndexExpr:
|
||||
name, err := getExtendedGenericFieldType(file, expr, nil)
|
||||
if err == nil {
|
||||
if schema, err := parser.getTypeSchema(name, file, false); err == nil {
|
||||
return schema, nil
|
||||
}
|
||||
}
|
||||
|
||||
parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead. (%s)\n", typeExpr, err)
|
||||
default:
|
||||
parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
|
||||
}
|
||||
|
||||
return PrimitiveSchema(OBJECT), nil
|
||||
}
|
||||
|
||||
29
vendor/github.com/swaggo/swag/generics_other.go
generated
vendored
29
vendor/github.com/swaggo/swag/generics_other.go
generated
vendored
@ -5,17 +5,42 @@ package swag
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/go-openapi/spec"
|
||||
"go/ast"
|
||||
)
|
||||
|
||||
type genericTypeSpec struct {
|
||||
ArrayDepth int
|
||||
TypeSpec *TypeSpecDef
|
||||
Name string
|
||||
}
|
||||
|
||||
func typeSpecFullName(typeSpecDef *TypeSpecDef) string {
|
||||
return typeSpecDef.FullName()
|
||||
}
|
||||
|
||||
func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, fullGenericForm string, parseDependency bool) *TypeSpecDef {
|
||||
func (pkgDefs *PackagesDefinitions) parametrizeGenericType(file *ast.File, original *TypeSpecDef, fullGenericForm string, parseDependency bool) *TypeSpecDef {
|
||||
return original
|
||||
}
|
||||
|
||||
func getGenericFieldType(file *ast.File, field ast.Expr) (string, error) {
|
||||
func getGenericFieldType(file *ast.File, field ast.Expr, genericParamTypeDefs map[string]*genericTypeSpec) (string, error) {
|
||||
return "", fmt.Errorf("unknown field type %#v", field)
|
||||
}
|
||||
|
||||
func (parser *Parser) parseGenericTypeExpr(file *ast.File, typeExpr ast.Expr) (*spec.Schema, error) {
|
||||
switch typeExpr.(type) {
|
||||
// suppress debug messages for these types
|
||||
case *ast.InterfaceType:
|
||||
case *ast.StructType:
|
||||
case *ast.Ident:
|
||||
case *ast.StarExpr:
|
||||
case *ast.SelectorExpr:
|
||||
case *ast.ArrayType:
|
||||
case *ast.MapType:
|
||||
case *ast.FuncType:
|
||||
default:
|
||||
parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
|
||||
}
|
||||
|
||||
return PrimitiveSchema(OBJECT), nil
|
||||
}
|
||||
|
||||
37
vendor/github.com/swaggo/swag/operation.go
generated
vendored
37
vendor/github.com/swaggo/swag/operation.go
generated
vendored
@ -6,7 +6,6 @@ import (
|
||||
"go/ast"
|
||||
goparser "go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@ -226,7 +225,7 @@ func findInSlice(arr []string, target string) bool {
|
||||
}
|
||||
|
||||
func (operation *Operation) parseArrayParam(param *spec.Parameter, paramType, refType, objectType string) error {
|
||||
if !IsPrimitiveType(refType) {
|
||||
if !IsPrimitiveType(refType) && !(refType == "file" && paramType == "formData") {
|
||||
return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
|
||||
}
|
||||
|
||||
@ -270,7 +269,9 @@ func (operation *Operation) parseArrayParam(param *spec.Parameter, paramType, re
|
||||
|
||||
// ParseParamComment parses params return []string of param properties
|
||||
// E.g. @Param queryText formData string true "The email for login"
|
||||
// [param name] [paramType] [data type] [is mandatory?] [Comment]
|
||||
//
|
||||
// [param name] [paramType] [data type] [is mandatory?] [Comment]
|
||||
//
|
||||
// E.g. @Param some_id path int true "Some ID".
|
||||
func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.File) error {
|
||||
matches := paramPattern.FindStringSubmatch(commentLine)
|
||||
@ -824,6 +825,10 @@ var responsePattern = regexp.MustCompile(`^([\w,]+)\s+([\w{}]+)\s+([\w\-.\\{}=,\
|
||||
var combinedPattern = regexp.MustCompile(`^([\w\-./\[\]]+){(.*)}$`)
|
||||
|
||||
func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File) (*spec.Schema, error) {
|
||||
return parseObjectSchema(operation.parser, refType, astFile)
|
||||
}
|
||||
|
||||
func parseObjectSchema(parser *Parser, refType string, astFile *ast.File) (*spec.Schema, error) {
|
||||
switch {
|
||||
case refType == NIL:
|
||||
return nil, nil
|
||||
@ -838,7 +843,7 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
|
||||
case IsPrimitiveType(refType):
|
||||
return PrimitiveSchema(refType), nil
|
||||
case strings.HasPrefix(refType, "[]"):
|
||||
schema, err := operation.parseObjectSchema(refType[2:], astFile)
|
||||
schema, err := parseObjectSchema(parser, refType[2:], astFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -856,17 +861,17 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
|
||||
return spec.MapProperty(nil), nil
|
||||
}
|
||||
|
||||
schema, err := operation.parseObjectSchema(refType, astFile)
|
||||
schema, err := parseObjectSchema(parser, refType, astFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return spec.MapProperty(schema), nil
|
||||
case strings.Contains(refType, "{"):
|
||||
return operation.parseCombinedObjectSchema(refType, astFile)
|
||||
return parseCombinedObjectSchema(parser, refType, astFile)
|
||||
default:
|
||||
if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
|
||||
schema, err := operation.parser.getTypeSchema(refType, astFile, true)
|
||||
if parser != nil { // checking refType has existing in 'TypeDefinitions'
|
||||
schema, err := parser.getTypeSchema(refType, astFile, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -896,13 +901,13 @@ func parseFields(s string) []string {
|
||||
})
|
||||
}
|
||||
|
||||
func (operation *Operation) parseCombinedObjectSchema(refType string, astFile *ast.File) (*spec.Schema, error) {
|
||||
func parseCombinedObjectSchema(parser *Parser, refType string, astFile *ast.File) (*spec.Schema, error) {
|
||||
matches := combinedPattern.FindStringSubmatch(refType)
|
||||
if len(matches) != 3 {
|
||||
return nil, fmt.Errorf("invalid type: %s", refType)
|
||||
}
|
||||
|
||||
schema, err := operation.parseObjectSchema(matches[1], astFile)
|
||||
schema, err := parseObjectSchema(parser, matches[1], astFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -912,7 +917,7 @@ func (operation *Operation) parseCombinedObjectSchema(refType string, astFile *a
|
||||
for _, field := range fields {
|
||||
keyVal := strings.SplitN(field, "=", 2)
|
||||
if len(keyVal) == 2 {
|
||||
schema, err := operation.parseObjectSchema(keyVal[1], astFile)
|
||||
schema, err := parseObjectSchema(parser, keyVal[1], astFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1193,17 +1198,17 @@ func createParameter(paramType, description, paramName, schemaType string, requi
|
||||
}
|
||||
|
||||
func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error) {
|
||||
filesInfos, err := ioutil.ReadDir(dirPath)
|
||||
dirEntries, err := os.ReadDir(dirPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, fileInfo := range filesInfos {
|
||||
if fileInfo.IsDir() {
|
||||
for _, entry := range dirEntries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
fileName := fileInfo.Name()
|
||||
fileName := entry.Name()
|
||||
|
||||
if !strings.Contains(fileName, ".json") {
|
||||
continue
|
||||
@ -1212,7 +1217,7 @@ func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error
|
||||
if strings.Contains(fileName, summaryName) {
|
||||
fullPath := filepath.Join(dirPath, fileName)
|
||||
|
||||
commentInfo, err := ioutil.ReadFile(fullPath)
|
||||
commentInfo, err := os.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to read code example file %s error: %s ", fullPath, err)
|
||||
}
|
||||
|
||||
42
vendor/github.com/swaggo/swag/packages.go
generated
vendored
42
vendor/github.com/swaggo/swag/packages.go
generated
vendored
@ -164,7 +164,8 @@ func (pkgDefs *PackagesDefinitions) parseTypesFromFile(astFile *ast.File, packag
|
||||
|
||||
func (pkgDefs *PackagesDefinitions) parseFunctionScopedTypesFromFile(astFile *ast.File, packagePath string, parsedSchemas map[*TypeSpecDef]*Schema) {
|
||||
for _, astDeclaration := range astFile.Decls {
|
||||
if funcDeclaration, ok := astDeclaration.(*ast.FuncDecl); ok {
|
||||
funcDeclaration, ok := astDeclaration.(*ast.FuncDecl)
|
||||
if ok && funcDeclaration.Body != nil {
|
||||
for _, stmt := range funcDeclaration.Body.List {
|
||||
if declStmt, ok := (stmt).(*ast.DeclStmt); ok {
|
||||
if genDecl, ok := (declStmt.Decl).(*ast.GenDecl); ok && genDecl.Tok == token.TYPE {
|
||||
@ -388,25 +389,17 @@ func (pkgDefs *PackagesDefinitions) FindTypeSpec(typeName string, file *ast.File
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(typeName, "[") {
|
||||
// joinedParts differs from typeName in that it does not contain any type parameters
|
||||
joinedParts := strings.Join(parts, ".")
|
||||
for tName, tSpec := range pkgDefs.uniqueDefinitions {
|
||||
if !strings.Contains(tName, "[") {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(tName, joinedParts) {
|
||||
if parametrized := pkgDefs.parametrizeStruct(tSpec, typeName, parseDependency); parametrized != nil {
|
||||
return parametrized
|
||||
}
|
||||
}
|
||||
}
|
||||
if def := pkgDefs.findGenericTypeSpec(typeName, file, parseDependency); def != nil {
|
||||
return def
|
||||
}
|
||||
|
||||
return pkgDefs.findTypeSpec(pkgPath, parts[1])
|
||||
}
|
||||
|
||||
if def := pkgDefs.findGenericTypeSpec(fullTypeName(file.Name.Name, typeName), file, parseDependency); def != nil {
|
||||
return def
|
||||
}
|
||||
|
||||
typeDef, ok := pkgDefs.uniqueDefinitions[fullTypeName(file.Name.Name, typeName)]
|
||||
if ok {
|
||||
return typeDef
|
||||
@ -428,3 +421,22 @@ func (pkgDefs *PackagesDefinitions) FindTypeSpec(typeName string, file *ast.File
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pkgDefs *PackagesDefinitions) findGenericTypeSpec(typeName string, file *ast.File, parseDependency bool) *TypeSpecDef {
|
||||
if strings.Contains(typeName, "[") {
|
||||
// genericName differs from typeName in that it does not contain any type parameters
|
||||
genericName := strings.SplitN(typeName, "[", 2)[0]
|
||||
for tName, tSpec := range pkgDefs.uniqueDefinitions {
|
||||
if !strings.Contains(tName, "[") {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(tName, genericName) {
|
||||
if parametrized := pkgDefs.parametrizeGenericType(file, tSpec, typeName, parseDependency); parametrized != nil {
|
||||
return parametrized
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
23
vendor/github.com/swaggo/swag/parser.go
generated
vendored
23
vendor/github.com/swaggo/swag/parser.go
generated
vendored
@ -9,7 +9,6 @@ import (
|
||||
"go/build"
|
||||
goparser "go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -733,17 +732,17 @@ func isGeneralAPIComment(comments []string) bool {
|
||||
}
|
||||
|
||||
func getMarkdownForTag(tagName string, dirPath string) ([]byte, error) {
|
||||
filesInfos, err := ioutil.ReadDir(dirPath)
|
||||
dirEntries, err := os.ReadDir(dirPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, fileInfo := range filesInfos {
|
||||
if fileInfo.IsDir() {
|
||||
for _, entry := range dirEntries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
fileName := fileInfo.Name()
|
||||
fileName := entry.Name()
|
||||
|
||||
if !strings.Contains(fileName, ".md") {
|
||||
continue
|
||||
@ -752,7 +751,7 @@ func getMarkdownForTag(tagName string, dirPath string) ([]byte, error) {
|
||||
if strings.Contains(fileName, tagName) {
|
||||
fullPath := filepath.Join(dirPath, fileName)
|
||||
|
||||
commentInfo, err := ioutil.ReadFile(fullPath)
|
||||
commentInfo, err := os.ReadFile(fullPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to read markdown file %s error: %s ", fullPath, err)
|
||||
}
|
||||
@ -873,7 +872,7 @@ func convertFromSpecificToPrimitive(typeName string) (string, error) {
|
||||
func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (*spec.Schema, error) {
|
||||
if override, ok := parser.Overrides[typeName]; ok {
|
||||
parser.debug.Printf("Override detected for %s: using %s instead", typeName, override)
|
||||
typeName = override
|
||||
return parseObjectSchema(parser, override, file)
|
||||
}
|
||||
|
||||
if IsInterfaceLike(typeName) {
|
||||
@ -1186,12 +1185,10 @@ func (parser *Parser) parseTypeExpr(file *ast.File, typeExpr ast.Expr, ref bool)
|
||||
|
||||
case *ast.FuncType:
|
||||
return nil, ErrFuncTypeField
|
||||
// ...
|
||||
default:
|
||||
parser.debug.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
|
||||
// ...
|
||||
}
|
||||
|
||||
return PrimitiveSchema(OBJECT), nil
|
||||
return parser.parseGenericTypeExpr(file, typeExpr)
|
||||
}
|
||||
|
||||
func (parser *Parser) parseStruct(file *ast.File, fields *ast.FieldList) (*spec.Schema, error) {
|
||||
@ -1334,7 +1331,7 @@ func getFieldType(file *ast.File, field ast.Expr) (string, error) {
|
||||
|
||||
return fullName, nil
|
||||
default:
|
||||
return getGenericFieldType(file, field)
|
||||
return getGenericFieldType(file, field, nil)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1490,7 +1487,7 @@ func (parser *Parser) getAllGoFileInfoFromDeps(pkg *depth.Pkg) error {
|
||||
|
||||
srcDir := pkg.Raw.Dir
|
||||
|
||||
files, err := ioutil.ReadDir(srcDir) // only parsing files in the dir(don't contain sub dir files)
|
||||
files, err := os.ReadDir(srcDir) // only parsing files in the dir(don't contain sub dir files)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
2
vendor/github.com/swaggo/swag/version.go
generated
vendored
2
vendor/github.com/swaggo/swag/version.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
package swag
|
||||
|
||||
// Version of swag.
|
||||
const Version = "v1.8.5"
|
||||
const Version = "v1.8.7"
|
||||
|
||||
3
vendor/github.com/valyala/fasttemplate/template.go
generated
vendored
3
vendor/github.com/valyala/fasttemplate/template.go
generated
vendored
@ -112,8 +112,7 @@ func ExecuteFuncString(template, startTag, endTag string, f TagFunc) string {
|
||||
// but when f returns an error, ExecuteFuncStringWithErr won't panic like ExecuteFuncString
|
||||
// it just returns an empty string and the error f returned
|
||||
func ExecuteFuncStringWithErr(template, startTag, endTag string, f TagFunc) (string, error) {
|
||||
tagsCount := bytes.Count(unsafeString2Bytes(template), unsafeString2Bytes(startTag))
|
||||
if tagsCount == 0 {
|
||||
if n := bytes.Index(unsafeString2Bytes(template), unsafeString2Bytes(startTag)); n < 0 {
|
||||
return template, nil
|
||||
}
|
||||
|
||||
|
||||
1
vendor/github.com/vektah/gqlparser/v2/parser/query.go
generated
vendored
1
vendor/github.com/vektah/gqlparser/v2/parser/query.go
generated
vendored
@ -336,7 +336,6 @@ func (p *parser) parseTypeReference() *Type {
|
||||
}
|
||||
|
||||
if p.skip(lexer.Bang) {
|
||||
typ.Position = p.peekPos()
|
||||
typ.NonNull = true
|
||||
}
|
||||
return &typ
|
||||
|
||||
3
vendor/go.uber.org/atomic/.gitignore
generated
vendored
3
vendor/go.uber.org/atomic/.gitignore
generated
vendored
@ -10,3 +10,6 @@ lint.log
|
||||
|
||||
# Profiling output
|
||||
*.prof
|
||||
|
||||
# Output of fossa analyzer
|
||||
/fossa
|
||||
|
||||
27
vendor/go.uber.org/atomic/.travis.yml
generated
vendored
27
vendor/go.uber.org/atomic/.travis.yml
generated
vendored
@ -1,27 +0,0 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go_import_path: go.uber.org/atomic
|
||||
|
||||
env:
|
||||
global:
|
||||
- GO111MODULE=on
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: oldstable
|
||||
- go: stable
|
||||
env: LINT=1
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
|
||||
before_install:
|
||||
- go version
|
||||
|
||||
script:
|
||||
- test -z "$LINT" || make lint
|
||||
- make cover
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
61
vendor/go.uber.org/atomic/CHANGELOG.md
generated
vendored
61
vendor/go.uber.org/atomic/CHANGELOG.md
generated
vendored
@ -4,6 +4,37 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.10.0] - 2022-08-11
|
||||
### Added
|
||||
- Add `atomic.Float32` type for atomic operations on `float32`.
|
||||
- Add `CompareAndSwap` and `Swap` methods to `atomic.String`, `atomic.Error`,
|
||||
and `atomic.Value`.
|
||||
- Add generic `atomic.Pointer[T]` type for atomic operations on pointers of any
|
||||
type. This is present only for Go 1.18 or higher, and is a drop-in for
|
||||
replacement for the standard library's `sync/atomic.Pointer` type.
|
||||
|
||||
### Changed
|
||||
- Deprecate `CAS` methods on all types in favor of corresponding
|
||||
`CompareAndSwap` methods.
|
||||
|
||||
Thanks to @eNV25 and @icpd for their contributions to this release.
|
||||
|
||||
[1.10.0]: https://github.com/uber-go/atomic/compare/v1.9.0...v1.10.0
|
||||
|
||||
## [1.9.0] - 2021-07-15
|
||||
### Added
|
||||
- Add `Float64.Swap` to match int atomic operations.
|
||||
- Add `atomic.Time` type for atomic operations on `time.Time` values.
|
||||
|
||||
[1.9.0]: https://github.com/uber-go/atomic/compare/v1.8.0...v1.9.0
|
||||
|
||||
## [1.8.0] - 2021-06-09
|
||||
### Added
|
||||
- Add `atomic.Uintptr` type for atomic operations on `uintptr` values.
|
||||
- Add `atomic.UnsafePointer` type for atomic operations on `unsafe.Pointer` values.
|
||||
|
||||
[1.8.0]: https://github.com/uber-go/atomic/compare/v1.7.0...v1.8.0
|
||||
|
||||
## [1.7.0] - 2020-09-14
|
||||
### Added
|
||||
- Support JSON serialization and deserialization of primitive atomic types.
|
||||
@ -15,32 +46,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Removed
|
||||
- Remove dependency on `golang.org/x/{lint, tools}`.
|
||||
|
||||
[1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0
|
||||
|
||||
## [1.6.0] - 2020-02-24
|
||||
### Changed
|
||||
- Drop library dependency on `golang.org/x/{lint, tools}`.
|
||||
|
||||
[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0
|
||||
|
||||
## [1.5.1] - 2019-11-19
|
||||
- Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together
|
||||
causing `CAS` to fail even though the old value matches.
|
||||
|
||||
[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1
|
||||
|
||||
## [1.5.0] - 2019-10-29
|
||||
### Changed
|
||||
- With Go modules, only the `go.uber.org/atomic` import path is supported now.
|
||||
If you need to use the old import path, please add a `replace` directive to
|
||||
your `go.mod`.
|
||||
|
||||
[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0
|
||||
|
||||
## [1.4.0] - 2019-05-01
|
||||
### Added
|
||||
- Add `atomic.Error` type for atomic operations on `error` values.
|
||||
|
||||
[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0
|
||||
|
||||
## [1.3.2] - 2018-05-02
|
||||
### Added
|
||||
- Add `atomic.Duration` type for atomic operations on `time.Duration` values.
|
||||
|
||||
[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2
|
||||
|
||||
## [1.3.1] - 2017-11-14
|
||||
### Fixed
|
||||
- Revert optimization for `atomic.String.Store("")` which caused data races.
|
||||
|
||||
[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1
|
||||
|
||||
## [1.3.0] - 2017-11-13
|
||||
### Added
|
||||
- Add `atomic.Bool.CAS` for compare-and-swap semantics on bools.
|
||||
@ -48,10 +93,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
- Optimize `atomic.String.Store("")` by avoiding an allocation.
|
||||
|
||||
[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0
|
||||
|
||||
## [1.2.0] - 2017-04-12
|
||||
### Added
|
||||
- Shadow `atomic.Value` from `sync/atomic`.
|
||||
|
||||
[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0
|
||||
|
||||
## [1.1.0] - 2017-03-10
|
||||
### Added
|
||||
- Add atomic `Float64` type.
|
||||
@ -59,18 +108,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
- Support new `go.uber.org/atomic` import path.
|
||||
|
||||
[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0
|
||||
|
||||
## [1.0.0] - 2016-07-18
|
||||
|
||||
- Initial release.
|
||||
|
||||
[1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0
|
||||
[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0
|
||||
[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1
|
||||
[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0
|
||||
[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0
|
||||
[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2
|
||||
[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1
|
||||
[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0
|
||||
[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0
|
||||
[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0
|
||||
[1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0
|
||||
|
||||
1
vendor/go.uber.org/atomic/Makefile
generated
vendored
1
vendor/go.uber.org/atomic/Makefile
generated
vendored
@ -69,6 +69,7 @@ generate: $(GEN_ATOMICINT) $(GEN_ATOMICWRAPPER)
|
||||
generatenodirty:
|
||||
@[ -z "$$(git status --porcelain)" ] || ( \
|
||||
echo "Working tree is dirty. Commit your changes first."; \
|
||||
git status; \
|
||||
exit 1 )
|
||||
@make generate
|
||||
@status=$$(git status --porcelain); \
|
||||
|
||||
4
vendor/go.uber.org/atomic/README.md
generated
vendored
4
vendor/go.uber.org/atomic/README.md
generated
vendored
@ -55,8 +55,8 @@ Released under the [MIT License](LICENSE.txt).
|
||||
|
||||
[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
|
||||
[doc]: https://godoc.org/go.uber.org/atomic
|
||||
[ci-img]: https://travis-ci.com/uber-go/atomic.svg?branch=master
|
||||
[ci]: https://travis-ci.com/uber-go/atomic
|
||||
[ci-img]: https://github.com/uber-go/atomic/actions/workflows/go.yml/badge.svg
|
||||
[ci]: https://github.com/uber-go/atomic/actions/workflows/go.yml
|
||||
[cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg
|
||||
[cov]: https://codecov.io/gh/uber-go/atomic
|
||||
[reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic
|
||||
|
||||
27
vendor/go.uber.org/atomic/bool.go
generated
vendored
27
vendor/go.uber.org/atomic/bool.go
generated
vendored
@ -1,6 +1,6 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
// Copyright (c) 2020-2022 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@ -36,10 +36,10 @@ type Bool struct {
|
||||
var _zeroBool bool
|
||||
|
||||
// NewBool creates a new Bool.
|
||||
func NewBool(v bool) *Bool {
|
||||
func NewBool(val bool) *Bool {
|
||||
x := &Bool{}
|
||||
if v != _zeroBool {
|
||||
x.Store(v)
|
||||
if val != _zeroBool {
|
||||
x.Store(val)
|
||||
}
|
||||
return x
|
||||
}
|
||||
@ -50,19 +50,26 @@ func (x *Bool) Load() bool {
|
||||
}
|
||||
|
||||
// Store atomically stores the passed bool.
|
||||
func (x *Bool) Store(v bool) {
|
||||
x.v.Store(boolToInt(v))
|
||||
func (x *Bool) Store(val bool) {
|
||||
x.v.Store(boolToInt(val))
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap for bool values.
|
||||
func (x *Bool) CAS(o, n bool) bool {
|
||||
return x.v.CAS(boolToInt(o), boolToInt(n))
|
||||
//
|
||||
// Deprecated: Use CompareAndSwap.
|
||||
func (x *Bool) CAS(old, new bool) (swapped bool) {
|
||||
return x.CompareAndSwap(old, new)
|
||||
}
|
||||
|
||||
// CompareAndSwap is an atomic compare-and-swap for bool values.
|
||||
func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) {
|
||||
return x.v.CompareAndSwap(boolToInt(old), boolToInt(new))
|
||||
}
|
||||
|
||||
// Swap atomically stores the given bool and returns the old
|
||||
// value.
|
||||
func (x *Bool) Swap(o bool) bool {
|
||||
return truthy(x.v.Swap(boolToInt(o)))
|
||||
func (x *Bool) Swap(val bool) (old bool) {
|
||||
return truthy(x.v.Swap(boolToInt(val)))
|
||||
}
|
||||
|
||||
// MarshalJSON encodes the wrapped bool into JSON.
|
||||
|
||||
2
vendor/go.uber.org/atomic/bool_ext.go
generated
vendored
2
vendor/go.uber.org/atomic/bool_ext.go
generated
vendored
@ -38,7 +38,7 @@ func boolToInt(b bool) uint32 {
|
||||
}
|
||||
|
||||
// Toggle atomically negates the Boolean and returns the previous value.
|
||||
func (b *Bool) Toggle() bool {
|
||||
func (b *Bool) Toggle() (old bool) {
|
||||
for {
|
||||
old := b.Load()
|
||||
if b.CAS(old, !old) {
|
||||
|
||||
27
vendor/go.uber.org/atomic/duration.go
generated
vendored
27
vendor/go.uber.org/atomic/duration.go
generated
vendored
@ -1,6 +1,6 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
// Copyright (c) 2020-2022 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@ -37,10 +37,10 @@ type Duration struct {
|
||||
var _zeroDuration time.Duration
|
||||
|
||||
// NewDuration creates a new Duration.
|
||||
func NewDuration(v time.Duration) *Duration {
|
||||
func NewDuration(val time.Duration) *Duration {
|
||||
x := &Duration{}
|
||||
if v != _zeroDuration {
|
||||
x.Store(v)
|
||||
if val != _zeroDuration {
|
||||
x.Store(val)
|
||||
}
|
||||
return x
|
||||
}
|
||||
@ -51,19 +51,26 @@ func (x *Duration) Load() time.Duration {
|
||||
}
|
||||
|
||||
// Store atomically stores the passed time.Duration.
|
||||
func (x *Duration) Store(v time.Duration) {
|
||||
x.v.Store(int64(v))
|
||||
func (x *Duration) Store(val time.Duration) {
|
||||
x.v.Store(int64(val))
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap for time.Duration values.
|
||||
func (x *Duration) CAS(o, n time.Duration) bool {
|
||||
return x.v.CAS(int64(o), int64(n))
|
||||
//
|
||||
// Deprecated: Use CompareAndSwap.
|
||||
func (x *Duration) CAS(old, new time.Duration) (swapped bool) {
|
||||
return x.CompareAndSwap(old, new)
|
||||
}
|
||||
|
||||
// CompareAndSwap is an atomic compare-and-swap for time.Duration values.
|
||||
func (x *Duration) CompareAndSwap(old, new time.Duration) (swapped bool) {
|
||||
return x.v.CompareAndSwap(int64(old), int64(new))
|
||||
}
|
||||
|
||||
// Swap atomically stores the given time.Duration and returns the old
|
||||
// value.
|
||||
func (x *Duration) Swap(o time.Duration) time.Duration {
|
||||
return time.Duration(x.v.Swap(int64(o)))
|
||||
func (x *Duration) Swap(val time.Duration) (old time.Duration) {
|
||||
return time.Duration(x.v.Swap(int64(val)))
|
||||
}
|
||||
|
||||
// MarshalJSON encodes the wrapped time.Duration into JSON.
|
||||
|
||||
8
vendor/go.uber.org/atomic/duration_ext.go
generated
vendored
8
vendor/go.uber.org/atomic/duration_ext.go
generated
vendored
@ -25,13 +25,13 @@ import "time"
|
||||
//go:generate bin/gen-atomicwrapper -name=Duration -type=time.Duration -wrapped=Int64 -pack=int64 -unpack=time.Duration -cas -swap -json -imports time -file=duration.go
|
||||
|
||||
// Add atomically adds to the wrapped time.Duration and returns the new value.
|
||||
func (d *Duration) Add(n time.Duration) time.Duration {
|
||||
return time.Duration(d.v.Add(int64(n)))
|
||||
func (d *Duration) Add(delta time.Duration) time.Duration {
|
||||
return time.Duration(d.v.Add(int64(delta)))
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
|
||||
func (d *Duration) Sub(n time.Duration) time.Duration {
|
||||
return time.Duration(d.v.Sub(int64(n)))
|
||||
func (d *Duration) Sub(delta time.Duration) time.Duration {
|
||||
return time.Duration(d.v.Sub(int64(delta)))
|
||||
}
|
||||
|
||||
// String encodes the wrapped value as a string.
|
||||
|
||||
23
vendor/go.uber.org/atomic/error.go
generated
vendored
23
vendor/go.uber.org/atomic/error.go
generated
vendored
@ -1,6 +1,6 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// Copyright (c) 2020 Uber Technologies, Inc.
|
||||
// Copyright (c) 2020-2022 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@ -32,10 +32,10 @@ type Error struct {
|
||||
var _zeroError error
|
||||
|
||||
// NewError creates a new Error.
|
||||
func NewError(v error) *Error {
|
||||
func NewError(val error) *Error {
|
||||
x := &Error{}
|
||||
if v != _zeroError {
|
||||
x.Store(v)
|
||||
if val != _zeroError {
|
||||
x.Store(val)
|
||||
}
|
||||
return x
|
||||
}
|
||||
@ -46,6 +46,17 @@ func (x *Error) Load() error {
|
||||
}
|
||||
|
||||
// Store atomically stores the passed error.
|
||||
func (x *Error) Store(v error) {
|
||||
x.v.Store(packError(v))
|
||||
func (x *Error) Store(val error) {
|
||||
x.v.Store(packError(val))
|
||||
}
|
||||
|
||||
// CompareAndSwap is an atomic compare-and-swap for error values.
|
||||
func (x *Error) CompareAndSwap(old, new error) (swapped bool) {
|
||||
return x.v.CompareAndSwap(packError(old), packError(new))
|
||||
}
|
||||
|
||||
// Swap atomically stores the given error and returns the old
|
||||
// value.
|
||||
func (x *Error) Swap(val error) (old error) {
|
||||
return unpackError(x.v.Swap(packError(val)))
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user