Update dependencies
This commit is contained in:
parent
4334105f95
commit
4cc82dd333
273 changed files with 19686 additions and 3612 deletions
|
|
@ -669,20 +669,6 @@ func (a *api) start() error {
|
||||||
}
|
}
|
||||||
certmagic.Default.DefaultServerName = cfg.Host.Name[0]
|
certmagic.Default.DefaultServerName = cfg.Host.Name[0]
|
||||||
certmagic.Default.Logger = nil
|
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()
|
magic := certmagic.NewDefault()
|
||||||
acme := certmagic.NewACMEIssuer(magic, certmagic.DefaultACME)
|
acme := certmagic.NewACMEIssuer(magic, certmagic.DefaultACME)
|
||||||
|
|
|
||||||
|
|
@ -3837,7 +3837,7 @@ const docTemplate = `{
|
||||||
"description": "The total number of received KM (Key Material) control packets",
|
"description": "The total number of received KM (Key Material) control packets",
|
||||||
"type": "integer"
|
"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",
|
"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"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
|
@ -3945,7 +3945,7 @@ const docTemplate = `{
|
||||||
"description": "The total number of retransmitted packets sent by the SRT sender",
|
"description": "The total number of retransmitted packets sent by the SRT sender",
|
||||||
"type": "integer"
|
"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)",
|
"description": "Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -3829,7 +3829,7 @@
|
||||||
"description": "The total number of received KM (Key Material) control packets",
|
"description": "The total number of received KM (Key Material) control packets",
|
||||||
"type": "integer"
|
"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",
|
"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"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
|
@ -3937,7 +3937,7 @@
|
||||||
"description": "The total number of retransmitted packets sent by the SRT sender",
|
"description": "The total number of retransmitted packets sent by the SRT sender",
|
||||||
"type": "integer"
|
"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)",
|
"description": "Same as pktSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -979,7 +979,7 @@ definitions:
|
||||||
recv_km_pkt:
|
recv_km_pkt:
|
||||||
description: The total number of received KM (Key Material) control packets
|
description: The total number of received KM (Key Material) control packets
|
||||||
type: integer
|
type: integer
|
||||||
recv_loss__bytes:
|
recv_loss_bytes:
|
||||||
description: Same as pktRcvLoss, but expressed in bytes, including payload
|
description: Same as pktRcvLoss, but expressed in bytes, including payload
|
||||||
and all the headers (IP, TCP, SRT), bytes for the presently missing (either
|
and all the headers (IP, TCP, SRT), bytes for the presently missing (either
|
||||||
reordered or lost) packets' payloads are estimated based on the average
|
reordered or lost) packets' payloads are estimated based on the average
|
||||||
|
|
@ -1088,7 +1088,7 @@ definitions:
|
||||||
sent_retrans_pkt:
|
sent_retrans_pkt:
|
||||||
description: The total number of retransmitted packets sent by the SRT sender
|
description: The total number of retransmitted packets sent by the SRT sender
|
||||||
type: integer
|
type: integer
|
||||||
sent_unique__bytes:
|
sent_unique_bytes:
|
||||||
description: Same as pktSentUnique, but expressed in bytes, including payload
|
description: Same as pktSentUnique, but expressed in bytes, including payload
|
||||||
and all the headers (IP, TCP, SRT)
|
and all the headers (IP, TCP, SRT)
|
||||||
type: integer
|
type: integer
|
||||||
|
|
|
||||||
54
go.mod
54
go.mod
|
|
@ -3,29 +3,29 @@ module github.com/datarhei/core/v16
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
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/atrox/haikunatorgo/v2 v2.0.1
|
||||||
github.com/caddyserver/certmagic v0.16.2
|
github.com/caddyserver/certmagic v0.17.2
|
||||||
github.com/datarhei/gosrt v0.2.1-0.20220817080252-d44df04a3845
|
github.com/datarhei/gosrt v0.3.1
|
||||||
github.com/datarhei/joy4 v0.0.0-20220914170649-23c70d207759
|
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/gobwas/glob v0.2.3
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.2
|
github.com/golang-jwt/jwt/v4 v4.4.2
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/invopop/jsonschema v0.4.0
|
github.com/invopop/jsonschema v0.4.0
|
||||||
github.com/joho/godotenv v1.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/lithammer/shortuuid/v4 v4.0.0
|
||||||
github.com/mattn/go-isatty v0.0.16
|
github.com/mattn/go-isatty v0.0.16
|
||||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
|
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
|
||||||
github.com/prometheus/client_golang v1.13.0
|
github.com/prometheus/client_golang v1.13.0
|
||||||
github.com/shirou/gopsutil/v3 v3.22.8
|
github.com/shirou/gopsutil/v3 v3.22.9
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.1
|
||||||
github.com/swaggo/echo-swagger v1.3.4
|
github.com/swaggo/echo-swagger v1.3.5
|
||||||
github.com/swaggo/swag v1.8.5
|
github.com/swaggo/swag v1.8.7
|
||||||
github.com/vektah/gqlparser/v2 v2.5.0
|
github.com/vektah/gqlparser/v2 v2.5.1
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0
|
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 (
|
require (
|
||||||
|
|
@ -49,20 +49,20 @@ require (
|
||||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||||
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.0.11 // indirect
|
github.com/klauspost/cpuid/v2 v2.1.2 // indirect
|
||||||
github.com/labstack/gommon v0.3.1 // indirect
|
github.com/labstack/gommon v0.4.0 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
github.com/libdns/libdns v0.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/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // 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/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/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // 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/common v0.37.0 // indirect
|
||||||
github.com/prometheus/procfs v0.8.0 // indirect
|
github.com/prometheus/procfs v0.8.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.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/tklauser/numcpus v0.5.0 // indirect
|
||||||
github.com/urfave/cli/v2 v2.8.1 // indirect
|
github.com/urfave/cli/v2 v2.8.1 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // 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/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
go.uber.org/zap v1.21.0 // indirect
|
go.uber.org/zap v1.23.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
|
golang.org/x/crypto v0.1.0 // indirect
|
||||||
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 // indirect
|
golang.org/x/net v0.1.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd // indirect
|
golang.org/x/sys v0.1.0 // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.4.0 // indirect
|
||||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
golang.org/x/time v0.1.0 // indirect
|
||||||
golang.org/x/tools v0.1.12 // indirect
|
golang.org/x/tools v0.2.0 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.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.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
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=
|
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.20 h1:O7WzccIhKB1dm+7g6dhQcULINftfiLSBg2l/mwbpJMw=
|
||||||
github.com/99designs/gqlgen v0.17.16/go.mod h1:dnJdUkgfh8iw8CEx2hhTdgTQO/GvVWKLcm/kult5gwI=
|
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 v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
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=
|
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.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
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/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.17.2 h1:o30seC1T/dBqBCNNGNHWwj2i5/I/FMjBbTAhjADP3nE=
|
||||||
github.com/caddyserver/certmagic v0.16.2/go.mod h1:PgLIr/dSJa+WA7t7z6Je5xuS/e5A/GFCPHRuZ1QP+MQ=
|
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/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.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
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 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
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/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.3.1 h1:9A75hIvnY74IUFyeguqYXh1lsGF8Qt8fjxJS2Ewr12Q=
|
||||||
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/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 h1:h8NyekuQSDvLIsZVTV172m5/RVArXkEM/cnHaUzszQU=
|
||||||
github.com/datarhei/joy4 v0.0.0-20220914170649-23c70d207759/go.mod h1:Jcw/6jZDQQmPx8A7INEkXmuEF7E9jjBbSTfVSLwmiQw=
|
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=
|
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/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 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/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.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||||
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
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/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 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
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.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.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.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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
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/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 v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
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/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
|
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/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.1.2 h1:XhdX4fqAJUA0yj+kUwMavO0hHrSPAecYdYf1ZmxHvak=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.11/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
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.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/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=
|
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.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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
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/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.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 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
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=
|
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/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/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-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-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
||||||
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281/go.mod h1:lc+czkgO/8F7puNki5jk8QyujbfK1LOT7Wl0ON2hxyk=
|
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-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/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=
|
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/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
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.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 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
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.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 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
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.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 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80=
|
||||||
github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY=
|
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.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||||
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
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.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 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
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-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-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.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.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.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.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
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/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 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
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.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=
|
||||||
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
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/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.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
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.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.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.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.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.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/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.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.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.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/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/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
github.com/swaggo/echo-swagger v1.3.4/go.mod h1:vh8QAdbHtTXwTSaWzc1Nby7zMYJd/g0FwQyArmrFHA8=
|
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 h1:kAe4YSu0O0UFn1DowNo2MY5p6xzqtJ/wQ7LZynSvGaY=
|
||||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
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.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
|
||||||
github.com/swaggo/swag v1.8.5 h1:7NgtfXsXE+jrcOwRyiftGKW7Ppydj7tZiVenuRf1fE4=
|
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
|
||||||
github.com/swaggo/swag v1.8.5/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
|
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 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
|
||||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
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=
|
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/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 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
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/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/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
github.com/vektah/gqlparser/v2 v2.5.0/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs=
|
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-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 h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
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.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.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.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 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
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.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.3/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.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.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 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
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/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.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-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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
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-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-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-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.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
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.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/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.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-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-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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/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-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-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-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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
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-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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/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-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-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 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-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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-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-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-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-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.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||||
golang.org/x/sys v0.0.0-20220907062415-87db552b00fd/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
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-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.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.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.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.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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/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.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-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-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-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-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.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
|
||||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
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-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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
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.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.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.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.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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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) {
|
func (s *SRTStatistics) Unmarshal(ss *gosrt.Statistics) {
|
||||||
s.MsTimeStamp = ss.MsTimeStamp
|
s.MsTimeStamp = ss.MsTimeStamp
|
||||||
|
|
||||||
s.PktSent = ss.PktSent
|
s.PktSent = ss.Accumulated.PktSent
|
||||||
s.PktRecv = ss.PktRecv
|
s.PktRecv = ss.Accumulated.PktRecv
|
||||||
s.PktSentUnique = ss.PktSentUnique
|
s.PktSentUnique = ss.Accumulated.PktSentUnique
|
||||||
s.PktRecvUnique = ss.PktRecvUnique
|
s.PktRecvUnique = ss.Accumulated.PktRecvUnique
|
||||||
s.PktSndLoss = ss.PktSndLoss
|
s.PktSndLoss = ss.Accumulated.PktSendLoss
|
||||||
s.PktRcvLoss = ss.PktRcvLoss
|
s.PktRcvLoss = ss.Accumulated.PktRecvLoss
|
||||||
s.PktRetrans = ss.PktRetrans
|
s.PktRetrans = ss.Accumulated.PktRetrans
|
||||||
s.PktRcvRetrans = ss.PktRcvRetrans
|
s.PktRcvRetrans = ss.Accumulated.PktRecvRetrans
|
||||||
s.PktSentACK = ss.PktSentACK
|
s.PktSentACK = ss.Accumulated.PktSentACK
|
||||||
s.PktRecvACK = ss.PktRecvACK
|
s.PktRecvACK = ss.Accumulated.PktRecvACK
|
||||||
s.PktSentNAK = ss.PktSentNAK
|
s.PktSentNAK = ss.Accumulated.PktSentNAK
|
||||||
s.PktRecvNAK = ss.PktRecvNAK
|
s.PktRecvNAK = ss.Accumulated.PktRecvNAK
|
||||||
s.PktSentKM = ss.PktSentKM
|
s.PktSentKM = ss.Accumulated.PktSentKM
|
||||||
s.PktRecvKM = ss.PktRecvKM
|
s.PktRecvKM = ss.Accumulated.PktRecvKM
|
||||||
s.UsSndDuration = ss.UsSndDuration
|
s.UsSndDuration = ss.Accumulated.UsSndDuration
|
||||||
s.PktSndDrop = ss.PktSndDrop
|
s.PktSndDrop = ss.Accumulated.PktSendDrop
|
||||||
s.PktRcvDrop = ss.PktRcvDrop
|
s.PktRcvDrop = ss.Accumulated.PktRecvDrop
|
||||||
s.PktRcvUndecrypt = ss.PktRcvUndecrypt
|
s.PktRcvUndecrypt = ss.Accumulated.PktRecvUndecrypt
|
||||||
|
|
||||||
s.ByteSent = ss.ByteSent
|
s.ByteSent = ss.Accumulated.ByteSent
|
||||||
s.ByteRecv = ss.ByteRecv
|
s.ByteRecv = ss.Accumulated.ByteRecv
|
||||||
s.ByteSentUnique = ss.ByteSentUnique
|
s.ByteSentUnique = ss.Accumulated.ByteSentUnique
|
||||||
s.ByteRecvUnique = ss.ByteRecvUnique
|
s.ByteRecvUnique = ss.Accumulated.ByteRecvUnique
|
||||||
s.ByteRcvLoss = ss.ByteRcvLoss
|
s.ByteRcvLoss = ss.Accumulated.ByteRecvLoss
|
||||||
s.ByteRetrans = ss.ByteRetrans
|
s.ByteRetrans = ss.Accumulated.ByteRetrans
|
||||||
s.ByteSndDrop = ss.ByteSndDrop
|
s.ByteSndDrop = ss.Accumulated.ByteSendDrop
|
||||||
s.ByteRcvDrop = ss.ByteRcvDrop
|
s.ByteRcvDrop = ss.Accumulated.ByteRecvDrop
|
||||||
s.ByteRcvUndecrypt = ss.ByteRcvUndecrypt
|
s.ByteRcvUndecrypt = ss.Accumulated.ByteRecvUndecrypt
|
||||||
|
|
||||||
s.UsPktSndPeriod = ss.UsPktSndPeriod
|
s.UsPktSndPeriod = ss.Instantaneous.UsPktSendPeriod
|
||||||
s.PktFlowWindow = ss.PktFlowWindow
|
s.PktFlowWindow = ss.Instantaneous.PktFlowWindow
|
||||||
s.PktFlightSize = ss.PktFlightSize
|
s.PktFlightSize = ss.Instantaneous.PktFlightSize
|
||||||
s.MsRTT = ss.MsRTT
|
s.MsRTT = ss.Instantaneous.MsRTT
|
||||||
s.MbpsBandwidth = ss.MbpsBandwidth
|
s.MbpsBandwidth = ss.Instantaneous.MbpsLinkCapacity
|
||||||
s.ByteAvailSndBuf = ss.ByteAvailSndBuf
|
s.ByteAvailSndBuf = ss.Instantaneous.ByteAvailSendBuf
|
||||||
s.ByteAvailRcvBuf = ss.ByteAvailRcvBuf
|
s.ByteAvailRcvBuf = ss.Instantaneous.ByteAvailRecvBuf
|
||||||
s.MbpsMaxBW = ss.MbpsMaxBW
|
s.MbpsMaxBW = ss.Instantaneous.MbpsMaxBW
|
||||||
s.ByteMSS = ss.ByteMSS
|
s.ByteMSS = ss.Instantaneous.ByteMSS
|
||||||
s.PktSndBuf = ss.PktSndBuf
|
s.PktSndBuf = ss.Instantaneous.PktSendBuf
|
||||||
s.ByteSndBuf = ss.ByteSndBuf
|
s.ByteSndBuf = ss.Instantaneous.ByteSendBuf
|
||||||
s.MsSndBuf = ss.MsSndBuf
|
s.MsSndBuf = ss.Instantaneous.MsSendBuf
|
||||||
s.MsSndTsbPdDelay = ss.MsSndTsbPdDelay
|
s.MsSndTsbPdDelay = ss.Instantaneous.MsSendTsbPdDelay
|
||||||
s.PktRcvBuf = ss.PktRcvBuf
|
s.PktRcvBuf = ss.Instantaneous.PktRecvBuf
|
||||||
s.ByteRcvBuf = ss.ByteRcvBuf
|
s.ByteRcvBuf = ss.Instantaneous.ByteRecvBuf
|
||||||
s.MsRcvBuf = ss.MsRcvBuf
|
s.MsRcvBuf = ss.Instantaneous.MsRecvBuf
|
||||||
s.MsRcvTsbPdDelay = ss.MsRcvTsbPdDelay
|
s.MsRcvTsbPdDelay = ss.Instantaneous.MsRecvTsbPdDelay
|
||||||
s.PktReorderTolerance = ss.PktReorderTolerance
|
s.PktReorderTolerance = ss.Instantaneous.PktReorderTolerance
|
||||||
s.PktRcvAvgBelatedTime = ss.PktRcvAvgBelatedTime
|
s.PktRcvAvgBelatedTime = ss.Instantaneous.PktRecvAvgBelatedTime
|
||||||
}
|
}
|
||||||
|
|
||||||
type SRTLog struct {
|
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)
|
ticker := time.NewTicker(1 * time.Second)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
stats := &srt.Statistics{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
stats := c.conn.Stats()
|
c.conn.Stats(stats)
|
||||||
|
|
||||||
rxbytes := stats.ByteRecv
|
rxbytes := stats.Accumulated.ByteRecv
|
||||||
txbytes := stats.ByteSent
|
txbytes := stats.Accumulated.ByteSent
|
||||||
|
|
||||||
c.collector.Ingress(c.id, int64(rxbytes-c.rxbytes))
|
c.collector.Ingress(c.id, int64(rxbytes-c.rxbytes))
|
||||||
c.collector.Egress(c.id, int64(txbytes-c.txbytes))
|
c.collector.Egress(c.id, int64(txbytes-c.txbytes))
|
||||||
|
|
@ -285,8 +287,11 @@ func (s *server) Channels() Channels {
|
||||||
socketId := ch.publisher.conn.SocketId()
|
socketId := ch.publisher.conn.SocketId()
|
||||||
st.Publisher[id] = socketId
|
st.Publisher[id] = socketId
|
||||||
|
|
||||||
|
stats := &srt.Statistics{}
|
||||||
|
ch.publisher.conn.Stats(stats)
|
||||||
|
|
||||||
st.Connections[socketId] = Connection{
|
st.Connections[socketId] = Connection{
|
||||||
Stats: ch.publisher.conn.Stats(),
|
Stats: *stats,
|
||||||
Log: map[string][]Log{},
|
Log: map[string][]Log{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,8 +299,11 @@ func (s *server) Channels() Channels {
|
||||||
socketId := c.conn.SocketId()
|
socketId := c.conn.SocketId()
|
||||||
st.Subscriber[id] = append(st.Subscriber[id], socketId)
|
st.Subscriber[id] = append(st.Subscriber[id], socketId)
|
||||||
|
|
||||||
|
stats := &srt.Statistics{}
|
||||||
|
c.conn.Stats(stats)
|
||||||
|
|
||||||
st.Connections[socketId] = Connection{
|
st.Connections[socketId] = Connection{
|
||||||
Stats: c.conn.Stats(),
|
Stats: *stats,
|
||||||
Log: map[string][]Log{},
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
<a name="unreleased"></a>
|
<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 if -->
|
||||||
<!-- end of CommitGroups -->
|
<!-- 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>
|
<a name="v0.17.14"></a>
|
||||||
## [v0.17.14](https://github.com/99designs/gqlgen/compare/v0.17.13...v0.17.14) - 2022-08-18
|
## [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
|
- <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.
|
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
|
## Other Resources
|
||||||
|
|
||||||
- [Christopher Biscardi @ Gophercon UK 2018](https://youtu.be/FdURVezcdcw)
|
- [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"`
|
StructTag string `yaml:"struct_tag,omitempty"`
|
||||||
Directives map[string]DirectiveConfig `yaml:"directives,omitempty"`
|
Directives map[string]DirectiveConfig `yaml:"directives,omitempty"`
|
||||||
OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"`
|
OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"`
|
||||||
|
OmitGetters bool `yaml:"omit_getters,omitempty"`
|
||||||
StructFieldsAlwaysPointers bool `yaml:"struct_fields_always_pointers,omitempty"`
|
StructFieldsAlwaysPointers bool `yaml:"struct_fields_always_pointers,omitempty"`
|
||||||
ResolversAlwaysReturnPointers bool `yaml:"resolvers_always_return_pointers,omitempty"`
|
ResolversAlwaysReturnPointers bool `yaml:"resolvers_always_return_pointers,omitempty"`
|
||||||
SkipValidation bool `yaml:"skip_validation,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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/vektah/gqlparser/v2/ast"
|
"github.com/vektah/gqlparser/v2/ast"
|
||||||
)
|
)
|
||||||
|
|
@ -15,6 +16,7 @@ type OperationContext struct {
|
||||||
Variables map[string]interface{}
|
Variables map[string]interface{}
|
||||||
OperationName string
|
OperationName string
|
||||||
Doc *ast.QueryDocument
|
Doc *ast.QueryDocument
|
||||||
|
Headers http.Header
|
||||||
|
|
||||||
Operation *ast.OperationDefinition
|
Operation *ast.OperationDefinition
|
||||||
DisableIntrospection bool
|
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,
|
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) {
|
func RegisterErrorType(code string, kind ErrorKind) {
|
||||||
codeType[code] = kind
|
codeType[code] = kind
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the error code on a given graphql error extension
|
// Set the error code on a given graphql error extension
|
||||||
func Set(err error, value string) {
|
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 {
|
if gqlErr.Extensions == nil {
|
||||||
gqlErr.Extensions = map[string]interface{}{}
|
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]
|
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
|
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{
|
rc := &graphql.OperationContext{
|
||||||
DisableIntrospection: true,
|
DisableIntrospection: true,
|
||||||
RecoverFunc: e.recoverFunc,
|
RecoverFunc: e.recoverFunc,
|
||||||
|
|
@ -58,6 +61,7 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||||
|
|
||||||
rc.RawQuery = params.Query
|
rc.RawQuery = params.Query
|
||||||
rc.OperationName = params.OperationName
|
rc.OperationName = params.OperationName
|
||||||
|
rc.Headers = params.Headers
|
||||||
|
|
||||||
var listErr gqlerror.List
|
var listErr gqlerror.List
|
||||||
rc.Doc, listErr = e.parseQuery(ctx, &rc.Stats, params.Query)
|
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
|
var err error
|
||||||
rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables)
|
rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables)
|
||||||
gqlErr, _ := err.(*gqlerror.Error)
|
|
||||||
if gqlErr != nil {
|
if err != nil {
|
||||||
errcode.Set(gqlErr, errcode.ValidationFailed)
|
gqlErr, ok := err.(*gqlerror.Error)
|
||||||
return rc, gqlerror.List{gqlErr}
|
if ok {
|
||||||
|
errcode.Set(gqlErr, errcode.ValidationFailed)
|
||||||
|
return rc, gqlerror.List{gqlErr}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rc.Stats.Validation.End = graphql.Now()
|
rc.Stats.Validation.End = graphql.Now()
|
||||||
|
|
||||||
|
|
@ -90,7 +97,10 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||||
return rc, nil
|
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)
|
ctx = graphql.WithOperationContext(ctx, rc)
|
||||||
|
|
||||||
var innerCtx context.Context
|
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.
|
// 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.
|
// 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()
|
stats.Parsing.Start = graphql.Now()
|
||||||
|
|
||||||
if doc, ok := e.queryCache.Get(ctx, query); ok {
|
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})
|
doc, err := parser.ParseQuery(&ast.Source{Input: query})
|
||||||
gqlErr, _ := err.(*gqlerror.Error)
|
if err != nil {
|
||||||
if gqlErr != nil {
|
gqlErr, ok := err.(*gqlerror.Error)
|
||||||
errcode.Set(gqlErr, errcode.ParseFailed)
|
if ok {
|
||||||
return nil, gqlerror.List{gqlErr}
|
errcode.Set(gqlErr, errcode.ParseFailed)
|
||||||
|
return nil, gqlerror.List{gqlErr}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stats.Parsing.End = graphql.Now()
|
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
|
// Its important to understand the lifecycle of a graphql request and the terminology we use in gqlgen
|
||||||
// before working with these
|
// before working with these
|
||||||
//
|
//
|
||||||
// +--- REQUEST POST /graphql --------------------------------------------+
|
// +--- REQUEST POST /graphql --------------------------------------------+
|
||||||
// | +- OPERATION query OpName { viewer { name } } -----------------------+ |
|
// | +- OPERATION query OpName { viewer { name } } -----------------------+ |
|
||||||
// | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | |
|
// | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | |
|
||||||
// | +- OPERATION subscription OpName2 { chat { message } } --------------+ |
|
// | +- OPERATION subscription OpName2 { chat { message } } --------------+ |
|
||||||
// | | RESPONSE { "data": { "chat": { "message": "hello" } } } | |
|
// | | RESPONSE { "data": { "chat": { "message": "hello" } } } | |
|
||||||
// | | RESPONSE { "data": { "chat": { "message": "byee" } } } | |
|
// | | RESPONSE { "data": { "chat": { "message": "byee" } } } | |
|
||||||
// | +--------------------------------------------------------------------+ |
|
// | +--------------------------------------------------------------------+ |
|
||||||
// +------------------------------------------------------------------------+
|
// +------------------------------------------------------------------------+
|
||||||
HandlerExtension interface {
|
HandlerExtension interface {
|
||||||
// ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging.
|
// ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging.
|
||||||
ExtensionName() string
|
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>
|
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
<title>{{.title}}</title>
|
<title>{{.title}}</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
|
|
@ -75,15 +76,15 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||||
// Handler responsible for setting up the playground
|
// Handler responsible for setting up the playground
|
||||||
func Handler(title string, endpoint string) http.HandlerFunc {
|
func Handler(title string, endpoint string) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
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{}{
|
err := page.Execute(w, map[string]interface{}{
|
||||||
"title": title,
|
"title": title,
|
||||||
"endpoint": endpoint,
|
"endpoint": endpoint,
|
||||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||||
"version": "2.0.1",
|
"version": "2.0.7",
|
||||||
"cssSRI": "sha256-hYUgpHapGug0ucdB5kG0zSipubcQOJcGjclIZke2rl8=",
|
"cssSRI": "sha256-gQryfbGYeYFxnJYnfPStPYFt0+uv8RP8Dm++eh00G9c=",
|
||||||
"jsSRI": "sha256-jMXGO5+Y4OhcHPSR34jpzpzlz4OZTlxcvaDXSWmUMRo=",
|
"jsSRI": "sha256-qQ6pw7LwTLC+GfzN+cJsYXfVWRKH9O5o7+5H96gTJhQ=",
|
||||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
"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
|
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 {
|
} else if f.Version == 2 {
|
||||||
input += `
|
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 @link(import: [String!], url: String!) repeatable on SCHEMA
|
||||||
directive @shareable on OBJECT | FIELD_DEFINITION
|
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 @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
|
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 {
|
switch schemaType.Kind {
|
||||||
case ast.Interface, ast.Union:
|
case ast.Interface, ast.Union:
|
||||||
fields, err := m.generateFields(cfg, schemaType)
|
var fields []*Field
|
||||||
if err != nil {
|
var err error
|
||||||
return err
|
if !cfg.OmitGetters {
|
||||||
|
fields, err = m.generateFields(cfg, schemaType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
it := &Interface{
|
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.
|
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
|
## 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),
|
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
|
// configure challenges (most of the time, DNS challenge is
|
||||||
// exclusive of other ones because it is usually only used
|
// 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...
|
// TODO: stop rate limiter when it is garbage-collected...
|
||||||
}
|
}
|
||||||
rateLimitersMu.Unlock()
|
rateLimitersMu.Unlock()
|
||||||
if c.iss.Logger != nil {
|
c.iss.Logger.Info("waiting on internal rate limiter",
|
||||||
c.iss.Logger.Info("waiting on internal rate limiter",
|
zap.Strings("identifiers", names),
|
||||||
zap.Strings("identifiers", names),
|
zap.String("ca", c.acmeClient.Directory),
|
||||||
zap.String("ca", c.acmeClient.Directory),
|
zap.String("account", email),
|
||||||
zap.String("account", email),
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
err := rl.Wait(ctx)
|
err := rl.Wait(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if c.iss.Logger != nil {
|
c.iss.Logger.Info("done waiting on internal rate limiter",
|
||||||
c.iss.Logger.Info("done waiting on internal rate limiter",
|
zap.Strings("identifiers", names),
|
||||||
zap.Strings("identifiers", names),
|
zap.String("ca", c.acmeClient.Directory),
|
||||||
zap.String("ca", c.acmeClient.Directory),
|
zap.String("account", email),
|
||||||
zap.String("account", email),
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
return nil
|
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
|
// certificate chains
|
||||||
PreferredChains ChainPreference
|
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
|
Logger *zap.Logger
|
||||||
|
|
||||||
config *Config
|
config *Config
|
||||||
|
|
@ -197,6 +199,11 @@ func NewACMEIssuer(cfg *Config, template ACMEIssuer) *ACMEIssuer {
|
||||||
template.Logger = DefaultACME.Logger
|
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.config = cfg
|
||||||
template.mu = new(sync.Mutex)
|
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.
|
// processing. If there are no matches, the first chain is returned.
|
||||||
func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.Certificate {
|
func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.Certificate {
|
||||||
if len(certChains) == 1 {
|
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",
|
am.Logger.Debug("there is only one chain offered; selecting it regardless of preferences",
|
||||||
zap.String("chain_url", certChains[0].URL))
|
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 {
|
for i, chain := range certChains {
|
||||||
certs, err := parseCertsFromPEMBundle(chain.ChainPEM)
|
certs, err := parseCertsFromPEMBundle(chain.ChainPEM)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if am.Logger != nil {
|
am.Logger.Error("unable to parse PEM certificate chain",
|
||||||
am.Logger.Error("unable to parse PEM certificate chain",
|
zap.Int("chain", i),
|
||||||
zap.Int("chain", i),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
decodedChains[i] = certs
|
decodedChains[i] = certs
|
||||||
|
|
@ -438,11 +443,9 @@ func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.C
|
||||||
for i, chain := range decodedChains {
|
for i, chain := range decodedChains {
|
||||||
for _, cert := range chain {
|
for _, cert := range chain {
|
||||||
if cert.Issuer.CommonName == prefAnyCN {
|
if cert.Issuer.CommonName == prefAnyCN {
|
||||||
if am.Logger != nil {
|
am.Logger.Debug("found preferred certificate chain by issuer common name",
|
||||||
am.Logger.Debug("found preferred certificate chain by issuer common name",
|
zap.String("preference", prefAnyCN),
|
||||||
zap.String("preference", prefAnyCN),
|
zap.Int("chain", i))
|
||||||
zap.Int("chain", i))
|
|
||||||
}
|
|
||||||
return certChains[i]
|
return certChains[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -454,20 +457,16 @@ func (am *ACMEIssuer) selectPreferredChain(certChains []acme.Certificate) acme.C
|
||||||
for _, prefRootCN := range am.PreferredChains.RootCommonName {
|
for _, prefRootCN := range am.PreferredChains.RootCommonName {
|
||||||
for i, chain := range decodedChains {
|
for i, chain := range decodedChains {
|
||||||
if chain[len(chain)-1].Issuer.CommonName == prefRootCN {
|
if chain[len(chain)-1].Issuer.CommonName == prefRootCN {
|
||||||
if am.Logger != nil {
|
am.Logger.Debug("found preferred certificate chain by root common name",
|
||||||
am.Logger.Debug("found preferred certificate chain by root common name",
|
zap.String("preference", prefRootCN),
|
||||||
zap.String("preference", prefRootCN),
|
zap.Int("chain", i))
|
||||||
zap.Int("chain", i))
|
|
||||||
}
|
|
||||||
return certChains[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]
|
return certChains[0]
|
||||||
|
|
@ -509,6 +508,7 @@ type ChainPreference struct {
|
||||||
var DefaultACME = ACMEIssuer{
|
var DefaultACME = ACMEIssuer{
|
||||||
CA: LetsEncryptProductionCA,
|
CA: LetsEncryptProductionCA,
|
||||||
TestCA: LetsEncryptStagingCA,
|
TestCA: LetsEncryptStagingCA,
|
||||||
|
Logger: defaultLogger,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some well-known CA endpoints available to use.
|
// 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.queue = jm.queue[1:]
|
||||||
jm.mu.Unlock()
|
jm.mu.Unlock()
|
||||||
if err := next.job(); err != nil {
|
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 != "" {
|
if next.name != "" {
|
||||||
jm.mu.Lock()
|
jm.mu.Lock()
|
||||||
|
|
@ -116,22 +114,19 @@ func doWithRetry(ctx context.Context, log *zap.Logger, f func(context.Context) e
|
||||||
intervalIndex++
|
intervalIndex++
|
||||||
}
|
}
|
||||||
if time.Since(start) < maxRetryDuration {
|
if time.Since(start) < maxRetryDuration {
|
||||||
if log != nil {
|
log.Error("will retry",
|
||||||
log.Error("will retry",
|
zap.Error(err),
|
||||||
zap.Error(err),
|
zap.Int("attempt", attempts),
|
||||||
zap.Int("attempt", attempts),
|
zap.Duration("retrying_in", retryIntervals[intervalIndex]),
|
||||||
zap.Duration("retrying_in", retryIntervals[intervalIndex]),
|
zap.Duration("elapsed", time.Since(start)),
|
||||||
zap.Duration("elapsed", time.Since(start)),
|
zap.Duration("max_duration", maxRetryDuration))
|
||||||
zap.Duration("max_duration", maxRetryDuration))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if log != nil {
|
log.Error("final attempt; giving up",
|
||||||
log.Error("final attempt; giving up",
|
zap.Error(err),
|
||||||
zap.Error(err),
|
zap.Int("attempt", attempts),
|
||||||
zap.Int("attempt", attempts),
|
zap.Duration("elapsed", time.Since(start)),
|
||||||
zap.Duration("elapsed", time.Since(start)),
|
zap.Duration("max_duration", maxRetryDuration))
|
||||||
zap.Duration("max_duration", maxRetryDuration))
|
|
||||||
}
|
|
||||||
return nil
|
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,
|
logger: opts.Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// absolutely do not allow a nil logger; panics galore
|
||||||
|
if c.logger == nil {
|
||||||
|
c.logger = defaultLogger
|
||||||
|
}
|
||||||
|
|
||||||
go c.maintainAssets(0)
|
go c.maintainAssets(0)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
|
|
@ -194,14 +199,12 @@ func (certCache *Cache) cacheCertificate(cert Certificate) {
|
||||||
func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||||
// no-op if this certificate already exists in the cache
|
// no-op if this certificate already exists in the cache
|
||||||
if _, ok := certCache.cache[cert.hash]; ok {
|
if _, ok := certCache.cache[cert.hash]; ok {
|
||||||
if certCache.logger != nil {
|
certCache.logger.Debug("certificate already cached",
|
||||||
certCache.logger.Debug("certificate already cached",
|
zap.Strings("subjects", cert.Names),
|
||||||
zap.Strings("subjects", cert.Names),
|
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
zap.Bool("managed", cert.managed),
|
||||||
zap.Bool("managed", cert.managed),
|
zap.String("issuer_key", cert.issuerKey),
|
||||||
zap.String("issuer_key", cert.issuerKey),
|
zap.String("hash", cert.hash))
|
||||||
zap.String("hash", cert.hash))
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,13 +220,11 @@ func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||||
i := 0
|
i := 0
|
||||||
for _, randomCert := range certCache.cache {
|
for _, randomCert := range certCache.cache {
|
||||||
if i == rnd {
|
if i == rnd {
|
||||||
if certCache.logger != nil {
|
certCache.logger.Debug("cache full; evicting random certificate",
|
||||||
certCache.logger.Debug("cache full; evicting random certificate",
|
zap.Strings("removing_subjects", randomCert.Names),
|
||||||
zap.Strings("removing_subjects", randomCert.Names),
|
zap.String("removing_hash", randomCert.hash),
|
||||||
zap.String("removing_hash", randomCert.hash),
|
zap.Strings("inserting_subjects", cert.Names),
|
||||||
zap.Strings("inserting_subjects", cert.Names),
|
zap.String("inserting_hash", cert.hash))
|
||||||
zap.String("inserting_hash", cert.hash))
|
|
||||||
}
|
|
||||||
certCache.removeCertificate(randomCert)
|
certCache.removeCertificate(randomCert)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -239,16 +240,14 @@ func (certCache *Cache) unsyncedCacheCertificate(cert Certificate) {
|
||||||
certCache.cacheIndex[name] = append(certCache.cacheIndex[name], cert.hash)
|
certCache.cacheIndex[name] = append(certCache.cacheIndex[name], cert.hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
if certCache.logger != nil {
|
certCache.logger.Debug("added certificate to cache",
|
||||||
certCache.logger.Debug("added certificate to cache",
|
zap.Strings("subjects", cert.Names),
|
||||||
zap.Strings("subjects", cert.Names),
|
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
zap.Bool("managed", cert.managed),
|
||||||
zap.Bool("managed", cert.managed),
|
zap.String("issuer_key", cert.issuerKey),
|
||||||
zap.String("issuer_key", cert.issuerKey),
|
zap.String("hash", cert.hash),
|
||||||
zap.String("hash", cert.hash),
|
zap.Int("cache_size", len(certCache.cache)),
|
||||||
zap.Int("cache_size", len(certCache.cache)),
|
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeCertificate removes cert from the cache.
|
// removeCertificate removes cert from the cache.
|
||||||
|
|
@ -275,16 +274,14 @@ func (certCache *Cache) removeCertificate(cert Certificate) {
|
||||||
// delete the actual cert from the cache
|
// delete the actual cert from the cache
|
||||||
delete(certCache.cache, cert.hash)
|
delete(certCache.cache, cert.hash)
|
||||||
|
|
||||||
if certCache.logger != nil {
|
certCache.logger.Debug("removed certificate from cache",
|
||||||
certCache.logger.Debug("removed certificate from cache",
|
zap.Strings("subjects", cert.Names),
|
||||||
zap.Strings("subjects", cert.Names),
|
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
zap.Bool("managed", cert.managed),
|
||||||
zap.Bool("managed", cert.managed),
|
zap.String("issuer_key", cert.issuerKey),
|
||||||
zap.String("issuer_key", cert.issuerKey),
|
zap.String("hash", cert.hash),
|
||||||
zap.String("hash", cert.hash),
|
zap.Int("cache_size", len(certCache.cache)),
|
||||||
zap.Int("cache_size", len(certCache.cache)),
|
zap.Int("cache_capacity", certCache.options.Capacity))
|
||||||
zap.Int("cache_capacity", certCache.options.Capacity))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// replaceCertificate atomically replaces oldCert with newCert in
|
// replaceCertificate atomically replaces oldCert with newCert in
|
||||||
|
|
@ -296,11 +293,9 @@ func (certCache *Cache) replaceCertificate(oldCert, newCert Certificate) {
|
||||||
certCache.removeCertificate(oldCert)
|
certCache.removeCertificate(oldCert)
|
||||||
certCache.unsyncedCacheCertificate(newCert)
|
certCache.unsyncedCacheCertificate(newCert)
|
||||||
certCache.mu.Unlock()
|
certCache.mu.Unlock()
|
||||||
if certCache.logger != nil {
|
certCache.logger.Info("replaced certificate in cache",
|
||||||
certCache.logger.Info("replaced certificate in cache",
|
zap.Strings("subjects", newCert.Names),
|
||||||
zap.Strings("subjects", newCert.Names),
|
zap.Time("new_expiration", expiresAt(newCert.Leaf)))
|
||||||
zap.Time("new_expiration", newCert.Leaf.NotAfter))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (certCache *Cache) getAllMatchingCerts(name string) []Certificate {
|
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
|
// NeedsRenewal returns true if the certificate is
|
||||||
// expiring soon (according to cfg) or has expired.
|
// expiring soon (according to cfg) or has expired.
|
||||||
func (cert Certificate) NeedsRenewal(cfg *Config) bool {
|
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.
|
// Expired returns true if the certificate has expired.
|
||||||
|
|
@ -79,7 +79,7 @@ func (cert Certificate) Expired() bool {
|
||||||
// tls.X509KeyPair() discards the leaf; oh well
|
// tls.X509KeyPair() discards the leaf; oh well
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return time.Now().After(cert.Leaf.NotAfter)
|
return time.Now().After(expiresAt(cert.Leaf))
|
||||||
}
|
}
|
||||||
|
|
||||||
// currentlyInRenewalWindow returns true if the current time is
|
// currentlyInRenewalWindow returns true if the current time is
|
||||||
|
|
@ -109,6 +109,13 @@ func (cert Certificate) HasTag(tag string) bool {
|
||||||
return false
|
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
|
// CacheManagedCertificate loads the certificate for domain into the
|
||||||
// cache, from the TLS storage for managed certificates. It returns a
|
// cache, from the TLS storage for managed certificates. It returns a
|
||||||
// copy of the Certificate that was put into the cache.
|
// 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
|
return cert, err
|
||||||
}
|
}
|
||||||
cfg.certCache.cacheCertificate(cert)
|
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
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +162,7 @@ func (cfg *Config) CacheUnmanagedCertificatePEMFile(ctx context.Context, certFil
|
||||||
}
|
}
|
||||||
cert.Tags = tags
|
cert.Tags = tags
|
||||||
cfg.certCache.cacheCertificate(cert)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,10 +177,10 @@ func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tlsCert tls
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil)
|
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.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
|
cert.Tags = tags
|
||||||
cfg.certCache.cacheCertificate(cert)
|
cfg.certCache.cacheCertificate(cert)
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -190,7 +197,7 @@ func (cfg *Config) CacheUnmanagedCertificatePEMBytes(ctx context.Context, certBy
|
||||||
}
|
}
|
||||||
cert.Tags = tags
|
cert.Tags = tags
|
||||||
cfg.certCache.cacheCertificate(cert)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,7 +225,7 @@ func (cfg Config) makeCertificateWithOCSP(ctx context.Context, certPEMBlock, key
|
||||||
return cert, err
|
return cert, err
|
||||||
}
|
}
|
||||||
err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, certPEMBlock)
|
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))
|
cfg.Logger.Warn("stapling OCSP", zap.Error(err), zap.Strings("identifiers", cert.Names))
|
||||||
}
|
}
|
||||||
return cert, nil
|
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
|
// 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.
|
// already in storage. It returns the newly-loaded certificate if successful.
|
||||||
func (cfg *Config) reloadManagedCertificate(ctx context.Context, oldCert Certificate) (Certificate, error) {
|
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])
|
newCert, err := cfg.loadManagedCertificate(ctx, oldCert.Names[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Certificate{}, fmt.Errorf("loading managed certificate for %v from storage: %v", oldCert.Names, err)
|
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"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTPS serves mux for all domainNames using the HTTP
|
// HTTPS serves mux for all domainNames using the HTTP
|
||||||
|
|
@ -405,7 +409,7 @@ type IssuedCertificate struct {
|
||||||
|
|
||||||
// Any extra information to serialize alongside the
|
// Any extra information to serialize alongside the
|
||||||
// certificate in storage.
|
// certificate in storage.
|
||||||
Metadata interface{}
|
Metadata any
|
||||||
}
|
}
|
||||||
|
|
||||||
// CertificateResource associates a certificate with its private
|
// CertificateResource associates a certificate with its private
|
||||||
|
|
@ -425,7 +429,7 @@ type CertificateResource struct {
|
||||||
|
|
||||||
// Any extra information associated with the certificate,
|
// Any extra information associated with the certificate,
|
||||||
// usually provided by the issuer implementation.
|
// 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
|
// The unique string identifying the issuer of the
|
||||||
// certificate; internally useful for storage access.
|
// certificate; internally useful for storage access.
|
||||||
|
|
@ -468,8 +472,16 @@ var Default = Config{
|
||||||
RenewalWindowRatio: DefaultRenewalWindowRatio,
|
RenewalWindowRatio: DefaultRenewalWindowRatio,
|
||||||
Storage: defaultFileStorage,
|
Storage: defaultFileStorage,
|
||||||
KeySource: DefaultKeyGenerator,
|
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 (
|
const (
|
||||||
// HTTPChallengePort is the officially-designated port for
|
// HTTPChallengePort is the officially-designated port for
|
||||||
// the HTTP challenge according to the ACME spec.
|
// 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
|
// to subscribe to certain things happening
|
||||||
// internally by this config; invocations are
|
// internally by this config; invocations are
|
||||||
// synchronous, so make them return quickly!
|
// 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
|
// DefaultServerName specifies a server name
|
||||||
// to use when choosing a certificate if the
|
// to use when choosing a certificate if the
|
||||||
|
|
@ -110,7 +119,8 @@ type Config struct {
|
||||||
// TLS assets. Default is the local file system.
|
// TLS assets. Default is the local file system.
|
||||||
Storage Storage
|
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
|
Logger *zap.Logger
|
||||||
|
|
||||||
// required pointer to the in-memory cert cache
|
// required pointer to the in-memory cert cache
|
||||||
|
|
@ -196,6 +206,16 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||||
if cfg.OnDemand == nil {
|
if cfg.OnDemand == nil {
|
||||||
cfg.OnDemand = Default.OnDemand
|
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 {
|
if cfg.RenewalWindowRatio == 0 {
|
||||||
cfg.RenewalWindowRatio = Default.RenewalWindowRatio
|
cfg.RenewalWindowRatio = Default.RenewalWindowRatio
|
||||||
}
|
}
|
||||||
|
|
@ -208,18 +228,11 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||||
if cfg.DefaultServerName == "" {
|
if cfg.DefaultServerName == "" {
|
||||||
cfg.DefaultServerName = Default.DefaultServerName
|
cfg.DefaultServerName = Default.DefaultServerName
|
||||||
}
|
}
|
||||||
if !cfg.MustStaple {
|
|
||||||
cfg.MustStaple = Default.MustStaple
|
|
||||||
}
|
|
||||||
if cfg.Storage == nil {
|
if cfg.Storage == nil {
|
||||||
cfg.Storage = Default.Storage
|
cfg.Storage = Default.Storage
|
||||||
}
|
}
|
||||||
if len(cfg.Issuers) == 0 {
|
if cfg.Logger == nil {
|
||||||
cfg.Issuers = Default.Issuers
|
cfg.Logger = Default.Logger
|
||||||
if len(cfg.Issuers) == 0 {
|
|
||||||
// at least one issuer is absolutely required
|
|
||||||
cfg.Issuers = []Issuer{NewACMEIssuer(&cfg, DefaultACME)}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// absolutely don't allow a nil storage,
|
// absolutely don't allow a nil storage,
|
||||||
|
|
@ -229,6 +242,12 @@ func newWithCache(certCache *Cache, cfg Config) *Config {
|
||||||
cfg.Storage = defaultFileStorage
|
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
|
cfg.certCache = certCache
|
||||||
|
|
||||||
return &cfg
|
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)
|
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
|
// ensure idempotency of the obtain operation for this name
|
||||||
lockKey := cfg.lockKey(certIssueLockOp, 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)
|
return fmt.Errorf("unable to acquire lock '%s': %v", lockKey, err)
|
||||||
}
|
}
|
||||||
defer func() {
|
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 err := releaseLock(ctx, cfg.Storage, lockKey); err != nil {
|
||||||
if log != nil {
|
log.Error("unable to unlock",
|
||||||
log.Error("unable to unlock",
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.String("lock_key", lockKey),
|
||||||
zap.String("lock_key", lockKey),
|
zap.Error(err))
|
||||||
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 {
|
f := func(ctx context.Context) error {
|
||||||
// check if obtain is still needed -- might have been obtained during lock
|
// check if obtain is still needed -- might have been obtained during lock
|
||||||
if cfg.storageHasCertResourcesAnyIssuer(ctx, name) {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if storage has a private key already, use it; otherwise,
|
log.Info("obtaining certificate", zap.String("identifier", name))
|
||||||
// we'll generate our own
|
|
||||||
|
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)
|
privKey, privKeyPEM, issuers, err := cfg.reusePrivateKey(ctx, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
// try to obtain from each issuer until we succeed
|
||||||
var issuedCert *IssuedCertificate
|
var issuedCert *IssuedCertificate
|
||||||
var issuerUsed Issuer
|
var issuerUsed Issuer
|
||||||
|
var issuerKeys []string
|
||||||
for i, issuer := range issuers {
|
for i, issuer := range issuers {
|
||||||
if log != nil {
|
issuerKeys = append(issuerKeys, issuer.IssuerKey())
|
||||||
log.Debug(fmt.Sprintf("trying issuer %d/%d", i+1, len(cfg.Issuers)),
|
|
||||||
zap.String("issuer", 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 {
|
if prechecker, ok := issuer.(PreChecker); ok {
|
||||||
err = prechecker.PreCheck(ctx, []string{name}, interactive)
|
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) {
|
if errors.As(err, &problem) {
|
||||||
errToLog = problem
|
errToLog = problem
|
||||||
}
|
}
|
||||||
if log != nil {
|
log.Error("could not get certificate from issuer",
|
||||||
log.Error("could not get certificate from issuer",
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.String("issuer", issuer.IssuerKey()),
|
||||||
zap.String("issuer", issuer.IssuerKey()),
|
zap.Error(errToLog))
|
||||||
zap.Error(errToLog))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
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
|
// only the error from the last issuer will be returned, but we logged the others
|
||||||
return fmt.Errorf("[%s] Obtain: %w", name, err)
|
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)
|
return fmt.Errorf("[%s] Obtain: saving assets: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.emit("cert_obtained", CertificateEventData{
|
log.Info("certificate obtained successfully", zap.String("identifier", name))
|
||||||
Name: name,
|
|
||||||
IssuerKey: issuerUsed.IssuerKey(),
|
|
||||||
StorageKey: certRes.NamesKey(),
|
|
||||||
})
|
|
||||||
|
|
||||||
if log != nil {
|
cfg.emit(ctx, "cert_obtained", map[string]any{
|
||||||
log.Info("certificate obtained successfully", zap.String("identifier", name))
|
"renewal": false,
|
||||||
}
|
"identifier": name,
|
||||||
|
"issuers": issuerUsed.IssuerKey(),
|
||||||
|
"storage_key": certRes.NamesKey(),
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
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)
|
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
|
// ensure idempotency of the renew operation for this name
|
||||||
lockKey := cfg.lockKey(certIssueLockOp, 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)
|
return fmt.Errorf("unable to acquire lock '%s': %v", lockKey, err)
|
||||||
}
|
}
|
||||||
defer func() {
|
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 err := releaseLock(ctx, cfg.Storage, lockKey); err != nil {
|
||||||
if log != nil {
|
log.Error("unable to unlock",
|
||||||
log.Error("unable to unlock",
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.String("lock_key", lockKey),
|
||||||
zap.String("lock_key", lockKey),
|
zap.Error(err))
|
||||||
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 {
|
f := func(ctx context.Context) error {
|
||||||
// prepare for renewal (load PEM cert, key, and meta)
|
// 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)
|
timeLeft, needsRenew := cfg.managedCertNeedsRenewal(certRes)
|
||||||
if !needsRenew {
|
if !needsRenew {
|
||||||
if force {
|
if force {
|
||||||
if log != nil {
|
log.Info("certificate does not need to be renewed, but renewal is being forced",
|
||||||
log.Info("certificate does not need to be renewed, but renewal is being forced",
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.Duration("remaining", timeLeft))
|
||||||
zap.Duration("remaining", timeLeft))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if log != nil {
|
log.Info("certificate appears to have been renewed already",
|
||||||
log.Info("certificate appears to have been renewed already",
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.Duration("remaining", timeLeft))
|
||||||
zap.Duration("remaining", timeLeft))
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if log != nil {
|
log.Info("renewing certificate",
|
||||||
log.Info("renewing certificate",
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.Duration("remaining", timeLeft))
|
||||||
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)
|
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
|
// try to obtain from each issuer until we succeed
|
||||||
var issuedCert *IssuedCertificate
|
var issuedCert *IssuedCertificate
|
||||||
var issuerUsed Issuer
|
var issuerUsed Issuer
|
||||||
|
var issuerKeys []string
|
||||||
for _, issuer := range cfg.Issuers {
|
for _, issuer := range cfg.Issuers {
|
||||||
|
issuerKeys = append(issuerKeys, issuer.IssuerKey())
|
||||||
if prechecker, ok := issuer.(PreChecker); ok {
|
if prechecker, ok := issuer.(PreChecker); ok {
|
||||||
err = prechecker.PreCheck(ctx, []string{name}, interactive)
|
err = prechecker.PreCheck(ctx, []string{name}, interactive)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -769,14 +787,21 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
|
||||||
if errors.As(err, &problem) {
|
if errors.As(err, &problem) {
|
||||||
errToLog = problem
|
errToLog = problem
|
||||||
}
|
}
|
||||||
if log != nil {
|
log.Error("could not get certificate from issuer",
|
||||||
log.Error("could not get certificate from issuer",
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.String("issuer", issuer.IssuerKey()),
|
||||||
zap.String("issuer", issuer.IssuerKey()),
|
zap.Error(errToLog))
|
||||||
zap.Error(errToLog))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
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
|
// only the error from the last issuer will be returned, but we logged the others
|
||||||
return fmt.Errorf("[%s] Renew: %w", name, err)
|
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)
|
return fmt.Errorf("[%s] Renew: saving assets: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.emit("cert_renewed", CertificateEventData{
|
log.Info("certificate renewed successfully", zap.String("identifier", name))
|
||||||
Name: name,
|
|
||||||
IssuerKey: issuerUsed.IssuerKey(),
|
|
||||||
StorageKey: certRes.NamesKey(),
|
|
||||||
})
|
|
||||||
|
|
||||||
if log != nil {
|
cfg.emit(ctx, "cert_obtained", map[string]any{
|
||||||
log.Info("certificate renewed successfully", zap.String("identifier", name))
|
"renewal": true,
|
||||||
}
|
"remaining": timeLeft,
|
||||||
|
"identifier": name,
|
||||||
|
"issuer": issuerUsed.IssuerKey(),
|
||||||
|
"storage_key": certRes.NamesKey(),
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
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)
|
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)
|
err = cfg.deleteSiteAssets(ctx, issuerKey, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("certificate revoked, but unable to fully clean up assets from issuer %s: %v", issuerKey, err)
|
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() {
|
defer func() {
|
||||||
deleteErr := cfg.Storage.Delete(ctx, key)
|
deleteErr := cfg.Storage.Delete(ctx, key)
|
||||||
if deleteErr != nil {
|
if deleteErr != nil {
|
||||||
if cfg.Logger != nil {
|
cfg.Logger.Error("deleting test key from storage",
|
||||||
cfg.Logger.Error("deleting test key from storage",
|
zap.String("key", key), zap.Error(err))
|
||||||
zap.String("key", key), zap.Error(err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// if there was no other error, make sure
|
// if there was no other error, make sure
|
||||||
// to return any error returned from Delete
|
// to return any error returned from Delete
|
||||||
|
|
@ -1065,23 +1082,16 @@ func (cfg *Config) managedCertNeedsRenewal(certRes CertificateResource) (time.Du
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, true
|
return 0, true
|
||||||
}
|
}
|
||||||
remaining := time.Until(certChain[0].NotAfter)
|
remaining := time.Until(expiresAt(certChain[0]))
|
||||||
needsRenew := currentlyInRenewalWindow(certChain[0].NotBefore, certChain[0].NotAfter, cfg.RenewalWindowRatio)
|
needsRenew := currentlyInRenewalWindow(certChain[0].NotBefore, expiresAt(certChain[0]), cfg.RenewalWindowRatio)
|
||||||
return remaining, needsRenew
|
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 {
|
if cfg.OnEvent == nil {
|
||||||
return
|
|
||||||
}
|
|
||||||
cfg.OnEvent(eventName, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loggerNamed(l *zap.Logger, name string) *zap.Logger {
|
|
||||||
if l == nil {
|
|
||||||
return 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.
|
// 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
|
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
|
// certIssueLockOp is the name of the operation used
|
||||||
// when naming a lock to make it mutually exclusive
|
// when naming a lock to make it mutually exclusive
|
||||||
// with other certificate issuance operations for a
|
// 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)
|
return certResources[j].decoded.NotBefore.Before(certResources[i].decoded.NotBefore)
|
||||||
})
|
})
|
||||||
|
|
||||||
if cfg.Logger != nil {
|
cfg.Logger.Debug("loading managed certificate",
|
||||||
cfg.Logger.Debug("loading managed certificate",
|
zap.String("domain", certNamesKey),
|
||||||
zap.String("domain", certNamesKey),
|
zap.Time("expiration", expiresAt(certResources[0].decoded)),
|
||||||
zap.Time("expiration", certResources[0].decoded.NotAfter),
|
zap.String("issuer_key", certResources[0].issuer.IssuerKey()),
|
||||||
zap.String("issuer_key", certResources[0].issuer.IssuerKey()),
|
zap.Any("storage", cfg.Storage),
|
||||||
zap.Any("storage", cfg.Storage),
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return certResources[0].CertificateResource, nil
|
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.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
|
// if Present() succeeded, then it must show up eventually, or else
|
||||||
// something is really broken in the DNS provider or their API;
|
// something is really broken in the DNS provider or their API;
|
||||||
// no need for error here, simply have the caller try again
|
// 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))
|
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.
|
// until the lock can be obtained or an error is returned.
|
||||||
func (s *FileStorage) Lock(ctx context.Context, key string) error {
|
func (s *FileStorage) Lock(ctx context.Context, name string) error {
|
||||||
filename := s.lockFilename(key)
|
filename := s.lockFilename(name)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
err := createLockfile(filename)
|
err := createLockfile(filename)
|
||||||
|
|
@ -172,7 +172,13 @@ func (s *FileStorage) Lock(ctx context.Context, key string) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err2 := json.NewDecoder(f).Decode(&meta)
|
err2 := json.NewDecoder(f).Decode(&meta)
|
||||||
f.Close()
|
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)
|
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,
|
// or must give up on perfect mutual exclusivity; however, these cases are rare,
|
||||||
// so we prefer the simpler solution that avoids infinite loops)
|
// 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",
|
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 err = os.Remove(filename); err != nil { // hopefully we can replace the lock file quickly!
|
||||||
if !errors.Is(err, fs.ErrNotExist) {
|
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
|
continue
|
||||||
|
|
@ -215,16 +221,16 @@ func (s *FileStorage) Lock(ctx context.Context, key string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock releases the lock for name.
|
// Unlock releases the lock for name.
|
||||||
func (s *FileStorage) Unlock(_ context.Context, key string) error {
|
func (s *FileStorage) Unlock(_ context.Context, name string) error {
|
||||||
return os.Remove(s.lockFilename(key))
|
return os.Remove(s.lockFilename(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FileStorage) String() string {
|
func (s *FileStorage) String() string {
|
||||||
return "FileStorage:" + s.Path
|
return "FileStorage:" + s.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FileStorage) lockFilename(key string) string {
|
func (s *FileStorage) lockFilename(name string) string {
|
||||||
return filepath.Join(s.lockDir(), StorageKeys.Safe(key)+".lock")
|
return filepath.Join(s.lockDir(), StorageKeys.Safe(name)+".lock")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FileStorage) lockDir() string {
|
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.
|
// This method is safe for use as a tls.Config.GetCertificate callback.
|
||||||
func (cfg *Config) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
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
|
// special case: serve up the certificate for a TLS-ALPN ACME challenge
|
||||||
// (https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05)
|
// (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 {
|
if proto == acmez.ACMETLS1Protocol {
|
||||||
challengeCert, distributed, err := cfg.getTLSALPNChallengeCert(clientHello)
|
challengeCert, distributed, err := cfg.getTLSALPNChallengeCert(clientHello)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cfg.Logger != nil {
|
cfg.Logger.Error("tls-alpn challenge",
|
||||||
cfg.Logger.Error("tls-alpn challenge",
|
zap.String("server_name", clientHello.ServerName),
|
||||||
zap.String("server_name", clientHello.ServerName),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if cfg.Logger != nil {
|
cfg.Logger.Info("served key authentication certificate",
|
||||||
cfg.Logger.Info("served key authentication certificate",
|
zap.String("server_name", clientHello.ServerName),
|
||||||
zap.String("server_name", clientHello.ServerName),
|
zap.String("challenge", "tls-alpn-01"),
|
||||||
zap.String("challenge", "tls-alpn-01"),
|
zap.String("remote", clientHello.Conn.RemoteAddr().String()),
|
||||||
zap.String("remote", clientHello.Conn.RemoteAddr().String()),
|
zap.Bool("distributed", distributed))
|
||||||
zap.Bool("distributed", distributed))
|
|
||||||
}
|
|
||||||
return challengeCert, nil
|
return challengeCert, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the certificate and serve it up
|
// get the certificate and serve it up
|
||||||
cert, err := cfg.getCertDuringHandshake(clientHello, true, true)
|
cert, err := cfg.getCertDuringHandshake(ctx, clientHello, true, true)
|
||||||
if err == nil {
|
|
||||||
cfg.emit("tls_handshake_completed", clientHello)
|
|
||||||
}
|
|
||||||
return &cert.Certificate, err
|
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
|
// then all certificates in the cache will be passed in
|
||||||
// for the cfg.CertSelection to make the final decision.
|
// for the cfg.CertSelection to make the final decision.
|
||||||
func (cfg *Config) selectCert(hello *tls.ClientHelloInfo, name string) (Certificate, bool) {
|
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)
|
choices := cfg.certCache.getAllMatchingCerts(name)
|
||||||
|
|
||||||
if len(choices) == 0 {
|
if len(choices) == 0 {
|
||||||
if cfg.CertSelection == nil {
|
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
|
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()
|
choices = cfg.certCache.getAllCerts()
|
||||||
}
|
}
|
||||||
if logger != nil {
|
|
||||||
logger.Debug("choosing certificate",
|
logger.Debug("choosing certificate",
|
||||||
zap.String("identifier", name),
|
zap.String("identifier", name),
|
||||||
zap.Int("num_choices", len(choices)))
|
zap.Int("num_choices", len(choices)))
|
||||||
}
|
|
||||||
if cfg.CertSelection == nil {
|
if cfg.CertSelection == nil {
|
||||||
cert, err := DefaultCertificateSelector(hello, choices)
|
cert, err := DefaultCertificateSelector(hello, choices)
|
||||||
if logger != nil {
|
logger.Debug("default 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)
|
|
||||||
if logger != nil {
|
|
||||||
logger.Debug("custom certificate selection results",
|
|
||||||
zap.Error(err),
|
zap.Error(err),
|
||||||
zap.String("identifier", name),
|
zap.String("identifier", name),
|
||||||
zap.Strings("subjects", cert.Names),
|
zap.Strings("subjects", cert.Names),
|
||||||
zap.Bool("managed", cert.managed),
|
zap.Bool("managed", cert.managed),
|
||||||
zap.String("issuer_key", cert.issuerKey),
|
zap.String("issuer_key", cert.issuerKey),
|
||||||
zap.String("hash", cert.hash))
|
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
|
return cert, err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,7 +212,7 @@ func DefaultCertificateSelector(hello *tls.ClientHelloInfo, choices []Certificat
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
best = choice // at least the client supports it...
|
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!"
|
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.
|
// An error will be returned if and only if no certificate is available.
|
||||||
//
|
//
|
||||||
// This function is safe for concurrent use.
|
// This function is safe for concurrent use.
|
||||||
func (cfg *Config) getCertDuringHandshake(hello *tls.ClientHelloInfo, loadIfNecessary, obtainIfNecessary bool) (Certificate, error) {
|
func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.ClientHelloInfo, loadIfNecessary, obtainIfNecessary bool) (Certificate, error) {
|
||||||
log := loggerNamed(cfg.Logger, "handshake")
|
log := logWithRemote(cfg.Logger.Named("handshake"), hello)
|
||||||
|
|
||||||
ctx := context.TODO() // TODO: get a proper context? from somewhere...
|
|
||||||
|
|
||||||
// First check our in-memory cache to see if we've already loaded it
|
// First check our in-memory cache to see if we've already loaded it
|
||||||
cert, matched, defaulted := cfg.getCertificateFromCache(hello)
|
cert, matched, defaulted := cfg.getCertificateFromCache(hello)
|
||||||
if matched {
|
if matched {
|
||||||
if log != nil {
|
log.Debug("matched certificate in cache",
|
||||||
log.Debug("matched certificate in cache",
|
zap.Strings("subjects", cert.Names),
|
||||||
zap.Strings("subjects", cert.Names),
|
zap.Bool("managed", cert.managed),
|
||||||
zap.Bool("managed", cert.managed),
|
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
zap.String("hash", cert.hash))
|
||||||
zap.String("hash", cert.hash))
|
|
||||||
}
|
|
||||||
if cert.managed && cfg.OnDemand != nil && obtainIfNecessary {
|
if cert.managed && cfg.OnDemand != nil && obtainIfNecessary {
|
||||||
// On-demand certificates are maintained in the background, but
|
// On-demand certificates are maintained in the background, but
|
||||||
// maintenance is triggered by handshakes instead of by a timer
|
// maintenance is triggered by handshakes instead of by a timer
|
||||||
// as in maintain.go.
|
// 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
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
@ -302,20 +296,16 @@ func (cfg *Config) getCertDuringHandshake(hello *tls.ClientHelloInfo, loadIfNece
|
||||||
loadedCert, err = cfg.CacheManagedCertificate(ctx, strings.Join(labels, "."))
|
loadedCert, err = cfg.CacheManagedCertificate(ctx, strings.Join(labels, "."))
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if log != nil {
|
log.Debug("loaded certificate from storage",
|
||||||
log.Debug("loaded certificate from storage",
|
zap.Strings("subjects", loadedCert.Names),
|
||||||
zap.Strings("subjects", loadedCert.Names),
|
zap.Bool("managed", loadedCert.managed),
|
||||||
zap.Bool("managed", loadedCert.managed),
|
zap.Time("expiration", expiresAt(loadedCert.Leaf)),
|
||||||
zap.Time("expiration", loadedCert.Leaf.NotAfter),
|
zap.String("hash", loadedCert.hash))
|
||||||
zap.String("hash", loadedCert.hash))
|
|
||||||
}
|
|
||||||
loadedCert, err = cfg.handshakeMaintenance(ctx, hello, loadedCert)
|
loadedCert, err = cfg.handshakeMaintenance(ctx, hello, loadedCert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log != nil {
|
log.Error("maintaining newly-loaded certificate",
|
||||||
log.Error("maintaining newly-loaded certificate",
|
zap.String("server_name", name),
|
||||||
zap.String("server_name", name),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return loadedCert, nil
|
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
|
// Fall back to the default certificate if there is one
|
||||||
if defaulted {
|
if defaulted {
|
||||||
if log != nil {
|
log.Debug("fell back to default certificate",
|
||||||
log.Debug("fell back to default certificate",
|
zap.Strings("subjects", cert.Names),
|
||||||
zap.Strings("subjects", cert.Names),
|
zap.Bool("managed", cert.managed),
|
||||||
zap.Bool("managed", cert.managed),
|
zap.Time("expiration", expiresAt(cert.Leaf)),
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter),
|
zap.String("hash", cert.hash))
|
||||||
zap.String("hash", cert.hash))
|
|
||||||
}
|
|
||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if log != nil {
|
log.Debug("no certificate matching TLS ClientHello",
|
||||||
log.Debug("no certificate matching TLS ClientHello",
|
zap.String("server_name", hello.ServerName),
|
||||||
zap.String("server_name", hello.ServerName),
|
zap.String("remote", hello.Conn.RemoteAddr().String()),
|
||||||
zap.String("remote", hello.Conn.RemoteAddr().String()),
|
zap.String("identifier", name),
|
||||||
zap.String("identifier", name),
|
zap.Uint16s("cipher_suites", hello.CipherSuites),
|
||||||
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.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("load_if_necessary", loadIfNecessary),
|
zap.Bool("obtain_if_necessary", obtainIfNecessary),
|
||||||
zap.Bool("obtain_if_necessary", obtainIfNecessary),
|
zap.Bool("on_demand", cfg.OnDemand != nil))
|
||||||
zap.Bool("on_demand", cfg.OnDemand != nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
return Certificate{}, fmt.Errorf("no certificate available for '%s'", name)
|
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
|
return newCert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if log != nil {
|
log.Error("renewing certificate on-demand failed",
|
||||||
log.Error("renewing certificate on-demand failed",
|
zap.Strings("subjects", cert.Names),
|
||||||
zap.Strings("subjects", cert.Names),
|
zap.Time("not_after", expiresAt(cert.Leaf)),
|
||||||
zap.Time("not_after", cert.Leaf.NotAfter),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
if cert.Expired() {
|
if cert.Expired() {
|
||||||
return cert, err
|
return cert, err
|
||||||
|
|
@ -402,13 +386,13 @@ func (cfg *Config) checkIfCertShouldBeObtained(name string) error {
|
||||||
//
|
//
|
||||||
// This function is safe for use by multiple concurrent goroutines.
|
// This function is safe for use by multiple concurrent goroutines.
|
||||||
func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.ClientHelloInfo) (Certificate, error) {
|
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)
|
name := cfg.getNameFromClientHello(hello)
|
||||||
|
|
||||||
getCertWithoutReobtaining := func() (Certificate, error) {
|
getCertWithoutReobtaining := func() (Certificate, error) {
|
||||||
// very important to set the obtainIfNecessary argument to false, so we don't repeat this infinitely
|
// 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.
|
// 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
|
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...
|
// 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)
|
// (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.
|
// This function is safe for use by multiple concurrent goroutines.
|
||||||
func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHelloInfo, cert Certificate) (Certificate, error) {
|
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
|
// Check OCSP staple validity
|
||||||
if cert.ocsp != nil && !freshOCSP(cert.ocsp) {
|
if cert.ocsp != nil && !freshOCSP(cert.ocsp) {
|
||||||
if log != nil {
|
log.Debug("OCSP response needs refreshing",
|
||||||
log.Debug("OCSP response needs refreshing",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
|
||||||
}
|
|
||||||
|
|
||||||
err := stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil)
|
err := stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// An error with OCSP stapling is not the end of the world, and in fact, is
|
// 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.
|
// quite common considering not all certs have issuer URLs that support it.
|
||||||
if log != nil {
|
log.Warn("stapling OCSP",
|
||||||
log.Warn("stapling OCSP",
|
zap.String("server_name", hello.ServerName),
|
||||||
zap.String("server_name", hello.ServerName),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
} else {
|
||||||
}
|
log.Debug("successfully stapled new OCSP response",
|
||||||
} else if log != nil {
|
zap.Strings("identifiers", cert.Names),
|
||||||
if log != nil {
|
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||||
log.Debug("successfully stapled new OCSP response",
|
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||||
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
|
// 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.
|
// We attempt to replace any certificates that were revoked.
|
||||||
// Crucially, this happens OUTSIDE a lock on the certCache.
|
// Crucially, this happens OUTSIDE a lock on the certCache.
|
||||||
if certShouldBeForceRenewed(cert) {
|
if certShouldBeForceRenewed(cert) {
|
||||||
if log != nil {
|
log.Warn("on-demand certificate's OCSP status is REVOKED; will try to forcefully renew",
|
||||||
log.Warn("on-demand certificate's OCSP status is REVOKED; will try to forcefully renew",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Int("ocsp_status", cert.ocsp.Status),
|
||||||
zap.Int("ocsp_status", cert.ocsp.Status),
|
zap.Time("revoked_at", cert.ocsp.RevokedAt),
|
||||||
zap.Time("revoked_at", cert.ocsp.RevokedAt),
|
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
||||||
zap.Time("this_update", cert.ocsp.ThisUpdate),
|
zap.Time("next_update", cert.ocsp.NextUpdate))
|
||||||
zap.Time("next_update", cert.ocsp.NextUpdate))
|
|
||||||
}
|
|
||||||
return cfg.renewDynamicCertificate(ctx, hello, cert)
|
return cfg.renewDynamicCertificate(ctx, hello, cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check cert expiration
|
// 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)
|
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.
|
// This function is safe for use by multiple concurrent goroutines.
|
||||||
func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.ClientHelloInfo, currentCert Certificate) (Certificate, error) {
|
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)
|
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
|
revoked := currentCert.ocsp != nil && currentCert.ocsp.Status == ocsp.Revoked
|
||||||
|
|
||||||
getCertWithoutReobtaining := func() (Certificate, error) {
|
getCertWithoutReobtaining := func() (Certificate, error) {
|
||||||
// very important to set the obtainIfNecessary argument to false, so we don't repeat this infinitely
|
// 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
|
// 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
|
// 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
|
// we're forcing renewal, in which case the current certificate is not usable
|
||||||
if timeLeft > 0 && !revoked {
|
if timeLeft > 0 && !revoked {
|
||||||
if log != nil {
|
log.Debug("certificate expires soon but is already being renewed; serving current certificate",
|
||||||
log.Debug("certificate expires soon but is already being renewed; serving current certificate",
|
zap.Strings("subjects", currentCert.Names),
|
||||||
zap.Strings("subjects", currentCert.Names),
|
zap.Duration("remaining", timeLeft))
|
||||||
zap.Duration("remaining", timeLeft))
|
|
||||||
}
|
|
||||||
return currentCert, nil
|
return currentCert, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, we'll have to wait for the renewal to finish so we don't serve
|
// otherwise, we'll have to wait for the renewal to finish so we don't serve
|
||||||
// a revoked or expired certificate
|
// a revoked or expired certificate
|
||||||
|
|
||||||
if log != nil {
|
log.Debug("certificate has expired, but is already being renewed; waiting for renewal to complete",
|
||||||
log.Debug("certificate has expired, but is already being renewed; waiting for renewal to complete",
|
zap.Strings("subjects", currentCert.Names),
|
||||||
zap.Strings("subjects", currentCert.Names),
|
zap.Time("expired", expiresAt(currentCert.Leaf)),
|
||||||
zap.Time("expired", currentCert.Leaf.NotAfter),
|
zap.Bool("revoked", revoked))
|
||||||
zap.Bool("revoked", revoked))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: see if we can get a proper context in here, for true cancellation
|
// TODO: see if we can get a proper context in here, for true cancellation
|
||||||
timeout := time.NewTimer(2 * time.Minute)
|
timeout := time.NewTimer(2 * time.Minute)
|
||||||
|
|
@ -620,30 +590,36 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
|
||||||
obtainCertWaitChansMu.Unlock()
|
obtainCertWaitChansMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
if log != nil {
|
log = log.With(
|
||||||
log.Info("attempting certificate renewal",
|
zap.String("server_name", name),
|
||||||
zap.String("server_name", name),
|
zap.Strings("subjects", currentCert.Names),
|
||||||
zap.Strings("subjects", currentCert.Names),
|
zap.Time("expiration", expiresAt(currentCert.Leaf)),
|
||||||
zap.Time("expiration", currentCert.Leaf.NotAfter),
|
zap.Duration("remaining", timeLeft),
|
||||||
zap.Duration("remaining", timeLeft),
|
zap.Bool("revoked", revoked),
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Renew and reload the certificate
|
// Renew and reload the certificate
|
||||||
renewAndReload := func(ctx context.Context, cancel context.CancelFunc) (Certificate, error) {
|
renewAndReload := func(ctx context.Context, cancel context.CancelFunc) (Certificate, error) {
|
||||||
defer cancel()
|
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.
|
// otherwise, renew with issuer, etc.
|
||||||
var newCert Certificate
|
var newCert Certificate
|
||||||
if revoked {
|
if revoked {
|
||||||
|
|
@ -656,9 +632,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
|
||||||
// make the replacement as atomic as possible.
|
// make the replacement as atomic as possible.
|
||||||
newCert, err = cfg.CacheManagedCertificate(ctx, name)
|
newCert, err = cfg.CacheManagedCertificate(ctx, name)
|
||||||
if err != nil {
|
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 {
|
} else {
|
||||||
// replace the old certificate with the new one
|
// replace the old certificate with the new one
|
||||||
cfg.certCache.replaceCertificate(currentCert, newCert)
|
cfg.certCache.replaceCertificate(currentCert, newCert)
|
||||||
|
|
@ -672,12 +646,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
|
||||||
unblockWaiters()
|
unblockWaiters()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log != nil {
|
log.Error("renewing and reloading certificate", zap.Error(err))
|
||||||
log.Error("renewing and reloading certificate",
|
|
||||||
zap.String("server_name", name),
|
|
||||||
zap.Error(err),
|
|
||||||
zap.Bool("forced", revoked))
|
|
||||||
}
|
|
||||||
return newCert, err
|
return newCert, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -723,9 +692,7 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if upstreamCert == nil {
|
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
|
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)
|
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",
|
||||||
log.Debug("using externally-managed certificate",
|
zap.String("sni", hello.ServerName),
|
||||||
zap.String("sni", hello.ServerName),
|
zap.Strings("names", cert.Names),
|
||||||
zap.Strings("names", cert.Names),
|
zap.Time("expiration", expiresAt(cert.Leaf)))
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter))
|
|
||||||
}
|
|
||||||
|
|
||||||
return cert, nil
|
return cert, nil
|
||||||
}
|
}
|
||||||
|
|
@ -785,6 +750,20 @@ func (*Config) getNameFromClientHello(hello *tls.ClientHelloInfo) string {
|
||||||
return localIPFromConn(hello.Conn)
|
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
|
// localIPFromConn returns the host portion of c's local address
|
||||||
// and strips the scope ID if one exists (see RFC 4007).
|
// and strips the scope ID if one exists (see RFC 4007).
|
||||||
func localIPFromConn(c net.Conn) string {
|
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)
|
host := hostOnly(r.Host)
|
||||||
chalInfo, distributed, err := am.config.getChallengeInfo(r.Context(), host)
|
chalInfo, distributed, err := am.config.getChallengeInfo(r.Context(), host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if am.Logger != nil {
|
am.Logger.Error("looking up info for HTTP challenge",
|
||||||
am.Logger.Error("looking up info for HTTP challenge",
|
zap.String("host", host),
|
||||||
zap.String("host", host),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return solveHTTPChallenge(am.Logger, w, r, chalInfo.Challenge, distributed)
|
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.Header().Add("Content-Type", "text/plain")
|
||||||
w.Write([]byte(challenge.KeyAuthorization))
|
w.Write([]byte(challenge.KeyAuthorization))
|
||||||
r.Close = true
|
r.Close = true
|
||||||
if logger != nil {
|
logger.Info("served key authentication",
|
||||||
logger.Info("served key authentication",
|
zap.String("identifier", challenge.Identifier.Value),
|
||||||
zap.String("identifier", challenge.Identifier.Value),
|
zap.String("challenge", "http-01"),
|
||||||
zap.String("challenge", "http-01"),
|
zap.String("remote", r.RemoteAddr),
|
||||||
zap.String("remote", r.RemoteAddr),
|
zap.Bool("distributed", distributed))
|
||||||
zap.Bool("distributed", distributed))
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
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
|
// incrementing panicCount each time. Initial invocation should
|
||||||
// start panicCount at 0.
|
// start panicCount at 0.
|
||||||
func (certCache *Cache) maintainAssets(panicCount int) {
|
func (certCache *Cache) maintainAssets(panicCount int) {
|
||||||
log := loggerNamed(certCache.logger, "maintenance")
|
log := certCache.logger.Named("maintenance")
|
||||||
if log != nil {
|
log = log.With(zap.String("cache", fmt.Sprintf("%p", certCache)))
|
||||||
log = log.With(zap.String("cache", fmt.Sprintf("%p", certCache)))
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
buf := make([]byte, stackTraceBufferSize)
|
buf := make([]byte, stackTraceBufferSize)
|
||||||
buf = buf[:runtime.Stack(buf, false)]
|
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 {
|
if panicCount < 10 {
|
||||||
certCache.maintainAssets(panicCount + 1)
|
certCache.maintainAssets(panicCount + 1)
|
||||||
}
|
}
|
||||||
|
|
@ -60,9 +56,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||||
renewalTicker := time.NewTicker(certCache.options.RenewCheckInterval)
|
renewalTicker := time.NewTicker(certCache.options.RenewCheckInterval)
|
||||||
ocspTicker := time.NewTicker(certCache.options.OCSPCheckInterval)
|
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())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
@ -71,7 +65,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||||
select {
|
select {
|
||||||
case <-renewalTicker.C:
|
case <-renewalTicker.C:
|
||||||
err := certCache.RenewManagedCertificates(ctx)
|
err := certCache.RenewManagedCertificates(ctx)
|
||||||
if err != nil && log != nil {
|
if err != nil {
|
||||||
log.Error("renewing managed certificates", zap.Error(err))
|
log.Error("renewing managed certificates", zap.Error(err))
|
||||||
}
|
}
|
||||||
case <-ocspTicker.C:
|
case <-ocspTicker.C:
|
||||||
|
|
@ -79,9 +73,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||||
case <-certCache.stopChan:
|
case <-certCache.stopChan:
|
||||||
renewalTicker.Stop()
|
renewalTicker.Stop()
|
||||||
ocspTicker.Stop()
|
ocspTicker.Stop()
|
||||||
if log != nil {
|
log.Info("stopped background certificate maintenance")
|
||||||
log.Info("stopped background certificate maintenance")
|
|
||||||
}
|
|
||||||
close(certCache.doneChan)
|
close(certCache.doneChan)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +86,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
|
||||||
// need to call this. This method assumes non-interactive
|
// need to call this. This method assumes non-interactive
|
||||||
// mode (i.e. operating in the background).
|
// mode (i.e. operating in the background).
|
||||||
func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
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
|
// configs will hold a map of certificate name to the config
|
||||||
// to use when managing that certificate
|
// 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?
|
// the list of names on this cert should never be empty... programmer error?
|
||||||
if cert.Names == nil || len(cert.Names) == 0 {
|
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)
|
deleteQueue = append(deleteQueue, cert)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -126,19 +116,15 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||||
// get the config associated with this certificate
|
// get the config associated with this certificate
|
||||||
cfg, err := certCache.getConfig(cert)
|
cfg, err := certCache.getConfig(cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log != nil {
|
log.Error("unable to get configuration to manage certificate; unable to renew",
|
||||||
log.Error("unable to get configuration to manage certificate; unable to renew",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
// this is bad if this happens, probably a programmer error (oops)
|
// this is bad if this happens, probably a programmer error (oops)
|
||||||
if log != nil {
|
log.Error("no configuration associated with certificate; unable to manage",
|
||||||
log.Error("no configuration associated with certificate; unable to manage",
|
zap.Strings("identifiers", cert.Names))
|
||||||
zap.Strings("identifiers", cert.Names))
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if cfg.OnDemand != nil {
|
if cfg.OnDemand != nil {
|
||||||
|
|
@ -156,11 +142,9 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||||
storedCertExpiring, err := cfg.managedCertInStorageExpiresSoon(ctx, cert)
|
storedCertExpiring, err := cfg.managedCertInStorageExpiresSoon(ctx, cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// hmm, weird, but not a big deal, maybe it was deleted or something
|
// 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",
|
||||||
log.Warn("error while checking if stored certificate is also expiring soon",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
} else if !storedCertExpiring {
|
} else if !storedCertExpiring {
|
||||||
// if the certificate is NOT expiring soon and there was no error, then we
|
// 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
|
// 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
|
// Reload certificates that merely need to be updated in memory
|
||||||
for _, oldCert := range reloadQueue {
|
for _, oldCert := range reloadQueue {
|
||||||
timeLeft := oldCert.Leaf.NotAfter.Sub(time.Now().UTC())
|
timeLeft := expiresAt(oldCert.Leaf).Sub(time.Now().UTC())
|
||||||
if log != nil {
|
log.Info("certificate expires soon, but is already renewed in storage; reloading stored certificate",
|
||||||
log.Info("certificate expires soon, but is already renewed in storage; reloading stored certificate",
|
zap.Strings("identifiers", oldCert.Names),
|
||||||
zap.Strings("identifiers", oldCert.Names),
|
zap.Duration("remaining", timeLeft))
|
||||||
zap.Duration("remaining", timeLeft))
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := configs[oldCert.Names[0]]
|
cfg := configs[oldCert.Names[0]]
|
||||||
|
|
||||||
// crucially, this happens OUTSIDE a lock on the certCache
|
// crucially, this happens OUTSIDE a lock on the certCache
|
||||||
_, err := cfg.reloadManagedCertificate(ctx, oldCert)
|
_, err := cfg.reloadManagedCertificate(ctx, oldCert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log != nil {
|
log.Error("loading renewed certificate",
|
||||||
log.Error("loading renewed certificate",
|
zap.Strings("identifiers", oldCert.Names),
|
||||||
zap.Strings("identifiers", oldCert.Names),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -206,11 +186,9 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
|
||||||
cfg := configs[oldCert.Names[0]]
|
cfg := configs[oldCert.Names[0]]
|
||||||
err := certCache.queueRenewalTask(ctx, oldCert, cfg)
|
err := certCache.queueRenewalTask(ctx, oldCert, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if log != nil {
|
log.Error("queueing renewal task",
|
||||||
log.Error("queueing renewal task",
|
zap.Strings("identifiers", oldCert.Names),
|
||||||
zap.Strings("identifiers", oldCert.Names),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
continue
|
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 {
|
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())
|
timeLeft := expiresAt(oldCert.Leaf).Sub(time.Now().UTC())
|
||||||
if log != nil {
|
log.Info("certificate expires soon; queuing for renewal",
|
||||||
log.Info("certificate expires soon; queuing for renewal",
|
zap.Strings("identifiers", oldCert.Names),
|
||||||
zap.Strings("identifiers", oldCert.Names),
|
zap.Duration("remaining", timeLeft))
|
||||||
zap.Duration("remaining", timeLeft))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the name which we should use to renew this certificate;
|
// Get the name which we should use to renew this certificate;
|
||||||
// we only support managing certificates with one name per cert,
|
// 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)
|
// queue up this renewal job (is a no-op if already active or queued)
|
||||||
jm.Submit(cfg.Logger, "renew_"+renewName, func() error {
|
jm.Submit(cfg.Logger, "renew_"+renewName, func() error {
|
||||||
timeLeft := oldCert.Leaf.NotAfter.Sub(time.Now().UTC())
|
timeLeft := expiresAt(oldCert.Leaf).Sub(time.Now().UTC())
|
||||||
if log != nil {
|
log.Info("attempting certificate renewal",
|
||||||
log.Info("attempting certificate renewal",
|
zap.Strings("identifiers", oldCert.Names),
|
||||||
zap.Strings("identifiers", oldCert.Names),
|
zap.Duration("remaining", timeLeft))
|
||||||
zap.Duration("remaining", timeLeft))
|
|
||||||
}
|
|
||||||
|
|
||||||
// perform renewal - crucially, this happens OUTSIDE a lock on certCache
|
// perform renewal - crucially, this happens OUTSIDE a lock on certCache
|
||||||
err := cfg.RenewCertAsync(ctx, renewName, false)
|
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:
|
// Ryan Sleevi's recommendations for good OCSP support:
|
||||||
// https://gist.github.com/sleevi/5efe9ef98961ecfb4da8
|
// https://gist.github.com/sleevi/5efe9ef98961ecfb4da8
|
||||||
func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||||
logger := loggerNamed(certCache.logger, "maintenance")
|
logger := certCache.logger.Named("maintenance")
|
||||||
|
|
||||||
// temporary structures to store updates or tasks
|
// temporary structures to store updates or tasks
|
||||||
// so that we can keep our locks short-lived
|
// 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)
|
cfg, err := certCache.getConfig(cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if logger != nil {
|
logger.Error("unable to get automation config for certificate; maintenance for this certificate will likely fail",
|
||||||
logger.Error("unable to get automation config for certificate; maintenance for this certificate will likely fail",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// always try to replace revoked certificates, even if OCSP response is still fresh
|
// 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 {
|
if qe.cfg == nil {
|
||||||
// this is bad if this happens, probably a programmer error (oops)
|
// 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",
|
||||||
logger.Error("no configuration associated with certificate; unable to manage OCSP staples",
|
zap.Strings("identifiers", cert.Names))
|
||||||
zap.Strings("identifiers", cert.Names))
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,11 +328,9 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cert.ocsp != nil {
|
if cert.ocsp != nil {
|
||||||
// if there was no staple before, that's fine; otherwise we should log the error
|
// if there was no staple before, that's fine; otherwise we should log the error
|
||||||
if logger != nil {
|
logger.Error("stapling OCSP",
|
||||||
logger.Error("stapling OCSP",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -372,17 +340,22 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||||
// sure we apply the update to all names on the certificate if
|
// sure we apply the update to all names on the certificate if
|
||||||
// the status is still Good.
|
// the status is still Good.
|
||||||
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Good && (lastNextUpdate.IsZero() || lastNextUpdate != cert.ocsp.NextUpdate) {
|
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Good && (lastNextUpdate.IsZero() || lastNextUpdate != cert.ocsp.NextUpdate) {
|
||||||
if logger != nil {
|
logger.Info("advancing OCSP staple",
|
||||||
logger.Info("advancing OCSP staple",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Time("from", lastNextUpdate),
|
||||||
zap.Time("from", lastNextUpdate),
|
zap.Time("to", cert.ocsp.NextUpdate))
|
||||||
zap.Time("to", cert.ocsp.NextUpdate))
|
|
||||||
}
|
|
||||||
updated[certHash] = ocspUpdate{rawBytes: cert.Certificate.OCSPStaple, parsed: cert.ocsp}
|
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 the updated staple shows that the certificate was revoked, we should immediately renew it
|
||||||
if certShouldBeForceRenewed(cert) {
|
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{
|
renewQueue = append(renewQueue, renewQueueEntry{
|
||||||
oldCert: cert,
|
oldCert: cert,
|
||||||
cfg: qe.cfg,
|
cfg: qe.cfg,
|
||||||
|
|
@ -405,7 +378,7 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
|
||||||
// Crucially, this happens OUTSIDE a lock on the certCache.
|
// Crucially, this happens OUTSIDE a lock on the certCache.
|
||||||
for _, renew := range renewQueue {
|
for _, renew := range renewQueue {
|
||||||
_, err := renew.cfg.forceRenew(ctx, logger, renew.oldCert)
|
_, 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",
|
logger.Info("forcefully renewing certificate due to REVOKED status",
|
||||||
zap.Strings("identifiers", renew.oldCert.Names),
|
zap.Strings("identifiers", renew.oldCert.Names),
|
||||||
zap.Error(err))
|
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)
|
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)
|
log.Printf("[INFO] Certificate %s expired %s ago; cleaning up", assetKey, expiredTime)
|
||||||
baseName := strings.TrimSuffix(assetKey, ".crt")
|
baseName := strings.TrimSuffix(assetKey, ".crt")
|
||||||
for _, relatedAsset := range []string{
|
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
|
// 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.
|
// 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) {
|
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 {
|
||||||
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Revoked {
|
logger.Warn("OCSP status for managed certificate is REVOKED; attempting to replace with new certificate",
|
||||||
logger.Warn("OCSP status for managed certificate is REVOKED; attempting to replace with new certificate",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Time("expiration", expiresAt(cert.Leaf)))
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter))
|
} else {
|
||||||
} else {
|
logger.Warn("forcefully renewing certificate",
|
||||||
logger.Warn("forcefully renewing certificate",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Time("expiration", expiresAt(cert.Leaf)))
|
||||||
zap.Time("expiration", cert.Leaf.NotAfter))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renewName := cert.Names[0]
|
renewName := cert.Names[0]
|
||||||
|
|
@ -584,7 +555,7 @@ func (cfg *Config) forceRenew(ctx context.Context, logger *zap.Logger, cert Cert
|
||||||
var obtainInsteadOfRenew bool
|
var obtainInsteadOfRenew bool
|
||||||
if cert.ocsp != nil && cert.ocsp.RevocationReason == acme.ReasonKeyCompromise {
|
if cert.ocsp != nil && cert.ocsp.RevocationReason == acme.ReasonKeyCompromise {
|
||||||
err := cfg.moveCompromisedPrivateKey(ctx, cert, logger)
|
err := cfg.moveCompromisedPrivateKey(ctx, cert, logger)
|
||||||
if err != nil && logger != nil {
|
if err != nil {
|
||||||
logger.Error("could not remove compromised private key from use",
|
logger.Error("could not remove compromised private key from use",
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.String("issuer", cert.issuerKey),
|
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 err != nil {
|
||||||
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Revoked {
|
if cert.ocsp != nil && cert.ocsp.Status == ocsp.Revoked {
|
||||||
// probably better to not serve a revoked certificate at all
|
// 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",
|
||||||
logger.Error("unable to obtain new to certificate after OCSP status of REVOKED; removing from cache",
|
zap.Strings("identifiers", cert.Names),
|
||||||
zap.Strings("identifiers", cert.Names),
|
zap.Error(err))
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
cfg.certCache.mu.Lock()
|
cfg.certCache.mu.Lock()
|
||||||
cfg.certCache.removeCertificate(cert)
|
cfg.certCache.removeCertificate(cert)
|
||||||
cfg.certCache.mu.Unlock()
|
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
|
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.
|
// 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
|
// it was the reason a lot of Symantec-validated sites (not Caddy) went down
|
||||||
// in October 2017. https://twitter.com/mattiasgeniar/status/919432824708648961
|
// in October 2017. https://twitter.com/mattiasgeniar/status/919432824708648961
|
||||||
return fmt.Errorf("invalid: OCSP response for %v valid after certificate expiration (%s)",
|
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
|
// 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.
|
// 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()
|
solversMu.Lock()
|
||||||
defer solversMu.Unlock()
|
defer solversMu.Unlock()
|
||||||
si := getSolverInfo(s.address)
|
si := getSolverInfo(s.address)
|
||||||
|
|
@ -220,7 +220,7 @@ func (*tlsALPNSolver) handleConn(conn net.Conn) {
|
||||||
|
|
||||||
// CleanUp removes the challenge certificate from the cache, and if
|
// CleanUp removes the challenge certificate from the cache, and if
|
||||||
// it is the last one to finish, stops the TLS server.
|
// 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()
|
solversMu.Lock()
|
||||||
defer solversMu.Unlock()
|
defer solversMu.Unlock()
|
||||||
si := getSolverInfo(s.address)
|
si := getSolverInfo(s.address)
|
||||||
|
|
@ -234,7 +234,6 @@ func (s *tlsALPNSolver) CleanUp(ctx context.Context, chal acme.Challenge) error
|
||||||
}
|
}
|
||||||
delete(solvers, s.address)
|
delete(solvers, s.address)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -357,7 +356,7 @@ func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error
|
||||||
// timings
|
// timings
|
||||||
timeout := s.PropagationTimeout
|
timeout := s.PropagationTimeout
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
timeout = 2 * time.Minute
|
timeout = defaultDNSPropagationTimeout
|
||||||
}
|
}
|
||||||
const interval = 2 * time.Second
|
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().
|
// 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()
|
dnsName := challenge.DNS01TXTRecordName()
|
||||||
if s.OverrideDomain != "" {
|
if s.OverrideDomain != "" {
|
||||||
dnsName = s.OverrideDomain
|
dnsName = s.OverrideDomain
|
||||||
|
|
@ -402,7 +406,17 @@ func (s *DNS01Solver) CleanUp(ctx context.Context, challenge acme.Challenge) err
|
||||||
return 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})
|
_, err = s.DNSProvider.DeleteRecords(ctx, memory.dnsZone, []libdns.Record{memory.rec})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("deleting temporary record for name %q in zone %q: %w", memory.dnsName, memory.dnsZone, err)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultDNSPropagationTimeout = 2 * time.Minute
|
||||||
|
|
||||||
type dnsPresentMemory struct {
|
type dnsPresentMemory struct {
|
||||||
dnsZone string
|
dnsZone string
|
||||||
dnsName string
|
dnsName string
|
||||||
|
|
@ -680,7 +696,7 @@ var (
|
||||||
// data that can make it easier or more efficient to solve.
|
// data that can make it easier or more efficient to solve.
|
||||||
type Challenge struct {
|
type Challenge struct {
|
||||||
acme.Challenge
|
acme.Challenge
|
||||||
data interface{}
|
data any
|
||||||
}
|
}
|
||||||
|
|
||||||
// challengeKey returns the map key for a given challenge; it is the identifier
|
// 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
|
// Keys are prefix-based, with forward slash '/' as separators
|
||||||
// and without a leading slash.
|
// and without a leading slash.
|
||||||
//
|
//
|
||||||
// Processes running in a cluster will wish to use the
|
// Processes running in a cluster should use the same Storage
|
||||||
// same Storage value (its implementation and configuration)
|
// value (with the same configuration) in order to share
|
||||||
// in order to share certificates and other TLS resources
|
// certificates and other TLS resources with the cluster.
|
||||||
// with the cluster.
|
|
||||||
//
|
//
|
||||||
// The Load, Delete, List, and Stat methods should return
|
// The Load, Delete, List, and Stat methods should return
|
||||||
// fs.ErrNotExist if the key does not exist.
|
// fs.ErrNotExist if the key does not exist.
|
||||||
//
|
//
|
||||||
// Implementations of Storage must be safe for concurrent use
|
// 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 {
|
type Storage interface {
|
||||||
// Locker provides atomic synchronization
|
// Locker provides atomic synchronization
|
||||||
// operations, making Storage safe to share.
|
// 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
|
Locker
|
||||||
|
|
||||||
// Store puts value at key.
|
// Store puts value at key.
|
||||||
|
|
@ -70,10 +81,11 @@ type Storage interface {
|
||||||
Stat(ctx context.Context, key string) (KeyInfo, error)
|
Stat(ctx context.Context, key string) (KeyInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locker facilitates synchronization of certificate tasks across
|
// Locker facilitates synchronization across machines and networks.
|
||||||
// machines and networks.
|
// It essentially provides a distributed named-mutex service so
|
||||||
|
// that multiple consumers can coordinate tasks and share resources.
|
||||||
type Locker interface {
|
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
|
// can be obtained or an error is returned. Note that, even
|
||||||
// after acquiring a lock, an idempotent operation may have
|
// after acquiring a lock, an idempotent operation may have
|
||||||
// already been performed by another process that acquired
|
// 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
|
// same time always results in only one caller receiving the
|
||||||
// lock at any given time.
|
// lock at any given time.
|
||||||
//
|
//
|
||||||
// To prevent deadlocks, all implementations (where this concern
|
// To prevent deadlocks, all implementations should put a
|
||||||
// is relevant) should put a reasonable expiration on the lock in
|
// reasonable expiration on the lock in case Unlock is unable
|
||||||
// case Unlock is unable to be called due to some sort of network
|
// to be called due to some sort of network failure or system
|
||||||
// failure or system crash. Additionally, implementations should
|
// crash. Additionally, implementations should honor context
|
||||||
// honor context cancellation as much as possible (in case the
|
// cancellation as much as possible (in case the caller wishes
|
||||||
// caller wishes to give up and free resources before the lock
|
// to give up and free resources before the lock can be obtained).
|
||||||
// can be obtained).
|
//
|
||||||
Lock(ctx context.Context, key string) error
|
// 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
|
// called after a successful call to Lock, and only after the
|
||||||
// critical section is finished, even if it errored or timed
|
// critical section is finished, even if it errored or timed
|
||||||
// out. Unlock cleans up any resources allocated during Lock.
|
// 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.
|
// KeyInfo holds information about a key in storage.
|
||||||
|
|
@ -220,16 +237,14 @@ func CleanUpOwnLocks(ctx context.Context, logger *zap.Logger) {
|
||||||
locksMu.Lock()
|
locksMu.Lock()
|
||||||
defer locksMu.Unlock()
|
defer locksMu.Unlock()
|
||||||
for lockKey, storage := range locks {
|
for lockKey, storage := range locks {
|
||||||
err := storage.Unlock(ctx, lockKey)
|
if err := storage.Unlock(ctx, lockKey); err != nil {
|
||||||
if err == nil {
|
|
||||||
delete(locks, lockKey)
|
|
||||||
} else if logger != nil {
|
|
||||||
logger.Error("unable to clean up lock in storage backend",
|
logger.Error("unable to clean up lock in storage backend",
|
||||||
zap.Any("storage", storage),
|
zap.Any("storage", storage),
|
||||||
zap.String("lock_key", lockKey),
|
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: Run all tests
|
||||||
test:
|
test:
|
||||||
go test -race -coverprofile=/dev/null -timeout 60s -v ./...
|
go test -race -coverprofile=/dev/null -v ./...
|
||||||
|
|
||||||
## vet: Analyze code for potential errors
|
## vet: Analyze code for potential errors
|
||||||
vet:
|
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
|
StreamId() string
|
||||||
|
|
||||||
// Stats returns accumulated and instantaneous statistics of the connection.
|
// Stats returns accumulated and instantaneous statistics of the connection.
|
||||||
Stats() Statistics
|
Stats(s *Statistics)
|
||||||
}
|
}
|
||||||
|
|
||||||
type connStats struct {
|
type connStats struct {
|
||||||
|
|
@ -73,6 +73,7 @@ type connStats struct {
|
||||||
pktRecvKeepalive uint64
|
pktRecvKeepalive uint64
|
||||||
pktSentShutdown uint64
|
pktSentShutdown uint64
|
||||||
pktRecvShutdown uint64
|
pktRecvShutdown uint64
|
||||||
|
mbpsLinkCapacity float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we implement the net.Conn interface
|
// Check if we implement the net.Conn interface
|
||||||
|
|
@ -118,6 +119,8 @@ type srtConn struct {
|
||||||
tsbpdTimeBaseOffset uint64 // microseconds
|
tsbpdTimeBaseOffset uint64 // microseconds
|
||||||
tsbpdDelay uint64 // microseconds
|
tsbpdDelay uint64 // microseconds
|
||||||
tsbpdDrift uint64 // microseconds
|
tsbpdDrift uint64 // microseconds
|
||||||
|
peerTsbpdDelay uint64 // microseconds
|
||||||
|
dropThreshold uint64 // microseconds
|
||||||
|
|
||||||
// Queue for packets that are coming from the network
|
// Queue for packets that are coming from the network
|
||||||
networkQueue chan packet.Packet
|
networkQueue chan packet.Packet
|
||||||
|
|
@ -162,7 +165,8 @@ type srtConnConfig struct {
|
||||||
socketId uint32
|
socketId uint32
|
||||||
peerSocketId uint32
|
peerSocketId uint32
|
||||||
tsbpdTimeBase uint64 // microseconds
|
tsbpdTimeBase uint64 // microseconds
|
||||||
tsbpdDelay uint64
|
tsbpdDelay uint64 // microseconds
|
||||||
|
peerTsbpdDelay uint64 // microseconds
|
||||||
initialPacketSequenceNumber circular.Number
|
initialPacketSequenceNumber circular.Number
|
||||||
crypto crypto.Crypto
|
crypto crypto.Crypto
|
||||||
keyBaseEncryption packet.PacketEncryption
|
keyBaseEncryption packet.PacketEncryption
|
||||||
|
|
@ -181,6 +185,7 @@ func newSRTConn(config srtConnConfig) *srtConn {
|
||||||
peerSocketId: config.peerSocketId,
|
peerSocketId: config.peerSocketId,
|
||||||
tsbpdTimeBase: config.tsbpdTimeBase,
|
tsbpdTimeBase: config.tsbpdTimeBase,
|
||||||
tsbpdDelay: config.tsbpdDelay,
|
tsbpdDelay: config.tsbpdDelay,
|
||||||
|
peerTsbpdDelay: config.peerTsbpdDelay,
|
||||||
initialPacketSequenceNumber: config.initialPacketSequenceNumber,
|
initialPacketSequenceNumber: config.initialPacketSequenceNumber,
|
||||||
crypto: config.crypto,
|
crypto: config.crypto,
|
||||||
keyBaseEncryption: config.keyBaseEncryption,
|
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
|
// 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{
|
c.snd = congestion.NewLiveSend(congestion.SendConfig{
|
||||||
InitialSequenceNumber: c.initialPacketSequenceNumber,
|
InitialSequenceNumber: c.initialPacketSequenceNumber,
|
||||||
DropInterval: uint64(c.config.SendDropDelay.Microseconds()),
|
DropThreshold: c.dropThreshold,
|
||||||
MaxBW: c.config.MaxBW,
|
MaxBW: c.config.MaxBW,
|
||||||
InputBW: c.config.InputBW,
|
InputBW: c.config.InputBW,
|
||||||
MinInputBW: c.config.MinInputBW,
|
MinInputBW: c.config.MinInputBW,
|
||||||
|
|
@ -582,6 +594,8 @@ func (c *srtConn) handlePacket(p packet.Packet) {
|
||||||
|
|
||||||
c.debug.expectedRcvPacketSequenceNumber = header.PacketSequenceNumber.Inc()
|
c.debug.expectedRcvPacketSequenceNumber = header.PacketSequenceNumber.Inc()
|
||||||
|
|
||||||
|
//fmt.Printf("%s\n", p.String())
|
||||||
|
|
||||||
// Ignore FEC filter control packets
|
// Ignore FEC filter control packets
|
||||||
// https://github.com/Haivision/srt/blob/master/docs/features/packet-filtering-and-fec.md
|
// 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
|
// "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
|
// 4.10. Round-Trip Time Estimation
|
||||||
c.recalculateRTT(time.Duration(int64(cif.RTT)) * time.Microsecond)
|
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)
|
c.sendACKACK(p.Header().TypeSpecific)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -901,14 +918,14 @@ func (c *srtConn) sendACK(seq circular.Number, lite bool) {
|
||||||
|
|
||||||
p.Header().TypeSpecific = 0
|
p.Header().TypeSpecific = 0
|
||||||
} else {
|
} else {
|
||||||
pps, _ := c.recv.PacketRate()
|
pps, bps, capacity := c.recv.PacketRate()
|
||||||
|
|
||||||
cif.RTT = uint32(c.rtt)
|
cif.RTT = uint32(c.rtt)
|
||||||
cif.RTTVar = uint32(c.rttVar)
|
cif.RTTVar = uint32(c.rttVar)
|
||||||
cif.AvailableBufferSize = c.config.FC // TODO: available buffer size (packets)
|
cif.AvailableBufferSize = c.config.FC // TODO: available buffer size (packets)
|
||||||
cif.PacketsReceivingRate = pps // packets receiving rate (packets/s)
|
cif.PacketsReceivingRate = uint32(pps) // packets receiving rate (packets/s)
|
||||||
cif.EstimatedLinkCapacity = 0 // estimated link capacity (packets/s), not relevant for live mode
|
cif.EstimatedLinkCapacity = uint32(capacity) // estimated link capacity (packets/s), not relevant for live mode
|
||||||
cif.ReceivingRate = 0 // receiving rate (bytes/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()
|
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) SetReadDeadline(t time.Time) error { return nil }
|
||||||
func (c *srtConn) SetWriteDeadline(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()
|
send := c.snd.Stats()
|
||||||
recv := c.recv.Stats()
|
recv := c.recv.Stats()
|
||||||
|
|
||||||
s := Statistics{
|
previous := s.Accumulated
|
||||||
MsTimeStamp: uint64(time.Since(c.start).Milliseconds()),
|
interval := now - s.MsTimeStamp
|
||||||
|
|
||||||
// Accumulated
|
// Accumulated
|
||||||
PktSent: send.PktSent,
|
s.Accumulated = StatisticsAccumulated{
|
||||||
PktRecv: recv.PktRecv,
|
PktSent: send.Pkt,
|
||||||
PktSentUnique: send.PktSentUnique,
|
PktRecv: recv.Pkt,
|
||||||
PktRecvUnique: recv.PktRecvUnique,
|
PktSentUnique: send.PktUnique,
|
||||||
PktSndLoss: send.PktSndLoss,
|
PktRecvUnique: recv.PktUnique,
|
||||||
PktRcvLoss: recv.PktRcvLoss,
|
PktSendLoss: send.PktLoss,
|
||||||
PktRetrans: send.PktRetrans,
|
PktRecvLoss: recv.PktLoss,
|
||||||
PktRcvRetrans: recv.PktRcvRetrans,
|
PktRetrans: send.PktRetrans,
|
||||||
PktSentACK: c.statistics.pktSentACK,
|
PktRecvRetrans: recv.PktRetrans,
|
||||||
PktRecvACK: c.statistics.pktRecvACK,
|
PktSentACK: c.statistics.pktSentACK,
|
||||||
PktSentNAK: c.statistics.pktSentNAK,
|
PktRecvACK: c.statistics.pktRecvACK,
|
||||||
PktRecvNAK: c.statistics.pktRecvNAK,
|
PktSentNAK: c.statistics.pktSentNAK,
|
||||||
PktSentKM: c.statistics.pktSentKM,
|
PktRecvNAK: c.statistics.pktRecvNAK,
|
||||||
PktRecvKM: c.statistics.pktRecvKM,
|
PktSentKM: c.statistics.pktSentKM,
|
||||||
UsSndDuration: send.UsSndDuration,
|
PktRecvKM: c.statistics.pktRecvKM,
|
||||||
PktSndDrop: send.PktSndDrop,
|
UsSndDuration: send.UsSndDuration,
|
||||||
PktRcvDrop: recv.PktRcvDrop,
|
PktSendDrop: send.PktDrop,
|
||||||
PktRcvUndecrypt: c.statistics.pktRecvUndecrypt,
|
PktRecvDrop: recv.PktDrop,
|
||||||
ByteSent: send.ByteSent + (send.PktSent * c.statistics.headerSize),
|
PktRecvUndecrypt: c.statistics.pktRecvUndecrypt,
|
||||||
ByteRecv: recv.ByteRecv + (recv.PktRecv * c.statistics.headerSize),
|
ByteSent: send.Byte + (send.Pkt * c.statistics.headerSize),
|
||||||
ByteSentUnique: send.ByteSentUnique + (send.PktSentUnique * c.statistics.headerSize),
|
ByteRecv: recv.Byte + (recv.Pkt * c.statistics.headerSize),
|
||||||
ByteRecvUnique: recv.ByteRecvUnique + (recv.PktRecvUnique * c.statistics.headerSize),
|
ByteSentUnique: send.ByteUnique + (send.PktUnique * c.statistics.headerSize),
|
||||||
ByteRcvLoss: recv.ByteRcvLoss + (recv.PktRcvLoss * c.statistics.headerSize),
|
ByteRecvUnique: recv.ByteUnique + (recv.PktUnique * c.statistics.headerSize),
|
||||||
ByteRetrans: send.ByteRetrans + (send.PktRetrans * c.statistics.headerSize),
|
ByteRecvLoss: recv.ByteLoss + (recv.PktLoss * c.statistics.headerSize),
|
||||||
ByteSndDrop: send.ByteSndDrop + (send.PktSndDrop * c.statistics.headerSize),
|
ByteRetrans: send.ByteRetrans + (send.PktRetrans * c.statistics.headerSize),
|
||||||
ByteRcvDrop: recv.ByteRcvDrop + (recv.PktRcvDrop * c.statistics.headerSize),
|
ByteRecvRetrans: recv.ByteRetrans + (recv.PktRetrans * c.statistics.headerSize),
|
||||||
ByteRcvUndecrypt: c.statistics.byteRecvUndecrypt + (c.statistics.pktRecvUndecrypt * c.statistics.headerSize),
|
ByteSendDrop: send.ByteDrop + (send.PktDrop * c.statistics.headerSize),
|
||||||
|
ByteRecvDrop: recv.ByteDrop + (recv.PktDrop * c.statistics.headerSize),
|
||||||
// Instantaneous
|
ByteRecvUndecrypt: c.statistics.byteRecvUndecrypt + (c.statistics.pktRecvUndecrypt * c.statistics.headerSize),
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the largest TSBPD delay as advertised by the listener, but
|
// Select the largest TSBPD delay advertised by the listener, but at least 120ms
|
||||||
// at least 120ms
|
recvTsbpdDelay := uint16(dl.config.ReceiverLatency.Milliseconds())
|
||||||
tsbpdDelay := uint16(120)
|
sendTsbpdDelay := uint16(dl.config.PeerLatency.Milliseconds())
|
||||||
if cif.RecvTSBPDDelay > tsbpdDelay {
|
|
||||||
tsbpdDelay = cif.RecvTSBPDDelay
|
if cif.SendTSBPDDelay > recvTsbpdDelay {
|
||||||
|
recvTsbpdDelay = cif.SendTSBPDDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
if cif.SendTSBPDDelay > tsbpdDelay {
|
if cif.RecvTSBPDDelay > sendTsbpdDelay {
|
||||||
tsbpdDelay = cif.SendTSBPDDelay
|
sendTsbpdDelay = cif.RecvTSBPDDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the peer has a smaller MTU size, adjust to it
|
// 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,
|
socketId: dl.socketId,
|
||||||
peerSocketId: cif.SRTSocketId,
|
peerSocketId: cif.SRTSocketId,
|
||||||
tsbpdTimeBase: uint64(time.Since(dl.start).Microseconds()),
|
tsbpdTimeBase: uint64(time.Since(dl.start).Microseconds()),
|
||||||
tsbpdDelay: uint64(tsbpdDelay) * 1000,
|
tsbpdDelay: uint64(recvTsbpdDelay) * 1000,
|
||||||
|
peerTsbpdDelay: uint64(sendTsbpdDelay) * 1000,
|
||||||
initialPacketSequenceNumber: cif.InitialPacketSequenceNumber,
|
initialPacketSequenceNumber: cif.InitialPacketSequenceNumber,
|
||||||
crypto: dl.crypto,
|
crypto: dl.crypto,
|
||||||
keyBaseEncryption: packet.EvenKeyEncrypted,
|
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) 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) 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) 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) {
|
func (dl *dialer) log(topic string, message func() string) {
|
||||||
dl.config.Logger.Print(topic, dl.socketId, 2, message)
|
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
|
// SendConfig is the configuration for the liveSend congestion control
|
||||||
type SendConfig struct {
|
type SendConfig struct {
|
||||||
InitialSequenceNumber circular.Number
|
InitialSequenceNumber circular.Number
|
||||||
DropInterval uint64
|
DropThreshold uint64
|
||||||
MaxBW int64
|
MaxBW int64
|
||||||
InputBW int64
|
InputBW int64
|
||||||
MinInputBW int64
|
MinInputBW int64
|
||||||
|
|
@ -25,6 +25,7 @@ type Sender interface {
|
||||||
Tick(now uint64)
|
Tick(now uint64)
|
||||||
ACK(sequenceNumber circular.Number)
|
ACK(sequenceNumber circular.Number)
|
||||||
NAK(sequenceNumbers []circular.Number)
|
NAK(sequenceNumbers []circular.Number)
|
||||||
|
SetDropThreshold(threshold uint64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveConfig is the configuration for the liveResv congestion control
|
// 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
|
// Receiver is the receiving part of the congestion control
|
||||||
type Receiver interface {
|
type Receiver interface {
|
||||||
Stats() ReceiveStats
|
Stats() ReceiveStats
|
||||||
PacketRate() (pps, bps uint32)
|
PacketRate() (pps, bps, capacity float64)
|
||||||
Flush()
|
Flush()
|
||||||
Push(pkt packet.Packet)
|
Push(pkt packet.Packet)
|
||||||
Tick(now uint64)
|
Tick(now uint64)
|
||||||
|
|
@ -49,55 +50,68 @@ type Receiver interface {
|
||||||
|
|
||||||
// SendStats are collected statistics from liveSend
|
// SendStats are collected statistics from liveSend
|
||||||
type SendStats struct {
|
type SendStats struct {
|
||||||
PktSent uint64
|
Pkt uint64 // Sent packets in total
|
||||||
ByteSent uint64
|
Byte uint64 // Sent bytes in total
|
||||||
|
|
||||||
PktSentUnique uint64
|
PktUnique uint64
|
||||||
ByteSentUnique uint64
|
ByteUnique uint64
|
||||||
|
|
||||||
PktSndLoss uint64
|
PktLoss uint64
|
||||||
ByteSndLoss uint64
|
ByteLoss uint64
|
||||||
|
|
||||||
PktRetrans uint64
|
PktRetrans uint64
|
||||||
ByteRetrans uint64
|
ByteRetrans uint64
|
||||||
|
|
||||||
UsSndDuration uint64 // microseconds
|
UsSndDuration uint64 // microseconds
|
||||||
|
|
||||||
PktSndDrop uint64
|
PktDrop uint64
|
||||||
ByteSndDrop uint64
|
ByteDrop uint64
|
||||||
|
|
||||||
// instantaneous
|
// instantaneous
|
||||||
PktSndBuf uint64
|
PktBuf uint64
|
||||||
ByteSndBuf uint64
|
ByteBuf uint64
|
||||||
MsSndBuf uint64
|
MsBuf uint64
|
||||||
|
|
||||||
PktFlightSize uint64
|
PktFlightSize uint64
|
||||||
|
|
||||||
UsPktSndPeriod float64 // microseconds
|
UsPktSndPeriod float64 // microseconds
|
||||||
BytePayload uint64
|
BytePayload uint64
|
||||||
|
|
||||||
|
MbpsEstimatedInputBandwidth float64
|
||||||
|
MbpsEstimatedSentBandwidth float64
|
||||||
|
|
||||||
|
PktLossRate float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveStats are collected statistics from liveRecv
|
// ReceiveStats are collected statistics from liveRecv
|
||||||
type ReceiveStats struct {
|
type ReceiveStats struct {
|
||||||
PktRecv uint64
|
Pkt uint64
|
||||||
ByteRecv uint64
|
Byte uint64
|
||||||
|
|
||||||
PktRecvUnique uint64
|
PktUnique uint64
|
||||||
ByteRecvUnique uint64
|
ByteUnique uint64
|
||||||
|
|
||||||
PktRcvLoss uint64
|
PktLoss uint64
|
||||||
ByteRcvLoss uint64
|
ByteLoss uint64
|
||||||
|
|
||||||
PktRcvRetrans uint64
|
PktRetrans uint64
|
||||||
ByteRcvRetrans uint64
|
ByteRetrans uint64
|
||||||
|
|
||||||
PktRcvDrop uint64
|
PktBelated uint64
|
||||||
ByteRcvDrop uint64
|
ByteBelated uint64
|
||||||
|
|
||||||
|
PktDrop uint64
|
||||||
|
ByteDrop uint64
|
||||||
|
|
||||||
// instantaneous
|
// instantaneous
|
||||||
PktRcvBuf uint64
|
PktBuf uint64
|
||||||
ByteRcvBuf uint64
|
ByteBuf uint64
|
||||||
MsRcvBuf uint64
|
MsBuf uint64
|
||||||
|
|
||||||
BytePayload 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
|
// liveSend implements the Sender interface
|
||||||
type liveSend struct {
|
type liveSend struct {
|
||||||
nextSequenceNumber circular.Number
|
nextSequenceNumber circular.Number
|
||||||
|
dropThreshold uint64
|
||||||
|
|
||||||
packetList *list.List
|
packetList *list.List
|
||||||
lossList *list.List
|
lossList *list.List
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
|
||||||
dropInterval uint64 // microseconds
|
|
||||||
|
|
||||||
avgPayloadSize float64 // bytes
|
avgPayloadSize float64 // bytes
|
||||||
pktSndPeriod float64 // microseconds
|
pktSndPeriod float64 // microseconds
|
||||||
maxBW float64 // bytes/s
|
maxBW float64 // bytes/s
|
||||||
|
|
@ -29,14 +28,20 @@ type liveSend struct {
|
||||||
|
|
||||||
statistics SendStats
|
statistics SendStats
|
||||||
|
|
||||||
rate struct {
|
probeTime uint64
|
||||||
period time.Duration
|
|
||||||
last time.Time
|
|
||||||
|
|
||||||
bytes uint64
|
rate struct {
|
||||||
prevBytes uint64
|
period uint64 // microseconds
|
||||||
|
last uint64
|
||||||
|
|
||||||
|
bytes uint64
|
||||||
|
bytesSent uint64
|
||||||
|
bytesRetrans uint64
|
||||||
|
|
||||||
estimatedInputBW float64 // bytes/s
|
estimatedInputBW float64 // bytes/s
|
||||||
|
estimatedSentBW float64 // bytes/s
|
||||||
|
|
||||||
|
pktLossRate float64
|
||||||
}
|
}
|
||||||
|
|
||||||
deliver func(p packet.Packet)
|
deliver func(p packet.Packet)
|
||||||
|
|
@ -46,12 +51,11 @@ type liveSend struct {
|
||||||
func NewLiveSend(config SendConfig) Sender {
|
func NewLiveSend(config SendConfig) Sender {
|
||||||
s := &liveSend{
|
s := &liveSend{
|
||||||
nextSequenceNumber: config.InitialSequenceNumber,
|
nextSequenceNumber: config.InitialSequenceNumber,
|
||||||
|
dropThreshold: config.DropThreshold,
|
||||||
packetList: list.New(),
|
packetList: list.New(),
|
||||||
lossList: list.New(),
|
lossList: list.New(),
|
||||||
|
|
||||||
dropInterval: config.DropInterval, // microseconds
|
avgPayloadSize: packet.MAX_PAYLOAD_SIZE, // 5.1.2. SRT's Default LiveCC Algorithm
|
||||||
|
|
||||||
avgPayloadSize: 1456, // 5.1.2. SRT's Default LiveCC Algorithm
|
|
||||||
maxBW: float64(config.MaxBW),
|
maxBW: float64(config.MaxBW),
|
||||||
inputBW: float64(config.InputBW),
|
inputBW: float64(config.InputBW),
|
||||||
overheadBW: float64(config.OverheadBW),
|
overheadBW: float64(config.OverheadBW),
|
||||||
|
|
@ -66,8 +70,8 @@ func NewLiveSend(config SendConfig) Sender {
|
||||||
s.maxBW = 128 * 1024 * 1024 // 1 Gbit/s
|
s.maxBW = 128 * 1024 * 1024 // 1 Gbit/s
|
||||||
s.pktSndPeriod = (s.avgPayloadSize + 16) * 1_000_000 / s.maxBW
|
s.pktSndPeriod = (s.avgPayloadSize + 16) * 1_000_000 / s.maxBW
|
||||||
|
|
||||||
s.rate.period = time.Second
|
s.rate.period = uint64(time.Second.Microseconds())
|
||||||
s.rate.last = time.Now()
|
s.rate.last = 0
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
@ -78,15 +82,20 @@ func (s *liveSend) Stats() SendStats {
|
||||||
|
|
||||||
s.statistics.UsPktSndPeriod = s.pktSndPeriod
|
s.statistics.UsPktSndPeriod = s.pktSndPeriod
|
||||||
s.statistics.BytePayload = uint64(s.avgPayloadSize)
|
s.statistics.BytePayload = uint64(s.avgPayloadSize)
|
||||||
s.statistics.MsSndBuf = 0
|
s.statistics.MsBuf = 0
|
||||||
|
|
||||||
max := s.lossList.Back()
|
max := s.lossList.Back()
|
||||||
min := s.lossList.Front()
|
min := s.lossList.Front()
|
||||||
|
|
||||||
if max != nil && min != nil {
|
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
|
return s.statistics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,24 +121,27 @@ func (s *liveSend) Push(p packet.Packet) {
|
||||||
|
|
||||||
pktLen := p.Len()
|
pktLen := p.Len()
|
||||||
|
|
||||||
s.statistics.PktSndBuf++
|
s.statistics.PktBuf++
|
||||||
s.statistics.ByteSndBuf += pktLen
|
s.statistics.ByteBuf += pktLen
|
||||||
|
|
||||||
// bandwidth calculation
|
// input bandwidth calculation
|
||||||
s.rate.bytes += pktLen
|
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))
|
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.packetList.PushBack(p)
|
||||||
|
|
||||||
s.statistics.PktFlightSize = uint64(s.packetList.Len())
|
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() {
|
for e := s.packetList.Front(); e != nil; e = e.Next() {
|
||||||
p := e.Value.(packet.Packet)
|
p := e.Value.(packet.Packet)
|
||||||
if p.Header().PktTsbpdTime <= now {
|
if p.Header().PktTsbpdTime <= now {
|
||||||
s.statistics.PktSent++
|
s.statistics.Pkt++
|
||||||
s.statistics.PktSentUnique++
|
s.statistics.PktUnique++
|
||||||
|
|
||||||
s.statistics.ByteSent += p.Len()
|
pktLen := p.Len()
|
||||||
s.statistics.ByteSentUnique += p.Len()
|
|
||||||
|
s.statistics.Byte += pktLen
|
||||||
|
s.statistics.ByteUnique += pktLen
|
||||||
|
|
||||||
s.statistics.UsSndDuration += uint64(s.pktSndPeriod)
|
s.statistics.UsSndDuration += uint64(s.pktSndPeriod)
|
||||||
|
|
||||||
// 5.1.2. SRT's Default LiveCC Algorithm
|
// 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)
|
s.deliver(p)
|
||||||
removeList = append(removeList, e)
|
removeList = append(removeList, e)
|
||||||
|
|
@ -171,12 +187,12 @@ func (s *liveSend) Tick(now uint64) {
|
||||||
for e := s.lossList.Front(); e != nil; e = e.Next() {
|
for e := s.lossList.Front(); e != nil; e = e.Next() {
|
||||||
p := e.Value.(packet.Packet)
|
p := e.Value.(packet.Packet)
|
||||||
|
|
||||||
if p.Header().PktTsbpdTime+s.dropInterval <= now {
|
if p.Header().PktTsbpdTime+s.dropThreshold <= now {
|
||||||
// dropped packet because too old
|
// dropped packet because too old
|
||||||
s.statistics.PktSndDrop++
|
s.statistics.PktDrop++
|
||||||
s.statistics.PktSndLoss++
|
s.statistics.PktLoss++
|
||||||
s.statistics.ByteSndDrop += p.Len()
|
s.statistics.ByteDrop += p.Len()
|
||||||
s.statistics.ByteSndLoss += p.Len()
|
s.statistics.ByteLoss += p.Len()
|
||||||
|
|
||||||
removeList = append(removeList, e)
|
removeList = append(removeList, e)
|
||||||
}
|
}
|
||||||
|
|
@ -186,8 +202,8 @@ func (s *liveSend) Tick(now uint64) {
|
||||||
for _, e := range removeList {
|
for _, e := range removeList {
|
||||||
p := e.Value.(packet.Packet)
|
p := e.Value.(packet.Packet)
|
||||||
|
|
||||||
s.statistics.PktSndBuf--
|
s.statistics.PktBuf--
|
||||||
s.statistics.ByteSndBuf -= p.Len()
|
s.statistics.ByteBuf -= p.Len()
|
||||||
|
|
||||||
s.lossList.Remove(e)
|
s.lossList.Remove(e)
|
||||||
|
|
||||||
|
|
@ -195,6 +211,26 @@ func (s *liveSend) Tick(now uint64) {
|
||||||
p.Decommission()
|
p.Decommission()
|
||||||
}
|
}
|
||||||
s.lock.Unlock()
|
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) {
|
func (s *liveSend) ACK(sequenceNumber circular.Number) {
|
||||||
|
|
@ -216,8 +252,8 @@ func (s *liveSend) ACK(sequenceNumber circular.Number) {
|
||||||
for _, e := range removeList {
|
for _, e := range removeList {
|
||||||
p := e.Value.(packet.Packet)
|
p := e.Value.(packet.Packet)
|
||||||
|
|
||||||
s.statistics.PktSndBuf--
|
s.statistics.PktBuf--
|
||||||
s.statistics.ByteSndBuf -= p.Len()
|
s.statistics.ByteBuf -= p.Len()
|
||||||
|
|
||||||
s.lossList.Remove(e)
|
s.lossList.Remove(e)
|
||||||
|
|
||||||
|
|
@ -242,16 +278,19 @@ func (s *liveSend) NAK(sequenceNumbers []circular.Number) {
|
||||||
for i := 0; i < len(sequenceNumbers); i += 2 {
|
for i := 0; i < len(sequenceNumbers); i += 2 {
|
||||||
if p.Header().PacketSequenceNumber.Gte(sequenceNumbers[i]) && p.Header().PacketSequenceNumber.Lte(sequenceNumbers[i+1]) {
|
if p.Header().PacketSequenceNumber.Gte(sequenceNumbers[i]) && p.Header().PacketSequenceNumber.Lte(sequenceNumbers[i+1]) {
|
||||||
s.statistics.PktRetrans++
|
s.statistics.PktRetrans++
|
||||||
s.statistics.PktSent++
|
s.statistics.Pkt++
|
||||||
s.statistics.PktSndLoss++
|
s.statistics.PktLoss++
|
||||||
|
|
||||||
s.statistics.ByteRetrans += p.Len()
|
s.statistics.ByteRetrans += p.Len()
|
||||||
s.statistics.ByteSent += p.Len()
|
s.statistics.Byte += p.Len()
|
||||||
s.statistics.ByteSndLoss += p.Len()
|
s.statistics.ByteLoss += p.Len()
|
||||||
|
|
||||||
// 5.1.2. SRT's Default LiveCC Algorithm
|
// 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(p.Len())
|
||||||
|
|
||||||
|
s.rate.bytesSent += p.Len()
|
||||||
|
s.rate.bytesRetrans += p.Len()
|
||||||
|
|
||||||
p.Header().RetransmittedPacketFlag = true
|
p.Header().RetransmittedPacketFlag = true
|
||||||
s.deliver(p)
|
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
|
// liveReceive implements the Receiver interface
|
||||||
type liveReceive struct {
|
type liveReceive struct {
|
||||||
maxSeenSequenceNumber circular.Number
|
maxSeenSequenceNumber circular.Number
|
||||||
|
|
@ -275,21 +321,26 @@ type liveReceive struct {
|
||||||
lastPeriodicACK uint64
|
lastPeriodicACK uint64
|
||||||
lastPeriodicNAK uint64
|
lastPeriodicNAK uint64
|
||||||
|
|
||||||
avgPayloadSize float64 // bytes
|
avgPayloadSize float64 // bytes
|
||||||
|
avgLinkCapacity float64 // packets per second
|
||||||
|
|
||||||
|
probeTime time.Time
|
||||||
|
probeNextSeq circular.Number
|
||||||
|
|
||||||
statistics ReceiveStats
|
statistics ReceiveStats
|
||||||
|
|
||||||
rate struct {
|
rate struct {
|
||||||
last time.Time
|
last uint64 // microseconds
|
||||||
period time.Duration
|
period uint64
|
||||||
|
|
||||||
packets uint64
|
packets uint64
|
||||||
prevPackets uint64
|
bytes uint64
|
||||||
bytes uint64
|
bytesRetrans uint64
|
||||||
prevBytes uint64
|
|
||||||
|
|
||||||
pps uint32
|
packetsPerSecond float64
|
||||||
bps uint32
|
bytesPerSecond float64
|
||||||
|
|
||||||
|
pktLossRate float64
|
||||||
}
|
}
|
||||||
|
|
||||||
sendACK func(seq circular.Number, light bool)
|
sendACK func(seq circular.Number, light bool)
|
||||||
|
|
@ -327,8 +378,8 @@ func NewLiveReceive(config ReceiveConfig) Receiver {
|
||||||
r.deliver = func(p packet.Packet) {}
|
r.deliver = func(p packet.Packet) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.rate.last = time.Now()
|
r.rate.last = 0
|
||||||
r.rate.period = time.Second
|
r.rate.period = uint64(time.Second.Microseconds())
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
@ -338,34 +389,20 @@ func (r *liveReceive) Stats() ReceiveStats {
|
||||||
defer r.lock.RUnlock()
|
defer r.lock.RUnlock()
|
||||||
|
|
||||||
r.statistics.BytePayload = uint64(r.avgPayloadSize)
|
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
|
return r.statistics
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *liveReceive) PacketRate() (pps, bps uint32) {
|
func (r *liveReceive) PacketRate() (pps, bps, capacity float64) {
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
|
|
||||||
tdiff := time.Since(r.rate.last)
|
pps = r.rate.packetsPerSecond
|
||||||
|
bps = r.rate.bytesPerSecond
|
||||||
if tdiff < r.rate.period {
|
capacity = r.avgLinkCapacity
|
||||||
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
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -385,6 +422,28 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||||
return
|
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++
|
r.nPackets++
|
||||||
|
|
||||||
pktLen := pkt.Len()
|
pktLen := pkt.Len()
|
||||||
|
|
@ -392,13 +451,15 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||||
r.rate.packets++
|
r.rate.packets++
|
||||||
r.rate.bytes += pktLen
|
r.rate.bytes += pktLen
|
||||||
|
|
||||||
r.statistics.PktRecv++
|
r.statistics.Pkt++
|
||||||
r.statistics.ByteRecv += pktLen
|
r.statistics.Byte += pktLen
|
||||||
|
|
||||||
//pkt.PktTsbpdTime = pkt.Timestamp + r.delay
|
//pkt.PktTsbpdTime = pkt.Timestamp + r.delay
|
||||||
if pkt.Header().RetransmittedPacketFlag {
|
if pkt.Header().RetransmittedPacketFlag {
|
||||||
r.statistics.PktRcvRetrans++
|
r.statistics.PktRetrans++
|
||||||
r.statistics.ByteRcvRetrans += pktLen
|
r.statistics.ByteRetrans += pktLen
|
||||||
|
|
||||||
|
r.rate.bytesRetrans += pktLen
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.1.2. SRT's Default LiveCC Algorithm
|
// 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) {
|
if pkt.Header().PacketSequenceNumber.Lte(r.lastDeliveredSequenceNumber) {
|
||||||
// too old, because up until r.lastDeliveredSequenceNumber, we already delivered
|
// too old, because up until r.lastDeliveredSequenceNumber, we already delivered
|
||||||
r.statistics.PktRcvDrop++
|
r.statistics.PktBelated++
|
||||||
r.statistics.ByteRcvDrop += pktLen
|
r.statistics.ByteBelated += pktLen
|
||||||
|
|
||||||
|
r.statistics.PktDrop++
|
||||||
|
r.statistics.ByteDrop += pktLen
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pkt.Header().PacketSequenceNumber.Lt(r.lastACKSequenceNumber) {
|
if pkt.Header().PacketSequenceNumber.Lt(r.lastACKSequenceNumber) {
|
||||||
// already acknowledged, ignoring
|
// already acknowledged, ignoring
|
||||||
r.statistics.PktRcvDrop++
|
r.statistics.PktDrop++
|
||||||
r.statistics.ByteRcvDrop += pktLen
|
r.statistics.ByteDrop += pktLen
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -430,17 +494,17 @@ func (r *liveReceive) Push(pkt packet.Packet) {
|
||||||
|
|
||||||
if p.Header().PacketSequenceNumber == pkt.Header().PacketSequenceNumber {
|
if p.Header().PacketSequenceNumber == pkt.Header().PacketSequenceNumber {
|
||||||
// already received (has been sent more than once), ignoring
|
// already received (has been sent more than once), ignoring
|
||||||
r.statistics.PktRcvDrop++
|
r.statistics.PktDrop++
|
||||||
r.statistics.ByteRcvDrop += pktLen
|
r.statistics.ByteDrop += pktLen
|
||||||
|
|
||||||
break
|
break
|
||||||
} else if p.Header().PacketSequenceNumber.Gt(pkt.Header().PacketSequenceNumber) {
|
} else if p.Header().PacketSequenceNumber.Gt(pkt.Header().PacketSequenceNumber) {
|
||||||
// late arrival, this fills a gap
|
// late arrival, this fills a gap
|
||||||
r.statistics.PktRcvBuf++
|
r.statistics.PktBuf++
|
||||||
r.statistics.PktRecvUnique++
|
r.statistics.PktUnique++
|
||||||
|
|
||||||
r.statistics.ByteRcvBuf += pktLen
|
r.statistics.ByteBuf += pktLen
|
||||||
r.statistics.ByteRecvUnique += pktLen
|
r.statistics.ByteUnique += pktLen
|
||||||
|
|
||||||
r.packetList.InsertBefore(pkt, e)
|
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())
|
r.sendNAK(r.maxSeenSequenceNumber.Inc(), pkt.Header().PacketSequenceNumber.Dec())
|
||||||
|
|
||||||
len := uint64(pkt.Header().PacketSequenceNumber.Distance(r.maxSeenSequenceNumber))
|
len := uint64(pkt.Header().PacketSequenceNumber.Distance(r.maxSeenSequenceNumber))
|
||||||
r.statistics.PktRcvLoss += len
|
r.statistics.PktLoss += len
|
||||||
r.statistics.ByteRcvLoss += len * uint64(r.avgPayloadSize)
|
r.statistics.ByteLoss += len * uint64(r.avgPayloadSize)
|
||||||
|
|
||||||
r.maxSeenSequenceNumber = pkt.Header().PacketSequenceNumber
|
r.maxSeenSequenceNumber = pkt.Header().PacketSequenceNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
r.statistics.PktRcvBuf++
|
r.statistics.PktBuf++
|
||||||
r.statistics.PktRecvUnique++
|
r.statistics.PktUnique++
|
||||||
|
|
||||||
r.statistics.ByteRcvBuf += pktLen
|
r.statistics.ByteBuf += pktLen
|
||||||
r.statistics.ByteRecvUnique += pktLen
|
r.statistics.ByteUnique += pktLen
|
||||||
|
|
||||||
r.packetList.PushBack(pkt)
|
r.packetList.PushBack(pkt)
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +585,7 @@ func (r *liveReceive) periodicACK(now uint64) (ok bool, sequenceNumber circular.
|
||||||
r.lastPeriodicACK = now
|
r.lastPeriodicACK = now
|
||||||
r.nPackets = 0
|
r.nPackets = 0
|
||||||
|
|
||||||
r.statistics.MsRcvBuf = (maxPktTsbpdTime - minPktTsbpdTime) / 1_000
|
r.statistics.MsBuf = (maxPktTsbpdTime - minPktTsbpdTime) / 1_000
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -572,15 +636,13 @@ func (r *liveReceive) Tick(now uint64) {
|
||||||
|
|
||||||
// deliver packets whose PktTsbpdTime is ripe
|
// deliver packets whose PktTsbpdTime is ripe
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
|
||||||
|
|
||||||
removeList := make([]*list.Element, 0, r.packetList.Len())
|
removeList := make([]*list.Element, 0, r.packetList.Len())
|
||||||
for e := r.packetList.Front(); e != nil; e = e.Next() {
|
for e := r.packetList.Front(); e != nil; e = e.Next() {
|
||||||
p := e.Value.(packet.Packet)
|
p := e.Value.(packet.Packet)
|
||||||
|
|
||||||
if p.Header().PacketSequenceNumber.Lte(r.lastACKSequenceNumber) && p.Header().PktTsbpdTime <= now {
|
if p.Header().PacketSequenceNumber.Lte(r.lastACKSequenceNumber) && p.Header().PktTsbpdTime <= now {
|
||||||
r.statistics.PktRcvBuf--
|
r.statistics.PktBuf--
|
||||||
r.statistics.ByteRcvBuf -= p.Len()
|
r.statistics.ByteBuf -= p.Len()
|
||||||
|
|
||||||
r.lastDeliveredSequenceNumber = p.Header().PacketSequenceNumber
|
r.lastDeliveredSequenceNumber = p.Header().PacketSequenceNumber
|
||||||
|
|
||||||
|
|
@ -594,6 +656,27 @@ func (r *liveReceive) Tick(now uint64) {
|
||||||
for _, e := range removeList {
|
for _, e := range removeList {
|
||||||
r.packetList.Remove(e)
|
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) {
|
func (r *liveReceive) SetNAKInterval(nakInterval uint64) {
|
||||||
|
|
@ -630,7 +713,6 @@ type fakeLiveReceive struct {
|
||||||
periodicNAKInterval uint64 // config
|
periodicNAKInterval uint64 // config
|
||||||
|
|
||||||
lastPeriodicACK uint64
|
lastPeriodicACK uint64
|
||||||
lastPeriodicNAK uint64
|
|
||||||
|
|
||||||
avgPayloadSize float64 // bytes
|
avgPayloadSize float64 // bytes
|
||||||
|
|
||||||
|
|
@ -638,13 +720,11 @@ type fakeLiveReceive struct {
|
||||||
last time.Time
|
last time.Time
|
||||||
period time.Duration
|
period time.Duration
|
||||||
|
|
||||||
packets uint64
|
packets uint64
|
||||||
prevPackets uint64
|
bytes uint64
|
||||||
bytes uint64
|
|
||||||
prevBytes uint64
|
|
||||||
|
|
||||||
pps uint32
|
pps float64
|
||||||
bps uint32
|
bps float64
|
||||||
}
|
}
|
||||||
|
|
||||||
sendACK func(seq circular.Number, light bool)
|
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) Stats() ReceiveStats { return ReceiveStats{} }
|
||||||
func (r *fakeLiveReceive) PacketRate() (pps, bps uint32) {
|
func (r *fakeLiveReceive) PacketRate() (pps, bps, capacity float64) {
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
|
|
||||||
|
|
@ -702,13 +782,10 @@ func (r *fakeLiveReceive) PacketRate() (pps, bps uint32) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pdiff := r.rate.packets - r.rate.prevPackets
|
r.rate.pps = float64(r.rate.packets) / tdiff.Seconds()
|
||||||
bdiff := r.rate.bytes - r.rate.prevBytes
|
r.rate.bps = float64(r.rate.bytes) / tdiff.Seconds()
|
||||||
|
|
||||||
r.rate.pps = uint32(float64(pdiff) / tdiff.Seconds())
|
r.rate.packets, r.rate.bytes = 0, 0
|
||||||
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()
|
r.rate.last = time.Now()
|
||||||
|
|
||||||
pps = r.rate.pps
|
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_SEQUENCENUMBER uint32 = 0b01111111_11111111_11111111_11111111
|
||||||
const MAX_TIMESTAMP uint32 = 0b11111111_11111111_11111111_11111111
|
const MAX_TIMESTAMP uint32 = 0b11111111_11111111_11111111_11111111
|
||||||
|
const MAX_PAYLOAD_SIZE = 1456
|
||||||
|
|
||||||
// Table 1: SRT Control Packet Types
|
// Table 1: SRT Control Packet Types
|
||||||
const (
|
const (
|
||||||
|
|
@ -279,7 +280,7 @@ func (p *pkt) Decommission() {
|
||||||
func (p pkt) String() string {
|
func (p pkt) String() string {
|
||||||
var b strings.Builder
|
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 {
|
if p.header.IsControlPacket {
|
||||||
fmt.Fprintf(&b, "control packet:\n")
|
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
|
// Create a new socket ID
|
||||||
socketId := uint32(time.Since(ln.start).Microseconds())
|
socketId := uint32(time.Since(ln.start).Microseconds())
|
||||||
|
|
||||||
// Select the largest TSBPD delay advertised by the caller, but at
|
// Select the largest TSBPD delay advertised by the listener, but at least 120ms
|
||||||
// least 120ms
|
recvTsbpdDelay := uint16(ln.config.ReceiverLatency.Milliseconds())
|
||||||
tsbpdDelay := uint16(120)
|
sendTsbpdDelay := uint16(ln.config.PeerLatency.Milliseconds())
|
||||||
if request.handshake.RecvTSBPDDelay > tsbpdDelay {
|
|
||||||
tsbpdDelay = request.handshake.RecvTSBPDDelay
|
if request.handshake.SendTSBPDDelay > recvTsbpdDelay {
|
||||||
|
recvTsbpdDelay = request.handshake.SendTSBPDDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.handshake.SendTSBPDDelay > tsbpdDelay {
|
if request.handshake.RecvTSBPDDelay > sendTsbpdDelay {
|
||||||
tsbpdDelay = request.handshake.SendTSBPDDelay
|
sendTsbpdDelay = request.handshake.RecvTSBPDDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
ln.config.StreamId = request.handshake.StreamId
|
ln.config.StreamId = request.handshake.StreamId
|
||||||
|
|
@ -335,7 +336,8 @@ func (ln *listener) Accept(acceptFn AcceptFunc) (Conn, ConnType, error) {
|
||||||
socketId: socketId,
|
socketId: socketId,
|
||||||
peerSocketId: request.handshake.SRTSocketId,
|
peerSocketId: request.handshake.SRTSocketId,
|
||||||
tsbpdTimeBase: uint64(request.timestamp),
|
tsbpdTimeBase: uint64(request.timestamp),
|
||||||
tsbpdDelay: uint64(tsbpdDelay) * 1000,
|
tsbpdDelay: uint64(recvTsbpdDelay) * 1000,
|
||||||
|
peerTsbpdDelay: uint64(sendTsbpdDelay) * 1000,
|
||||||
initialPacketSequenceNumber: request.handshake.InitialPacketSequenceNumber,
|
initialPacketSequenceNumber: request.handshake.InitialPacketSequenceNumber,
|
||||||
crypto: request.crypto,
|
crypto: request.crypto,
|
||||||
keyBaseEncryption: packet.EvenKeyEncrypted,
|
keyBaseEncryption: packet.EvenKeyEncrypted,
|
||||||
|
|
@ -359,6 +361,8 @@ func (ln *listener) Accept(acceptFn AcceptFunc) (Conn, ConnType, error) {
|
||||||
request.handshake.SRTFlags.REXMITFLG = true
|
request.handshake.SRTFlags.REXMITFLG = true
|
||||||
request.handshake.SRTFlags.STREAM = false
|
request.handshake.SRTFlags.STREAM = false
|
||||||
request.handshake.SRTFlags.PACKET_FILTER = false
|
request.handshake.SRTFlags.PACKET_FILTER = false
|
||||||
|
request.handshake.RecvTSBPDDelay = recvTsbpdDelay
|
||||||
|
request.handshake.SendTSBPDDelay = sendTsbpdDelay
|
||||||
|
|
||||||
ln.accept(request)
|
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
|
MsTimeStamp uint64 // The time elapsed, in milliseconds, since the SRT socket has been created
|
||||||
|
|
||||||
// Accumulated
|
// Accumulated
|
||||||
|
Accumulated StatisticsAccumulated
|
||||||
|
|
||||||
PktSent uint64 // The total number of sent DATA packets, including retransmitted packets
|
// Interval
|
||||||
PktRecv uint64 // The total number of received DATA packets, including retransmitted packets
|
Interval StatisticsInterval
|
||||||
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)
|
|
||||||
|
|
||||||
// Instantaneous
|
// Instantaneous
|
||||||
|
Instantaneous StatisticsInstantaneous
|
||||||
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
|
type StatisticsAccumulated struct {
|
||||||
MsRTT float64 // Smoothed round-trip time (SRTT), an exponentially-weighted moving average (EWMA) of an endpoint's RTT samples, in milliseconds
|
PktSent uint64 // The total number of sent DATA packets, including retransmitted packets
|
||||||
MbpsBandwidth float64 // Estimated bandwidth of the network link, in Mbps
|
PktRecv uint64 // The total number of received DATA packets, including retransmitted packets
|
||||||
ByteAvailSndBuf uint64 // The available space in the sender's buffer, in bytes
|
PktSentUnique uint64 // The total number of unique DATA packets sent by the SRT sender
|
||||||
ByteAvailRcvBuf uint64 // The available space in the receiver's buffer, in bytes
|
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.
|
||||||
MbpsMaxBW float64 // Transmission bandwidth limit, in Mbps
|
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.
|
||||||
ByteMSS uint64 // Maximum Segment Size (MSS), in bytes
|
PktRecvLoss uint64 // The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
|
||||||
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
|
PktRetrans uint64 // The total number of retransmitted packets sent by the SRT sender
|
||||||
ByteSndBuf uint64 // Instantaneous (current) value of pktSndBuf, but expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
PktRecvRetrans uint64 // The total number of retransmitted packets registered at the receiver side
|
||||||
MsSndBuf uint64 // The timespan (msec) of packets in the sender's buffer (unacknowledged packets)
|
PktSentACK uint64 // The total number of sent ACK (Acknowledgement) control packets
|
||||||
MsSndTsbPdDelay uint64 // Timestamp-based Packet Delivery Delay value of the peer
|
PktRecvACK uint64 // The total number of received ACK (Acknowledgement) control packets
|
||||||
PktRcvBuf uint64 // The number of acknowledged packets in receiver's buffer
|
PktSentNAK uint64 // The total number of sent NAK (Negative Acknowledgement) control packets
|
||||||
ByteRcvBuf uint64 // Instantaneous (current) value of pktRcvBuf, expressed in bytes, including payload and all headers (IP, TCP, SRT)
|
PktRecvNAK uint64 // The total number of received NAK (Negative Acknowledgement) control packets
|
||||||
MsRcvBuf uint64 // The timespan (msec) of acknowledged packets in the receiver's buffer
|
PktSentKM uint64 // The total number of sent KM (Key Material) control packets
|
||||||
MsRcvTsbPdDelay uint64 // Timestamp-based Packet Delivery Delay value set on the socket via SRTO_RCVLATENCY or SRTO_LATENCY
|
PktRecvKM uint64 // The total number of received KM (Key Material) control packets
|
||||||
PktReorderTolerance uint64 // Instant value of the packet reorder tolerance
|
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
|
||||||
PktRcvAvgBelatedTime uint64 // Accumulated difference between the current time and the time-to-play of a packet that is received late
|
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
|
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)
|
<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://travis-ci.org/go-playground/validator)
|
||||||
[](https://coveralls.io/github/go-playground/validator?branch=master)
|
[](https://coveralls.io/github/go-playground/validator?branch=master)
|
||||||
[](https://goreportcard.com/report/github.com/go-playground/validator)
|
[](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())
|
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 {
|
func isBoolean(fl FieldLevel) bool {
|
||||||
_, err := strconv.ParseBool(fl.Field().String())
|
switch fl.Field().Kind() {
|
||||||
return err == nil
|
case reflect.Bool:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
_, err := strconv.ParseBool(fl.Field().String())
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isDefault is the opposite of required aka hasValue
|
// 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
|
# license
|
||||||
|
|
||||||
This code is published under an MIT license. See LICENSE file for more information.
|
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"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"math/bits"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -92,7 +93,8 @@ const (
|
||||||
AVX512VNNI // AVX-512 Vector Neural Network Instructions
|
AVX512VNNI // AVX-512 Vector Neural Network Instructions
|
||||||
AVX512VP2INTERSECT // AVX-512 Intersect for D/Q
|
AVX512VP2INTERSECT // AVX-512 Intersect for D/Q
|
||||||
AVX512VPOPCNTDQ // AVX-512 Vector Population Count Doubleword and Quadword
|
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
|
BMI1 // Bit Manipulation Instruction Set 1
|
||||||
BMI2 // Bit Manipulation Instruction Set 2
|
BMI2 // Bit Manipulation Instruction Set 2
|
||||||
CETIBT // Intel CET Indirect Branch Tracking
|
CETIBT // Intel CET Indirect Branch Tracking
|
||||||
|
|
@ -101,21 +103,28 @@ const (
|
||||||
CLMUL // Carry-less Multiplication
|
CLMUL // Carry-less Multiplication
|
||||||
CLZERO // CLZERO instruction supported
|
CLZERO // CLZERO instruction supported
|
||||||
CMOV // i686 CMOV
|
CMOV // i686 CMOV
|
||||||
|
CMPSB_SCADBS_SHORT // Fast short CMPSB and SCASB
|
||||||
CMPXCHG8 // CMPXCHG8 instruction
|
CMPXCHG8 // CMPXCHG8 instruction
|
||||||
CPBOOST // Core Performance Boost
|
CPBOOST // Core Performance Boost
|
||||||
CX16 // CMPXCHG16B Instruction
|
CX16 // CMPXCHG16B Instruction
|
||||||
ENQCMD // Enqueue Command
|
ENQCMD // Enqueue Command
|
||||||
ERMS // Enhanced REP MOVSB/STOSB
|
ERMS // Enhanced REP MOVSB/STOSB
|
||||||
F16C // Half-precision floating-point conversion
|
F16C // Half-precision floating-point conversion
|
||||||
|
FLUSH_L1D // Flush L1D cache
|
||||||
FMA3 // Intel FMA 3. Does not imply AVX.
|
FMA3 // Intel FMA 3. Does not imply AVX.
|
||||||
FMA4 // Bulldozer FMA4 functions
|
FMA4 // Bulldozer FMA4 functions
|
||||||
|
FSRM // Fast Short Rep Mov
|
||||||
FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9
|
FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9
|
||||||
FXSROPT // FXSAVE/FXRSTOR optimizations
|
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
|
HLE // Hardware Lock Elision
|
||||||
|
HRESET // If set CPU supports history reset and the IA32_HRESET_ENABLE MSR
|
||||||
HTT // Hyperthreading (enabled)
|
HTT // Hyperthreading (enabled)
|
||||||
HWA // Hardware assert supported. Indicates support for MSRC001_10
|
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
|
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)
|
IBPB // Indirect Branch Restricted Speculation (IBRS) and Indirect Branch Predictor Barrier (IBPB)
|
||||||
IBS // Instruction Based Sampling (AMD)
|
IBS // Instruction Based Sampling (AMD)
|
||||||
IBSBRNTRGT // Instruction Based Sampling Feature (AMD)
|
IBSBRNTRGT // Instruction Based Sampling Feature (AMD)
|
||||||
|
|
@ -126,21 +135,30 @@ const (
|
||||||
IBSOPSAM // Instruction Based Sampling Feature (AMD)
|
IBSOPSAM // Instruction Based Sampling Feature (AMD)
|
||||||
IBSRDWROPCNT // Instruction Based Sampling Feature (AMD)
|
IBSRDWROPCNT // Instruction Based Sampling Feature (AMD)
|
||||||
IBSRIPINVALIDCHK // 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.
|
INT_WBINVD // WBINVD/WBNOINVD are interruptible.
|
||||||
INVLPGB // NVLPGB and TLBSYNC instruction supported
|
INVLPGB // NVLPGB and TLBSYNC instruction supported
|
||||||
LAHF // LAHF/SAHF in long mode
|
LAHF // LAHF/SAHF in long mode
|
||||||
|
LAM // If set, CPU supports Linear Address Masking
|
||||||
|
LBRVIRT // LBR virtualization
|
||||||
LZCNT // LZCNT instruction
|
LZCNT // LZCNT instruction
|
||||||
MCAOVERFLOW // MCA overflow recovery support.
|
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
|
MCOMMIT // MCOMMIT instruction supported
|
||||||
|
MD_CLEAR // VERW clears CPU buffers
|
||||||
MMX // standard MMX
|
MMX // standard MMX
|
||||||
MMXEXT // SSE integer functions or AMD MMX ext
|
MMXEXT // SSE integer functions or AMD MMX ext
|
||||||
MOVBE // MOVBE instruction (big-endian)
|
MOVBE // MOVBE instruction (big-endian)
|
||||||
MOVDIR64B // Move 64 Bytes as Direct Store
|
MOVDIR64B // Move 64 Bytes as Direct Store
|
||||||
MOVDIRI // Move Doubleword as Direct Store
|
MOVDIRI // Move Doubleword as Direct Store
|
||||||
|
MOVSB_ZL // Fast Zero-Length MOVSB
|
||||||
MPX // Intel MPX (Memory Protection Extensions)
|
MPX // Intel MPX (Memory Protection Extensions)
|
||||||
MSRIRC // Instruction Retired Counter MSR available
|
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
|
NX // NX (No-Execute) bit
|
||||||
OSXSAVE // XSAVE enabled by OS
|
OSXSAVE // XSAVE enabled by OS
|
||||||
|
PCONFIG // PCONFIG for Intel Multi-Key Total Memory Encryption
|
||||||
POPCNT // POPCNT instruction
|
POPCNT // POPCNT instruction
|
||||||
RDPRU // RDPRU instruction supported
|
RDPRU // RDPRU instruction supported
|
||||||
RDRAND // RDRAND instruction is available
|
RDRAND // RDRAND instruction is available
|
||||||
|
|
@ -148,11 +166,21 @@ const (
|
||||||
RDTSCP // RDTSCP Instruction
|
RDTSCP // RDTSCP Instruction
|
||||||
RTM // Restricted Transactional Memory
|
RTM // Restricted Transactional Memory
|
||||||
RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort.
|
RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort.
|
||||||
SCE // SYSENTER and SYSEXIT instructions
|
|
||||||
SERIALIZE // Serialize Instruction Execution
|
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
|
SGX // Software Guard Extensions
|
||||||
SGXLC // Software Guard Extensions Launch Control
|
SGXLC // Software Guard Extensions Launch Control
|
||||||
SHA // Intel SHA Extensions
|
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
|
SSE // SSE functions
|
||||||
SSE2 // P4 SSE functions
|
SSE2 // P4 SSE functions
|
||||||
SSE3 // Prescott SSE3 functions
|
SSE3 // Prescott SSE3 functions
|
||||||
|
|
@ -161,17 +189,38 @@ const (
|
||||||
SSE4A // AMD Barcelona microarchitecture SSE4a instructions
|
SSE4A // AMD Barcelona microarchitecture SSE4a instructions
|
||||||
SSSE3 // Conroe SSSE3 functions
|
SSSE3 // Conroe SSSE3 functions
|
||||||
STIBP // Single Thread Indirect Branch Predictors
|
STIBP // Single Thread Indirect Branch Predictors
|
||||||
|
STOSB_SHORT // Fast short STOSB
|
||||||
SUCCOR // Software uncorrectable error containment and recovery capability.
|
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
|
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
|
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
|
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
|
WAITPKG // TPAUSE, UMONITOR, UMWAIT
|
||||||
WBNOINVD // Write Back and Do Not Invalidate Cache
|
WBNOINVD // Write Back and Do Not Invalidate Cache
|
||||||
X87 // FPU
|
X87 // FPU
|
||||||
|
XGETBV1 // Supports XGETBV with ECX = 1
|
||||||
XOP // Bulldozer XOP functions
|
XOP // Bulldozer XOP functions
|
||||||
XSAVE // XSAVE, XRESTOR, XSETBV, XGETBV
|
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:
|
// ARM features:
|
||||||
AESARM // AES instructions
|
AESARM // AES instructions
|
||||||
|
|
@ -198,7 +247,6 @@ const (
|
||||||
SM3 // SM3 instructions
|
SM3 // SM3 instructions
|
||||||
SM4 // SM4 instructions
|
SM4 // SM4 instructions
|
||||||
SVE // Scalable Vector Extension
|
SVE // Scalable Vector Extension
|
||||||
|
|
||||||
// Keep it last. It automatically defines the size of []flagSet
|
// Keep it last. It automatically defines the size of []flagSet
|
||||||
lastID
|
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.
|
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
|
Family int // CPU family number
|
||||||
Model int // CPU model number
|
Model int // CPU model number
|
||||||
|
Stepping int // CPU stepping info
|
||||||
CacheLine int // Cache line size in bytes. Will be 0 if undetectable.
|
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.
|
Hz int64 // Clock speed, if known, 0 otherwise. Will attempt to contain base clock speed.
|
||||||
BoostFreq int64 // Max clock speed, if known, 0 otherwise
|
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)
|
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
|
// https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
|
||||||
var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2)
|
var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2)
|
||||||
var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3)
|
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, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE)
|
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, 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 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.
|
// X64Level returns the microarchitecture level detected on the CPU.
|
||||||
// If features are lacking or non x64 mode, 0 is returned.
|
// 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
|
return c.VendorID == v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FeatureSet returns all available features as strings.
|
||||||
func (c CPUInfo) FeatureSet() []string {
|
func (c CPUInfo) FeatureSet() []string {
|
||||||
s := make([]string, 0)
|
s := make([]string, 0, c.featureSet.nEnabled())
|
||||||
s = append(s, c.featureSet.Strings()...)
|
s = append(s, c.featureSet.Strings()...)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
@ -543,6 +603,14 @@ func (s flagSet) hasSet(other flagSet) bool {
|
||||||
return true
|
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 {
|
func flagSetWith(feat ...FeatureID) flagSet {
|
||||||
var res flagSet
|
var res flagSet
|
||||||
for _, f := range feat {
|
for _, f := range feat {
|
||||||
|
|
@ -631,7 +699,7 @@ func threadsPerCore() int {
|
||||||
if vend == AMD {
|
if vend == AMD {
|
||||||
// Workaround for AMD returning 0, assume 2 if >= Zen 2
|
// Workaround for AMD returning 0, assume 2 if >= Zen 2
|
||||||
// It will be more correct than not.
|
// It will be more correct than not.
|
||||||
fam, _ := familyModel()
|
fam, _, _ := familyModel()
|
||||||
_, _, _, d := cpuid(1)
|
_, _, _, d := cpuid(1)
|
||||||
if (d&(1<<28)) != 0 && fam >= 23 {
|
if (d&(1<<28)) != 0 && fam >= 23 {
|
||||||
return 2
|
return 2
|
||||||
|
|
@ -669,14 +737,27 @@ func logicalCores() int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func familyModel() (int, int) {
|
func familyModel() (family, model, stepping int) {
|
||||||
if maxFunctionID() < 0x1 {
|
if maxFunctionID() < 0x1 {
|
||||||
return 0, 0
|
return 0, 0, 0
|
||||||
}
|
}
|
||||||
eax, _, _, _ := cpuid(1)
|
eax, _, _, _ := cpuid(1)
|
||||||
family := ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff)
|
// If BaseFamily[3:0] is less than Fh then ExtendedFamily[7:0] is reserved and Family is equal to BaseFamily[3:0].
|
||||||
model := ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0)
|
family = int((eax >> 8) & 0xf)
|
||||||
return int(family), int(model)
|
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 {
|
func physicalCores() int {
|
||||||
|
|
@ -811,9 +892,14 @@ func (c *CPUInfo) cacheSize() {
|
||||||
c.Cache.L2 = int(((ecx >> 16) & 0xFFFF) * 1024)
|
c.Cache.L2 = int(((ecx >> 16) & 0xFFFF) * 1024)
|
||||||
|
|
||||||
// CPUID Fn8000_001D_EAX_x[N:0] Cache Properties
|
// CPUID Fn8000_001D_EAX_x[N:0] Cache Properties
|
||||||
if maxExtendedFunction() < 0x8000001D {
|
if maxExtendedFunction() < 0x8000001D || !c.Has(TOPEXT) {
|
||||||
return
|
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++ {
|
for i := uint32(0); i < math.MaxUint32; i++ {
|
||||||
eax, ebx, ecx, _ := cpuidex(0x8000001D, i)
|
eax, ebx, ecx, _ := cpuidex(0x8000001D, i)
|
||||||
|
|
||||||
|
|
@ -829,6 +915,16 @@ func (c *CPUInfo) cacheSize() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for the same value repeated.
|
||||||
|
comb := eax ^ ebx ^ ecx
|
||||||
|
if comb == last {
|
||||||
|
nSame++
|
||||||
|
if nSame == 100 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last = comb
|
||||||
|
|
||||||
switch level {
|
switch level {
|
||||||
case 1:
|
case 1:
|
||||||
switch typ {
|
switch typ {
|
||||||
|
|
@ -913,14 +1009,13 @@ func support() flagSet {
|
||||||
if mfi < 0x1 {
|
if mfi < 0x1 {
|
||||||
return fs
|
return fs
|
||||||
}
|
}
|
||||||
family, model := familyModel()
|
family, model, _ := familyModel()
|
||||||
|
|
||||||
_, _, c, d := cpuid(1)
|
_, _, c, d := cpuid(1)
|
||||||
fs.setIf((d&(1<<0)) != 0, X87)
|
fs.setIf((d&(1<<0)) != 0, X87)
|
||||||
fs.setIf((d&(1<<8)) != 0, CMPXCHG8)
|
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<<15)) != 0, CMOV)
|
||||||
fs.setIf((d&(1<<22)) != 0, MMXEXT)
|
|
||||||
fs.setIf((d&(1<<23)) != 0, MMX)
|
fs.setIf((d&(1<<23)) != 0, MMX)
|
||||||
fs.setIf((d&(1<<24)) != 0, FXSR)
|
fs.setIf((d&(1<<24)) != 0, FXSR)
|
||||||
fs.setIf((d&(1<<25)) != 0, FXSROPT)
|
fs.setIf((d&(1<<25)) != 0, FXSROPT)
|
||||||
|
|
@ -928,9 +1023,9 @@ func support() flagSet {
|
||||||
fs.setIf((d&(1<<26)) != 0, SSE2)
|
fs.setIf((d&(1<<26)) != 0, SSE2)
|
||||||
fs.setIf((c&1) != 0, SSE3)
|
fs.setIf((c&1) != 0, SSE3)
|
||||||
fs.setIf((c&(1<<5)) != 0, VMX)
|
fs.setIf((c&(1<<5)) != 0, VMX)
|
||||||
fs.setIf((c&0x00000200) != 0, SSSE3)
|
fs.setIf((c&(1<<9)) != 0, SSSE3)
|
||||||
fs.setIf((c&0x00080000) != 0, SSE4)
|
fs.setIf((c&(1<<19)) != 0, SSE4)
|
||||||
fs.setIf((c&0x00100000) != 0, SSE42)
|
fs.setIf((c&(1<<20)) != 0, SSE42)
|
||||||
fs.setIf((c&(1<<25)) != 0, AESNI)
|
fs.setIf((c&(1<<25)) != 0, AESNI)
|
||||||
fs.setIf((c&(1<<1)) != 0, CLMUL)
|
fs.setIf((c&(1<<1)) != 0, CLMUL)
|
||||||
fs.setIf(c&(1<<22) != 0, MOVBE)
|
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.
|
// Check AVX2, AVX2 requires OS support, but BMI1/2 don't.
|
||||||
if mfi >= 7 {
|
if mfi >= 7 {
|
||||||
_, ebx, ecx, edx := cpuidex(7, 0)
|
_, ebx, ecx, edx := cpuidex(7, 0)
|
||||||
eax1, _, _, _ := cpuidex(7, 1)
|
|
||||||
if fs.inSet(AVX) && (ebx&0x00000020) != 0 {
|
if fs.inSet(AVX) && (ebx&0x00000020) != 0 {
|
||||||
fs.set(AVX2)
|
fs.set(AVX2)
|
||||||
}
|
}
|
||||||
|
|
@ -993,21 +1087,45 @@ func support() flagSet {
|
||||||
fs.setIf(ebx&(1<<18) != 0, RDSEED)
|
fs.setIf(ebx&(1<<18) != 0, RDSEED)
|
||||||
fs.setIf(ebx&(1<<19) != 0, ADX)
|
fs.setIf(ebx&(1<<19) != 0, ADX)
|
||||||
fs.setIf(ebx&(1<<29) != 0, SHA)
|
fs.setIf(ebx&(1<<29) != 0, SHA)
|
||||||
|
|
||||||
// CPUID.(EAX=7, ECX=0).ECX
|
// CPUID.(EAX=7, ECX=0).ECX
|
||||||
fs.setIf(ecx&(1<<5) != 0, WAITPKG)
|
fs.setIf(ecx&(1<<5) != 0, WAITPKG)
|
||||||
fs.setIf(ecx&(1<<7) != 0, CETSS)
|
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<<25) != 0, CLDEMOTE)
|
||||||
fs.setIf(ecx&(1<<27) != 0, MOVDIRI)
|
fs.setIf(ecx&(1<<27) != 0, MOVDIRI)
|
||||||
fs.setIf(ecx&(1<<28) != 0, MOVDIR64B)
|
fs.setIf(ecx&(1<<28) != 0, MOVDIR64B)
|
||||||
fs.setIf(ecx&(1<<29) != 0, ENQCMD)
|
fs.setIf(ecx&(1<<29) != 0, ENQCMD)
|
||||||
fs.setIf(ecx&(1<<30) != 0, SGXLC)
|
fs.setIf(ecx&(1<<30) != 0, SGXLC)
|
||||||
|
|
||||||
// CPUID.(EAX=7, ECX=0).EDX
|
// 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<<11) != 0, RTM_ALWAYS_ABORT)
|
||||||
fs.setIf(edx&(1<<14) != 0, SERIALIZE)
|
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<<16) != 0, TSXLDTRK)
|
||||||
|
fs.setIf(edx&(1<<18) != 0, PCONFIG)
|
||||||
fs.setIf(edx&(1<<20) != 0, CETIBT)
|
fs.setIf(edx&(1<<20) != 0, CETIBT)
|
||||||
fs.setIf(edx&(1<<26) != 0, IBPB)
|
fs.setIf(edx&(1<<26) != 0, IBPB)
|
||||||
fs.setIf(edx&(1<<27) != 0, STIBP)
|
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
|
// Only detect AVX-512 features if XGETBV is supported
|
||||||
if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) {
|
if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) {
|
||||||
|
|
@ -1033,9 +1151,6 @@ func support() flagSet {
|
||||||
// ecx
|
// ecx
|
||||||
fs.setIf(ecx&(1<<1) != 0, AVX512VBMI)
|
fs.setIf(ecx&(1<<1) != 0, AVX512VBMI)
|
||||||
fs.setIf(ecx&(1<<6) != 0, AVX512VBMI2)
|
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<<11) != 0, AVX512VNNI)
|
||||||
fs.setIf(ecx&(1<<12) != 0, AVX512BITALG)
|
fs.setIf(ecx&(1<<12) != 0, AVX512BITALG)
|
||||||
fs.setIf(ecx&(1<<14) != 0, AVX512VPOPCNTDQ)
|
fs.setIf(ecx&(1<<14) != 0, AVX512VPOPCNTDQ)
|
||||||
|
|
@ -1049,29 +1164,63 @@ func support() flagSet {
|
||||||
fs.setIf(eax1&(1<<5) != 0, AVX512BF16)
|
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 {
|
if maxExtendedFunction() >= 0x80000001 {
|
||||||
_, _, c, d := cpuid(0x80000001)
|
_, _, c, d := cpuid(0x80000001)
|
||||||
if (c & (1 << 5)) != 0 {
|
if (c & (1 << 5)) != 0 {
|
||||||
fs.set(LZCNT)
|
fs.set(LZCNT)
|
||||||
fs.set(POPCNT)
|
fs.set(POPCNT)
|
||||||
}
|
}
|
||||||
|
// ECX
|
||||||
fs.setIf((c&(1<<0)) != 0, LAHF)
|
fs.setIf((c&(1<<0)) != 0, LAHF)
|
||||||
fs.setIf((c&(1<<10)) != 0, IBS)
|
fs.setIf((c&(1<<2)) != 0, SVM)
|
||||||
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<<6)) != 0, SSE4A)
|
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<<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<<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
|
/* XOP and FMA4 use the AVX instruction coding scheme, so they can't be
|
||||||
* used unless the OS has AVX support. */
|
* used unless the OS has AVX support. */
|
||||||
if fs.inSet(AVX) {
|
if fs.inSet(AVX) {
|
||||||
fs.setIf((c&0x00000800) != 0, XOP)
|
fs.setIf((c&(1<<11)) != 0, XOP)
|
||||||
fs.setIf((c&0x00010000) != 0, FMA4)
|
fs.setIf((c&(1<<16)) != 0, FMA4)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1094,6 +1243,20 @@ func support() flagSet {
|
||||||
fs.setIf((b&(1<<0)) != 0, CLZERO)
|
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) {
|
if maxExtendedFunction() >= 0x8000001b && fs.inSet(IBS) {
|
||||||
eax, _, _, _ := cpuid(0x8000001b)
|
eax, _, _, _ := cpuid(0x8000001b)
|
||||||
fs.setIf((eax>>0)&1 == 1, IBSFFV)
|
fs.setIf((eax>>0)&1 == 1, IBSFFV)
|
||||||
|
|
@ -1106,6 +1269,24 @@ func support() flagSet {
|
||||||
fs.setIf((eax>>7)&1 == 1, IBSRIPINVALIDCHK)
|
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
|
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.maxExFunc = maxExtendedFunction()
|
||||||
c.BrandName = brandName()
|
c.BrandName = brandName()
|
||||||
c.CacheLine = cacheLine()
|
c.CacheLine = cacheLine()
|
||||||
c.Family, c.Model = familyModel()
|
c.Family, c.Model, c.Stepping = familyModel()
|
||||||
c.featureSet = support()
|
c.featureSet = support()
|
||||||
c.SGX = hasSGX(c.featureSet.inSet(SGX), c.featureSet.inSet(SGXLC))
|
c.SGX = hasSGX(c.featureSet.inSet(SGX), c.featureSet.inSet(SGXLC))
|
||||||
c.ThreadsPerCore = threadsPerCore()
|
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[AVX512VP2INTERSECT-24]
|
||||||
_ = x[AVX512VPOPCNTDQ-25]
|
_ = x[AVX512VPOPCNTDQ-25]
|
||||||
_ = x[AVXSLOW-26]
|
_ = x[AVXSLOW-26]
|
||||||
_ = x[BMI1-27]
|
_ = x[AVXVNNI-27]
|
||||||
_ = x[BMI2-28]
|
_ = x[BMI1-28]
|
||||||
_ = x[CETIBT-29]
|
_ = x[BMI2-29]
|
||||||
_ = x[CETSS-30]
|
_ = x[CETIBT-30]
|
||||||
_ = x[CLDEMOTE-31]
|
_ = x[CETSS-31]
|
||||||
_ = x[CLMUL-32]
|
_ = x[CLDEMOTE-32]
|
||||||
_ = x[CLZERO-33]
|
_ = x[CLMUL-33]
|
||||||
_ = x[CMOV-34]
|
_ = x[CLZERO-34]
|
||||||
_ = x[CMPXCHG8-35]
|
_ = x[CMOV-35]
|
||||||
_ = x[CPBOOST-36]
|
_ = x[CMPSB_SCADBS_SHORT-36]
|
||||||
_ = x[CX16-37]
|
_ = x[CMPXCHG8-37]
|
||||||
_ = x[ENQCMD-38]
|
_ = x[CPBOOST-38]
|
||||||
_ = x[ERMS-39]
|
_ = x[CX16-39]
|
||||||
_ = x[F16C-40]
|
_ = x[ENQCMD-40]
|
||||||
_ = x[FMA3-41]
|
_ = x[ERMS-41]
|
||||||
_ = x[FMA4-42]
|
_ = x[F16C-42]
|
||||||
_ = x[FXSR-43]
|
_ = x[FLUSH_L1D-43]
|
||||||
_ = x[FXSROPT-44]
|
_ = x[FMA3-44]
|
||||||
_ = x[GFNI-45]
|
_ = x[FMA4-45]
|
||||||
_ = x[HLE-46]
|
_ = x[FSRM-46]
|
||||||
_ = x[HTT-47]
|
_ = x[FXSR-47]
|
||||||
_ = x[HWA-48]
|
_ = x[FXSROPT-48]
|
||||||
_ = x[HYPERVISOR-49]
|
_ = x[GFNI-49]
|
||||||
_ = x[IBPB-50]
|
_ = x[HLE-50]
|
||||||
_ = x[IBS-51]
|
_ = x[HRESET-51]
|
||||||
_ = x[IBSBRNTRGT-52]
|
_ = x[HTT-52]
|
||||||
_ = x[IBSFETCHSAM-53]
|
_ = x[HWA-53]
|
||||||
_ = x[IBSFFV-54]
|
_ = x[HYBRID_CPU-54]
|
||||||
_ = x[IBSOPCNT-55]
|
_ = x[HYPERVISOR-55]
|
||||||
_ = x[IBSOPCNTEXT-56]
|
_ = x[IA32_ARCH_CAP-56]
|
||||||
_ = x[IBSOPSAM-57]
|
_ = x[IA32_CORE_CAP-57]
|
||||||
_ = x[IBSRDWROPCNT-58]
|
_ = x[IBPB-58]
|
||||||
_ = x[IBSRIPINVALIDCHK-59]
|
_ = x[IBS-59]
|
||||||
_ = x[INT_WBINVD-60]
|
_ = x[IBSBRNTRGT-60]
|
||||||
_ = x[INVLPGB-61]
|
_ = x[IBSFETCHSAM-61]
|
||||||
_ = x[LAHF-62]
|
_ = x[IBSFFV-62]
|
||||||
_ = x[LZCNT-63]
|
_ = x[IBSOPCNT-63]
|
||||||
_ = x[MCAOVERFLOW-64]
|
_ = x[IBSOPCNTEXT-64]
|
||||||
_ = x[MCOMMIT-65]
|
_ = x[IBSOPSAM-65]
|
||||||
_ = x[MMX-66]
|
_ = x[IBSRDWROPCNT-66]
|
||||||
_ = x[MMXEXT-67]
|
_ = x[IBSRIPINVALIDCHK-67]
|
||||||
_ = x[MOVBE-68]
|
_ = x[IBS_PREVENTHOST-68]
|
||||||
_ = x[MOVDIR64B-69]
|
_ = x[INT_WBINVD-69]
|
||||||
_ = x[MOVDIRI-70]
|
_ = x[INVLPGB-70]
|
||||||
_ = x[MPX-71]
|
_ = x[LAHF-71]
|
||||||
_ = x[MSRIRC-72]
|
_ = x[LAM-72]
|
||||||
_ = x[NX-73]
|
_ = x[LBRVIRT-73]
|
||||||
_ = x[OSXSAVE-74]
|
_ = x[LZCNT-74]
|
||||||
_ = x[POPCNT-75]
|
_ = x[MCAOVERFLOW-75]
|
||||||
_ = x[RDPRU-76]
|
_ = x[MCDT_NO-76]
|
||||||
_ = x[RDRAND-77]
|
_ = x[MCOMMIT-77]
|
||||||
_ = x[RDSEED-78]
|
_ = x[MD_CLEAR-78]
|
||||||
_ = x[RDTSCP-79]
|
_ = x[MMX-79]
|
||||||
_ = x[RTM-80]
|
_ = x[MMXEXT-80]
|
||||||
_ = x[RTM_ALWAYS_ABORT-81]
|
_ = x[MOVBE-81]
|
||||||
_ = x[SCE-82]
|
_ = x[MOVDIR64B-82]
|
||||||
_ = x[SERIALIZE-83]
|
_ = x[MOVDIRI-83]
|
||||||
_ = x[SGX-84]
|
_ = x[MOVSB_ZL-84]
|
||||||
_ = x[SGXLC-85]
|
_ = x[MPX-85]
|
||||||
_ = x[SHA-86]
|
_ = x[MSRIRC-86]
|
||||||
_ = x[SSE-87]
|
_ = x[MSR_PAGEFLUSH-87]
|
||||||
_ = x[SSE2-88]
|
_ = x[NRIPS-88]
|
||||||
_ = x[SSE3-89]
|
_ = x[NX-89]
|
||||||
_ = x[SSE4-90]
|
_ = x[OSXSAVE-90]
|
||||||
_ = x[SSE42-91]
|
_ = x[PCONFIG-91]
|
||||||
_ = x[SSE4A-92]
|
_ = x[POPCNT-92]
|
||||||
_ = x[SSSE3-93]
|
_ = x[RDPRU-93]
|
||||||
_ = x[STIBP-94]
|
_ = x[RDRAND-94]
|
||||||
_ = x[SUCCOR-95]
|
_ = x[RDSEED-95]
|
||||||
_ = x[TBM-96]
|
_ = x[RDTSCP-96]
|
||||||
_ = x[TSXLDTRK-97]
|
_ = x[RTM-97]
|
||||||
_ = x[VAES-98]
|
_ = x[RTM_ALWAYS_ABORT-98]
|
||||||
_ = x[VMX-99]
|
_ = x[SERIALIZE-99]
|
||||||
_ = x[VPCLMULQDQ-100]
|
_ = x[SEV-100]
|
||||||
_ = x[WAITPKG-101]
|
_ = x[SEV_64BIT-101]
|
||||||
_ = x[WBNOINVD-102]
|
_ = x[SEV_ALTERNATIVE-102]
|
||||||
_ = x[X87-103]
|
_ = x[SEV_DEBUGSWAP-103]
|
||||||
_ = x[XOP-104]
|
_ = x[SEV_ES-104]
|
||||||
_ = x[XSAVE-105]
|
_ = x[SEV_RESTRICTED-105]
|
||||||
_ = x[AESARM-106]
|
_ = x[SEV_SNP-106]
|
||||||
_ = x[ARMCPUID-107]
|
_ = x[SGX-107]
|
||||||
_ = x[ASIMD-108]
|
_ = x[SGXLC-108]
|
||||||
_ = x[ASIMDDP-109]
|
_ = x[SHA-109]
|
||||||
_ = x[ASIMDHP-110]
|
_ = x[SME-110]
|
||||||
_ = x[ASIMDRDM-111]
|
_ = x[SME_COHERENT-111]
|
||||||
_ = x[ATOMICS-112]
|
_ = x[SPEC_CTRL_SSBD-112]
|
||||||
_ = x[CRC32-113]
|
_ = x[SRBDS_CTRL-113]
|
||||||
_ = x[DCPOP-114]
|
_ = x[SSE-114]
|
||||||
_ = x[EVTSTRM-115]
|
_ = x[SSE2-115]
|
||||||
_ = x[FCMA-116]
|
_ = x[SSE3-116]
|
||||||
_ = x[FP-117]
|
_ = x[SSE4-117]
|
||||||
_ = x[FPHP-118]
|
_ = x[SSE42-118]
|
||||||
_ = x[GPA-119]
|
_ = x[SSE4A-119]
|
||||||
_ = x[JSCVT-120]
|
_ = x[SSSE3-120]
|
||||||
_ = x[LRCPC-121]
|
_ = x[STIBP-121]
|
||||||
_ = x[PMULL-122]
|
_ = x[STOSB_SHORT-122]
|
||||||
_ = x[SHA1-123]
|
_ = x[SUCCOR-123]
|
||||||
_ = x[SHA2-124]
|
_ = x[SVM-124]
|
||||||
_ = x[SHA3-125]
|
_ = x[SVMDA-125]
|
||||||
_ = x[SHA512-126]
|
_ = x[SVMFBASID-126]
|
||||||
_ = x[SM3-127]
|
_ = x[SVML-127]
|
||||||
_ = x[SM4-128]
|
_ = x[SVMNP-128]
|
||||||
_ = x[SVE-129]
|
_ = x[SVMPF-129]
|
||||||
_ = x[lastID-130]
|
_ = 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]
|
_ = 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 {
|
func (i FeatureID) String() string {
|
||||||
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {
|
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
|
package cpuid
|
||||||
|
|
||||||
import "runtime"
|
import (
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
func detectOS(c *CPUInfo) bool {
|
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
|
// 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
|
// to detect their supported state dynamically. Assume the CPU features that
|
||||||
// Apple Silicon M1 supports to be available as a minimal set of features
|
// Apple Silicon M1 supports to be available as a minimal set of features
|
||||||
// to all Go programs running on darwin/arm64.
|
// to all Go programs running on darwin/arm64.
|
||||||
// TODO: Add more if we know them.
|
// TODO: Add more if we know them.
|
||||||
c.featureSet.setIf(runtime.GOOS != "ios", AESARM, PMULL, SHA1, SHA2)
|
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
|
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
|
# 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
|
## v4.9.0 - 2022-09-04
|
||||||
|
|
||||||
**Security**
|
**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
|
## 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).
|
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:
|
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
|
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.
|
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 returns the `Logger` instance.
|
||||||
Logger() Logger
|
Logger() Logger
|
||||||
|
|
||||||
// Set the logger
|
// SetLogger Set the logger
|
||||||
SetLogger(l Logger)
|
SetLogger(l Logger)
|
||||||
|
|
||||||
// Echo returns the `Echo` instance.
|
// 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 defines a function to skip middleware.
|
||||||
Skipper Skipper
|
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{"*"}.
|
// 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"`
|
AllowOrigins []string `yaml:"allow_origins"`
|
||||||
|
|
||||||
// AllowOriginFunc is a custom function to validate the origin. It takes the
|
// 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
|
// 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
|
// an error is returned, it is returned by the handler. If this option is
|
||||||
// set, AllowOrigins is ignored.
|
// 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.
|
// Optional.
|
||||||
AllowOriginFunc func(origin string) (bool, error) `yaml:"allow_origin_func"`
|
AllowOriginFunc func(origin string) (bool, error) `yaml:"allow_origin_func"`
|
||||||
|
|
||||||
// AllowMethods defines a list methods allowed when accessing the resource.
|
// AllowMethods determines the value of the Access-Control-Allow-Methods
|
||||||
// This is used in response to a preflight request.
|
// 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.
|
// 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.
|
// 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"`
|
AllowMethods []string `yaml:"allow_methods"`
|
||||||
|
|
||||||
// AllowHeaders defines a list of request headers that can be used when
|
// AllowHeaders determines the value of the Access-Control-Allow-Headers
|
||||||
// making the actual request. This is in response to a preflight request.
|
// 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{}.
|
// 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"`
|
AllowHeaders []string `yaml:"allow_headers"`
|
||||||
|
|
||||||
// AllowCredentials indicates whether or not the response to the request
|
// AllowCredentials determines the value of the
|
||||||
// can be exposed when the credentials flag is true. When used as part of
|
// Access-Control-Allow-Credentials response header. This header indicates
|
||||||
// a response to a preflight request, this indicates whether or not the
|
// whether or not the response to the request can be exposed when the
|
||||||
// actual request can be made using credentials.
|
// credentials mode (Request.credentials) is true. When used as part of a
|
||||||
// Optional. Default value false.
|
// 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 = *`.
|
// 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"`
|
AllowCredentials bool `yaml:"allow_credentials"`
|
||||||
|
|
||||||
// ExposeHeaders defines a whitelist headers that clients are allowed to
|
// ExposeHeaders determines the value of Access-Control-Expose-Headers, which
|
||||||
// access.
|
// defines a list of headers that clients are allowed to access.
|
||||||
// Optional. Default value []string{}.
|
//
|
||||||
|
// 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"`
|
ExposeHeaders []string `yaml:"expose_headers"`
|
||||||
|
|
||||||
// MaxAge indicates how long (in seconds) the results of a preflight request
|
// MaxAge determines the value of the Access-Control-Max-Age response header.
|
||||||
// can be cached.
|
// This header indicates how long (in seconds) the results of a preflight
|
||||||
// Optional. Default value 0.
|
// 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"`
|
MaxAge int `yaml:"max_age"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -69,13 +108,22 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// CORS returns a Cross-Origin Resource Sharing (CORS) middleware.
|
// 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 {
|
func CORS() echo.MiddlewareFunc {
|
||||||
return CORSWithConfig(DefaultCORSConfig)
|
return CORSWithConfig(DefaultCORSConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CORSWithConfig returns a CORS middleware with config.
|
// CORSWithConfig returns a CORS middleware with config.
|
||||||
// See: `CORS()`.
|
// See: [CORS].
|
||||||
func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
|
||||||
// Defaults
|
// Defaults
|
||||||
if config.Skipper == nil {
|
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{}
|
Bytes struct{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// binary units (IEC 60027)
|
||||||
const (
|
const (
|
||||||
_ = 1.0 << (10 * iota) // ignore first value by assigning to blank identifier
|
_ = 1.0 << (10 * iota) // ignore first value by assigning to blank identifier
|
||||||
KB
|
KiB
|
||||||
MB
|
MiB
|
||||||
GB
|
GiB
|
||||||
TB
|
TiB
|
||||||
PB
|
PiB
|
||||||
EB
|
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 (
|
var (
|
||||||
pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]B?|B?)$`)
|
patternBinary = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]iB?)$`)
|
||||||
global = New()
|
patternDecimal = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)\s?([KMGTPE]B?|B?)$`)
|
||||||
|
global = New()
|
||||||
)
|
)
|
||||||
|
|
||||||
// New creates a Bytes instance.
|
// New creates a Bytes instance.
|
||||||
|
|
@ -32,44 +44,97 @@ func New() *Bytes {
|
||||||
return &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.
|
// 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 := ""
|
multiple := ""
|
||||||
value := float64(b)
|
val := float64(value)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case b >= EB:
|
case value >= EiB:
|
||||||
value /= EB
|
val /= EiB
|
||||||
multiple = "EB"
|
multiple = "EiB"
|
||||||
case b >= PB:
|
case value >= PiB:
|
||||||
value /= PB
|
val /= PiB
|
||||||
multiple = "PB"
|
multiple = "PiB"
|
||||||
case b >= TB:
|
case value >= TiB:
|
||||||
value /= TB
|
val /= TiB
|
||||||
multiple = "TB"
|
multiple = "TiB"
|
||||||
case b >= GB:
|
case value >= GiB:
|
||||||
value /= GB
|
val /= GiB
|
||||||
multiple = "GB"
|
multiple = "GiB"
|
||||||
case b >= MB:
|
case value >= MiB:
|
||||||
value /= MB
|
val /= MiB
|
||||||
multiple = "MB"
|
multiple = "MiB"
|
||||||
case b >= KB:
|
case value >= KiB:
|
||||||
value /= KB
|
val /= KiB
|
||||||
multiple = "KB"
|
multiple = "KiB"
|
||||||
case b == 0:
|
case value == 0:
|
||||||
return "0"
|
return "0"
|
||||||
default:
|
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.
|
// Parse parses human readable bytes string to bytes integer.
|
||||||
// For example, 6GB (6G is also valid) will return 6442450944.
|
// For example, 6GiB (6Gi is also valid) will return 6442450944, and
|
||||||
func (*Bytes) Parse(value string) (i int64, err error) {
|
// 6GB (6G is also valid) will return 6000000000.
|
||||||
parts := pattern.FindStringSubmatch(value)
|
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 {
|
if len(parts) < 3 {
|
||||||
return 0, fmt.Errorf("error parsing value=%s", value)
|
return 0, fmt.Errorf("error parsing value=%s", value)
|
||||||
}
|
}
|
||||||
|
|
@ -81,8 +146,38 @@ func (*Bytes) Parse(value string) (i int64, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch multiple {
|
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:
|
default:
|
||||||
return int64(bytes), nil
|
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":
|
case "K", "KB":
|
||||||
return int64(bytes * KB), nil
|
return int64(bytes * KB), nil
|
||||||
case "M", "MB":
|
case "M", "MB":
|
||||||
|
|
@ -95,15 +190,27 @@ func (*Bytes) Parse(value string) (i int64, err error) {
|
||||||
return int64(bytes * PB), nil
|
return int64(bytes * PB), nil
|
||||||
case "E", "EB":
|
case "E", "EB":
|
||||||
return int64(bytes * EB), nil
|
return int64(bytes * EB), nil
|
||||||
|
default:
|
||||||
|
return int64(bytes), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format wraps global Bytes's Format function.
|
// Format wraps global Bytes's Format function.
|
||||||
func Format(b int64) string {
|
func Format(value int64) string {
|
||||||
return global.Format(b)
|
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.
|
// Parse wraps global Bytes's Parse function.
|
||||||
func Parse(val string) (int64, error) {
|
func Parse(value string) (int64, error) {
|
||||||
return global.Parse(val)
|
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 {
|
if err == nil {
|
||||||
s := buf.String()
|
s := buf.String()
|
||||||
i := buf.Len() - 1
|
i := buf.Len() - 1
|
||||||
if s[i] == '}' {
|
if i >= 0 && s[i] == '}' {
|
||||||
// JSON header
|
// JSON header
|
||||||
buf.Truncate(i)
|
buf.Truncate(i)
|
||||||
buf.WriteByte(',')
|
buf.WriteByte(',')
|
||||||
|
|
@ -404,7 +404,9 @@ func (l *Logger) log(level Lvl, format string, args ...interface{}) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Text header
|
// Text header
|
||||||
buf.WriteByte(' ')
|
if len(s) > 0 {
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
buf.WriteString(message)
|
buf.WriteString(message)
|
||||||
}
|
}
|
||||||
buf.WriteByte('\n')
|
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 {
|
if ua, ok := c.LocalAddr().(*net.UnixAddr); ok {
|
||||||
return ua.Net == "unixgram"
|
return ua.Net == "unixgram" || ua.Net == "unixpacket"
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
@ -280,7 +280,7 @@ func (co *Conn) ReadMsg() (*Msg, error) {
|
||||||
}
|
}
|
||||||
if t := m.IsTsig(); t != nil {
|
if t := m.IsTsig(); t != nil {
|
||||||
// Need to work on the original message p, as that was used to calculate the tsig.
|
// 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
|
return m, err
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +358,7 @@ func (co *Conn) WriteMsg(m *Msg) (err error) {
|
||||||
var out []byte
|
var out []byte
|
||||||
if t := m.IsTsig(); t != nil {
|
if t := m.IsTsig(); t != nil {
|
||||||
// Set tsigRequestMAC for the next read, although only used in zone transfers.
|
// 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 {
|
} else {
|
||||||
out, err = m.Pack()
|
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
|
wasDot = false
|
||||||
case '.':
|
case '.':
|
||||||
|
if i == 0 && len(s) > 1 {
|
||||||
|
// leading dots are not legal except for the root zone
|
||||||
|
return labels, false
|
||||||
|
}
|
||||||
|
|
||||||
if wasDot {
|
if wasDot {
|
||||||
// two dots back to back is not legal
|
// two dots back to back is not legal
|
||||||
return labels, false
|
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.
|
// 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{
|
var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||||
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
|
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
|
||||||
DSA: crypto.SHA1,
|
DSA: crypto.SHA1,
|
||||||
|
|
@ -74,7 +77,7 @@ var AlgorithmToHash = map[uint8]crypto.Hash{
|
||||||
ECDSAP256SHA256: crypto.SHA256,
|
ECDSAP256SHA256: crypto.SHA256,
|
||||||
ECDSAP384SHA384: crypto.SHA384,
|
ECDSAP384SHA384: crypto.SHA384,
|
||||||
RSASHA512: crypto.SHA512,
|
RSASHA512: crypto.SHA512,
|
||||||
ED25519: crypto.Hash(0),
|
ED25519: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
// DNSSEC hashing algorithm codes.
|
// DNSSEC hashing algorithm codes.
|
||||||
|
|
@ -137,12 +140,12 @@ func (k *DNSKEY) KeyTag() uint16 {
|
||||||
var keytag int
|
var keytag int
|
||||||
switch k.Algorithm {
|
switch k.Algorithm {
|
||||||
case RSAMD5:
|
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.
|
// 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))
|
modulus, _ := fromBase64([]byte(k.PublicKey))
|
||||||
if len(modulus) > 1 {
|
if len(modulus) > 1 {
|
||||||
x := binary.BigEndian.Uint16(modulus[len(modulus)-2:])
|
x := binary.BigEndian.Uint16(modulus[len(modulus)-3:])
|
||||||
keytag = int(x)
|
keytag = int(x)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -296,35 +299,20 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, ok := AlgorithmToHash[rr.Algorithm]
|
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return ErrAlg
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch rr.Algorithm {
|
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:
|
case RSAMD5, DSA, DSANSEC3SHA1:
|
||||||
// See RFC 6944.
|
// See RFC 6944.
|
||||||
return ErrAlg
|
return ErrAlg
|
||||||
default:
|
default:
|
||||||
h := hash.New()
|
|
||||||
h.Write(signdata)
|
h.Write(signdata)
|
||||||
h.Write(wire)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +329,7 @@ func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch alg {
|
switch alg {
|
||||||
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512:
|
case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, ED25519:
|
||||||
return signature, nil
|
return signature, nil
|
||||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||||
ecdsaSignature := &struct {
|
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 := intToBytes(ecdsaSignature.R, intlen)
|
||||||
signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
|
signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...)
|
||||||
return signature, nil
|
return signature, nil
|
||||||
case ED25519:
|
|
||||||
return signature, nil
|
|
||||||
default:
|
default:
|
||||||
return nil, ErrAlg
|
return nil, ErrAlg
|
||||||
}
|
}
|
||||||
|
|
@ -437,9 +423,9 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||||
// remove the domain name and assume its ours?
|
// remove the domain name and assume its ours?
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, ok := AlgorithmToHash[rr.Algorithm]
|
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return ErrAlg
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch rr.Algorithm {
|
switch rr.Algorithm {
|
||||||
|
|
@ -450,10 +436,9 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
|
||||||
return ErrKey
|
return ErrKey
|
||||||
}
|
}
|
||||||
|
|
||||||
h := hash.New()
|
|
||||||
h.Write(signeddata)
|
h.Write(signeddata)
|
||||||
h.Write(wire)
|
h.Write(wire)
|
||||||
return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf)
|
return rsa.VerifyPKCS1v15(pubkey, cryptohash, h.Sum(nil), sigbuf)
|
||||||
|
|
||||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||||
pubkey := k.publicKeyECDSA()
|
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])
|
r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2])
|
||||||
s := 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(signeddata)
|
||||||
h.Write(wire)
|
h.Write(wire)
|
||||||
if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
|
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 {
|
type EDNS0_EXPIRE struct {
|
||||||
Code uint16 // Always EDNS0EXPIRE
|
Code uint16 // Always EDNS0EXPIRE
|
||||||
Expire uint32
|
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.
|
// Option implements the EDNS0 interface.
|
||||||
func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
|
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, e.Empty} }
|
||||||
func (e *EDNS0_EXPIRE) copy() EDNS0 { return &EDNS0_EXPIRE{e.Code, e.Expire} }
|
|
||||||
|
|
||||||
func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
||||||
|
if e.Empty {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
binary.BigEndian.PutUint32(b, e.Expire)
|
binary.BigEndian.PutUint32(b, e.Expire)
|
||||||
return b, nil
|
return b, nil
|
||||||
|
|
@ -600,15 +603,24 @@ func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
|
||||||
func (e *EDNS0_EXPIRE) unpack(b []byte) error {
|
func (e *EDNS0_EXPIRE) unpack(b []byte) error {
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
// zero-length EXPIRE query, see RFC 7314 Section 2
|
// zero-length EXPIRE query, see RFC 7314 Section 2
|
||||||
|
e.Empty = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(b) < 4 {
|
if len(b) < 4 {
|
||||||
return ErrBuf
|
return ErrBuf
|
||||||
}
|
}
|
||||||
e.Expire = binary.BigEndian.Uint32(b)
|
e.Expire = binary.BigEndian.Uint32(b)
|
||||||
|
e.Empty = false
|
||||||
return nil
|
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
|
// The EDNS0_LOCAL option is used for local/experimental purposes. The option
|
||||||
// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
|
// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
|
||||||
// (RFC6891), although any unassigned code can actually be used. The content of
|
// (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
|
wasDot = false
|
||||||
case '.':
|
case '.':
|
||||||
|
if i == 0 && len(s) > 1 {
|
||||||
|
// leading dots are not legal except for the root zone
|
||||||
|
return len(msg), ErrRdata
|
||||||
|
}
|
||||||
|
|
||||||
if wasDot {
|
if wasDot {
|
||||||
// two dots back to back is not legal
|
// two dots back to back is not legal
|
||||||
return len(msg), ErrRdata
|
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
|
length, window, lastwindow := 0, 0, -1
|
||||||
for off < len(msg) {
|
for off < len(msg) {
|
||||||
if off+2 > 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])
|
window = int(msg[off])
|
||||||
length = int(msg[off+1])
|
length = int(msg[off+1])
|
||||||
|
|
@ -484,17 +484,17 @@ func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
|
||||||
if window <= lastwindow {
|
if window <= lastwindow {
|
||||||
// RFC 4034: Blocks are present in the NSEC RR RDATA in
|
// RFC 4034: Blocks are present in the NSEC RR RDATA in
|
||||||
// increasing numerical order.
|
// 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 {
|
if length == 0 {
|
||||||
// RFC 4034: Blocks with no types present MUST NOT be included.
|
// 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 {
|
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) {
|
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
|
// 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 {
|
if len(bitmap) == 0 {
|
||||||
return off, nil
|
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
|
var lastwindow, lastlength uint16
|
||||||
for _, t := range bitmap {
|
for _, t := range bitmap {
|
||||||
window := t / 256
|
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
|
w.tsigStatus = nil
|
||||||
if w.tsigProvider != nil {
|
if w.tsigProvider != nil {
|
||||||
if t := req.IsTsig(); t != 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.tsigTimersOnly = false
|
||||||
w.tsigRequestMAC = t.MAC
|
w.tsigRequestMAC = t.MAC
|
||||||
}
|
}
|
||||||
|
|
@ -728,7 +728,7 @@ func (w *response) WriteMsg(m *Msg) (err error) {
|
||||||
var data []byte
|
var data []byte
|
||||||
if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check)
|
if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check)
|
||||||
if t := m.IsTsig(); t != nil {
|
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 {
|
if err != nil {
|
||||||
return err
|
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 (
|
import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"crypto/ed25519"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -38,18 +39,17 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
|
||||||
}
|
}
|
||||||
buf = buf[:off:cap(buf)]
|
buf = buf[:off:cap(buf)]
|
||||||
|
|
||||||
hash, ok := AlgorithmToHash[rr.Algorithm]
|
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return nil, ErrAlg
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher := hash.New()
|
|
||||||
// Write SIG rdata
|
// 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
|
// 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -82,20 +82,10 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||||
return ErrKey
|
return ErrKey
|
||||||
}
|
}
|
||||||
|
|
||||||
var hash crypto.Hash
|
h, cryptohash, err := hashFromAlgorithm(rr.Algorithm)
|
||||||
switch rr.Algorithm {
|
if err != nil {
|
||||||
case RSASHA1:
|
return err
|
||||||
hash = crypto.SHA1
|
|
||||||
case RSASHA256, ECDSAP256SHA256:
|
|
||||||
hash = crypto.SHA256
|
|
||||||
case ECDSAP384SHA384:
|
|
||||||
hash = crypto.SHA384
|
|
||||||
case RSASHA512:
|
|
||||||
hash = crypto.SHA512
|
|
||||||
default:
|
|
||||||
return ErrAlg
|
|
||||||
}
|
}
|
||||||
hasher := hash.New()
|
|
||||||
|
|
||||||
buflen := len(buf)
|
buflen := len(buf)
|
||||||
qdc := binary.BigEndian.Uint16(buf[4:])
|
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:])
|
auc := binary.BigEndian.Uint16(buf[8:])
|
||||||
adc := binary.BigEndian.Uint16(buf[10:])
|
adc := binary.BigEndian.Uint16(buf[10:])
|
||||||
offset := headerSize
|
offset := headerSize
|
||||||
var err error
|
|
||||||
for i := uint16(0); i < qdc && offset < buflen; i++ {
|
for i := uint16(0); i < qdc && offset < buflen; i++ {
|
||||||
_, offset, err = UnpackDomainName(buf, offset)
|
_, offset, err = UnpackDomainName(buf, offset)
|
||||||
if err != nil {
|
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"}
|
return &Error{err: "signer name doesn't match key name"}
|
||||||
}
|
}
|
||||||
sigend := offset
|
sigend := offset
|
||||||
hasher.Write(buf[sigstart:sigend])
|
h.Write(buf[sigstart:sigend])
|
||||||
hasher.Write(buf[:10])
|
h.Write(buf[:10])
|
||||||
hasher.Write([]byte{
|
h.Write([]byte{
|
||||||
byte((adc - 1) << 8),
|
byte((adc - 1) << 8),
|
||||||
byte(adc - 1),
|
byte(adc - 1),
|
||||||
})
|
})
|
||||||
hasher.Write(buf[12:bodyend])
|
h.Write(buf[12:bodyend])
|
||||||
|
|
||||||
hashed := hasher.Sum(nil)
|
hashed := h.Sum(nil)
|
||||||
sig := buf[sigend:]
|
sig := buf[sigend:]
|
||||||
switch k.Algorithm {
|
switch k.Algorithm {
|
||||||
case RSASHA1, RSASHA256, RSASHA512:
|
case RSASHA1, RSASHA256, RSASHA512:
|
||||||
pk := k.publicKeyRSA()
|
pk := k.publicKeyRSA()
|
||||||
if pk != nil {
|
if pk != nil {
|
||||||
return rsa.VerifyPKCS1v15(pk, hash, hashed, sig)
|
return rsa.VerifyPKCS1v15(pk, cryptohash, hashed, sig)
|
||||||
}
|
}
|
||||||
case ECDSAP256SHA256, ECDSAP384SHA384:
|
case ECDSAP256SHA256, ECDSAP384SHA384:
|
||||||
pk := k.publicKeyECDSA()
|
pk := k.publicKeyECDSA()
|
||||||
|
|
@ -192,6 +181,14 @@ func (rr *SIG) Verify(k *KEY, buf []byte) error {
|
||||||
}
|
}
|
||||||
return ErrSig
|
return ErrSig
|
||||||
}
|
}
|
||||||
|
case ED25519:
|
||||||
|
pk := k.publicKeyED25519()
|
||||||
|
if pk != nil {
|
||||||
|
if ed25519.Verify(pk, hashed, sig) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ErrSig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ErrKeyAlg
|
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"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -13,16 +14,18 @@ import (
|
||||||
// SVCBKey is the type of the keys used in the SVCB RR.
|
// SVCBKey is the type of the keys used in the SVCB RR.
|
||||||
type SVCBKey uint16
|
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 (
|
const (
|
||||||
SVCB_MANDATORY SVCBKey = 0
|
SVCB_MANDATORY SVCBKey = iota
|
||||||
SVCB_ALPN SVCBKey = 1
|
SVCB_ALPN
|
||||||
SVCB_NO_DEFAULT_ALPN SVCBKey = 2
|
SVCB_NO_DEFAULT_ALPN
|
||||||
SVCB_PORT SVCBKey = 3
|
SVCB_PORT
|
||||||
SVCB_IPV4HINT SVCBKey = 4
|
SVCB_IPV4HINT
|
||||||
SVCB_ECHCONFIG SVCBKey = 5
|
SVCB_ECHCONFIG
|
||||||
SVCB_IPV6HINT SVCBKey = 6
|
SVCB_IPV6HINT
|
||||||
svcb_RESERVED SVCBKey = 65535
|
SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9
|
||||||
|
|
||||||
|
svcb_RESERVED SVCBKey = 65535
|
||||||
)
|
)
|
||||||
|
|
||||||
var svcbKeyToStringMap = map[SVCBKey]string{
|
var svcbKeyToStringMap = map[SVCBKey]string{
|
||||||
|
|
@ -31,8 +34,9 @@ var svcbKeyToStringMap = map[SVCBKey]string{
|
||||||
SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
|
SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
|
||||||
SVCB_PORT: "port",
|
SVCB_PORT: "port",
|
||||||
SVCB_IPV4HINT: "ipv4hint",
|
SVCB_IPV4HINT: "ipv4hint",
|
||||||
SVCB_ECHCONFIG: "echconfig",
|
SVCB_ECHCONFIG: "ech",
|
||||||
SVCB_IPV6HINT: "ipv6hint",
|
SVCB_IPV6HINT: "ipv6hint",
|
||||||
|
SVCB_DOHPATH: "dohpath",
|
||||||
}
|
}
|
||||||
|
|
||||||
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
|
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
|
||||||
|
|
@ -167,10 +171,14 @@ func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
|
||||||
}
|
}
|
||||||
l, _ = c.Next()
|
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
|
rr.Value = xs
|
||||||
if rr.Priority == 0 && len(xs) > 0 {
|
|
||||||
return &ParseError{l.token, "SVCB aliasform can't have values", l}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,6 +199,8 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
||||||
return new(SVCBECHConfig)
|
return new(SVCBECHConfig)
|
||||||
case SVCB_IPV6HINT:
|
case SVCB_IPV6HINT:
|
||||||
return new(SVCBIPv6Hint)
|
return new(SVCBIPv6Hint)
|
||||||
|
case SVCB_DOHPATH:
|
||||||
|
return new(SVCBDoHPath)
|
||||||
case svcb_RESERVED:
|
case svcb_RESERVED:
|
||||||
return nil
|
return nil
|
||||||
default:
|
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 {
|
type SVCB struct {
|
||||||
Hdr RR_Header
|
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"`
|
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.
|
// 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.
|
// 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 {
|
type HTTPS struct {
|
||||||
SVCB
|
SVCB
|
||||||
}
|
}
|
||||||
|
|
@ -235,15 +253,29 @@ type SVCBKeyValue interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SVCBMandatory pair adds to required keys that must be interpreted for the RR
|
// 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:
|
// Basic use pattern for creating a mandatory option:
|
||||||
//
|
//
|
||||||
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
||||||
// e := new(dns.SVCBMandatory)
|
// e := new(dns.SVCBMandatory)
|
||||||
// e.Code = []uint16{65403}
|
// e.Code = []uint16{dns.SVCB_ALPN}
|
||||||
// s.Value = append(s.Value, e)
|
// s.Value = append(s.Value, e)
|
||||||
|
// t := new(dns.SVCBAlpn)
|
||||||
|
// t.Alpn = []string{"xmpp-client"}
|
||||||
|
// s.Value = append(s.Value, t)
|
||||||
type SVCBMandatory struct {
|
type SVCBMandatory struct {
|
||||||
Code []SVCBKey // Must not include mandatory
|
Code []SVCBKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
|
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.
|
// 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
|
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
|
||||||
// Basic use pattern for creating an alpn option:
|
// 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}
|
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||||
// e := new(dns.SVCBAlpn)
|
// e := new(dns.SVCBAlpn)
|
||||||
// e.Alpn = []string{"h2", "http/1.1"}
|
// e.Alpn = []string{"h2", "http/1.1"}
|
||||||
// h.Value = append(o.Value, e)
|
// h.Value = append(h.Value, e)
|
||||||
type SVCBAlpn struct {
|
type SVCBAlpn struct {
|
||||||
Alpn []string
|
Alpn []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
||||||
func (s *SVCBAlpn) String() string { return strings.Join(s.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) {
|
func (s *SVCBAlpn) pack() ([]byte, error) {
|
||||||
// Liberally estimate the size of an alpn as 10 octets
|
// 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 {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -370,9 +487,13 @@ func (s *SVCBAlpn) copy() SVCBKeyValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
|
// 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:
|
// Basic use pattern for creating a no-default-alpn option:
|
||||||
//
|
//
|
||||||
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
|
// 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)
|
// e := new(dns.SVCBNoDefaultAlpn)
|
||||||
// s.Value = append(s.Value, e)
|
// s.Value = append(s.Value, e)
|
||||||
type SVCBNoDefaultAlpn struct{}
|
type SVCBNoDefaultAlpn struct{}
|
||||||
|
|
@ -385,14 +506,14 @@ func (*SVCBNoDefaultAlpn) len() int { return 0 }
|
||||||
|
|
||||||
func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
|
func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
|
||||||
if len(b) != 0 {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*SVCBNoDefaultAlpn) parse(b string) error {
|
func (*SVCBNoDefaultAlpn) parse(b string) error {
|
||||||
if b != "" {
|
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
|
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].
|
// 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 := new(dns.HTTPS)
|
||||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
// 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, ...}
|
// e.ECH = []byte{0xfe, 0x08, ...}
|
||||||
// h.Value = append(h.Value, e)
|
// h.Value = append(h.Value, e)
|
||||||
type SVCBECHConfig struct {
|
type SVCBECHConfig struct {
|
||||||
ECH []byte
|
ECH []byte // Specifically ECHConfigList including the redundant length prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG }
|
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 {
|
func (s *SVCBECHConfig) parse(b string) error {
|
||||||
x, err := fromBase64([]byte(b))
|
x, err := fromBase64([]byte(b))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("dns: svcbechconfig: bad base64 echconfig")
|
return errors.New("dns: svcbech: bad base64 ech")
|
||||||
}
|
}
|
||||||
s.ECH = x
|
s.ECH = x
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -618,9 +739,6 @@ func (s *SVCBIPv6Hint) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SVCBIPv6Hint) parse(b string) error {
|
func (s *SVCBIPv6Hint) parse(b string) error {
|
||||||
if strings.Contains(b, ".") {
|
|
||||||
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
|
|
||||||
}
|
|
||||||
str := strings.Split(b, ",")
|
str := strings.Split(b, ",")
|
||||||
dst := make([]net.IP, len(str))
|
dst := make([]net.IP, len(str))
|
||||||
for i, e := range str {
|
for i, e := range str {
|
||||||
|
|
@ -628,6 +746,9 @@ func (s *SVCBIPv6Hint) parse(b string) error {
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return errors.New("dns: svcbipv6hint: bad ip")
|
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
|
dst[i] = ip
|
||||||
}
|
}
|
||||||
s.Hint = dst
|
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
|
// SVCBLocal pair is intended for experimental/private use. The key is recommended
|
||||||
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
||||||
// Basic use pattern for creating a keyNNNNN option:
|
// 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) 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) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil }
|
||||||
func (s *SVCBLocal) len() int { return len(s.Data) }
|
func (s *SVCBLocal) len() int { return len(s.Data) }
|
||||||
|
|
||||||
|
|
@ -669,50 +839,10 @@ func (s *SVCBLocal) unpack(b []byte) error {
|
||||||
return nil
|
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 {
|
func (s *SVCBLocal) parse(b string) error {
|
||||||
data := make([]byte, 0, len(b))
|
data, err := svcbParseParam(b)
|
||||||
for i := 0; i < len(b); {
|
if err != nil {
|
||||||
if b[i] != '\\' {
|
return fmt.Errorf("dns: svcblocal: svcb private/experimental key %w", err)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
s.Data = data
|
s.Data = data
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -753,3 +883,53 @@ func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
|
||||||
}
|
}
|
||||||
return true
|
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.
|
// TsigGenerate fills out the TSIG record attached to the message.
|
||||||
// The message should contain
|
// The message should contain a "stub" TSIG RR with the algorithm, key name
|
||||||
// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
|
// (owner name of the RR), time fudge (defaults to 300 seconds) and the current
|
||||||
// time fudge (defaults to 300 seconds) and the current time
|
// time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for
|
||||||
// The TSIG MAC is saved in that Tsig RR.
|
// the first time requestMAC should be set to the empty string and timersOnly to
|
||||||
// When TsigGenerate is called for the first time requestMAC is set to the empty string and
|
// false.
|
||||||
// timersOnly is false.
|
|
||||||
// If something goes wrong an error is returned, otherwise it is nil.
|
|
||||||
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
|
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 {
|
if m.IsTsig() == nil {
|
||||||
panic("dns: TSIG not last RR in additional")
|
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
|
return mbuf, t.MAC, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TsigVerify verifies the TSIG on a message.
|
// TsigVerify verifies the TSIG on a message. If the signature does not
|
||||||
// If the signature does not validate err contains the
|
// validate the returned error contains the cause. If the signature is OK, the
|
||||||
// error, otherwise it is nil.
|
// error is nil.
|
||||||
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
|
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
|
||||||
return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
|
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()))
|
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"
|
import "fmt"
|
||||||
|
|
||||||
// Version is current version of this library.
|
// 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.
|
// v holds the version of this library.
|
||||||
type v struct {
|
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 {
|
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.
|
// 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
|
t.tsigRequestMAC = ts.MAC
|
||||||
}
|
}
|
||||||
return m, err
|
return m, err
|
||||||
|
|
@ -247,7 +247,7 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
|
||||||
func (t *Transfer) WriteMsg(m *Msg) (err error) {
|
func (t *Transfer) WriteMsg(m *Msg) (err error) {
|
||||||
var out []byte
|
var out []byte
|
||||||
if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
|
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 {
|
} else {
|
||||||
out, err = m.Pack()
|
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.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// source: metrics.proto
|
// source: io/prometheus/client/metrics.proto
|
||||||
|
|
||||||
package io_prometheus_client
|
package io_prometheus_client
|
||||||
|
|
||||||
|
|
@ -24,11 +24,18 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||||
type MetricType int32
|
type MetricType int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MetricType_COUNTER MetricType = 0
|
// COUNTER must use the Metric field "counter".
|
||||||
MetricType_GAUGE MetricType = 1
|
MetricType_COUNTER MetricType = 0
|
||||||
MetricType_SUMMARY MetricType = 2
|
// GAUGE must use the Metric field "gauge".
|
||||||
MetricType_UNTYPED MetricType = 3
|
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
|
MetricType_HISTOGRAM MetricType = 4
|
||||||
|
// GAUGE_HISTOGRAM must use the Metric field "histogram".
|
||||||
|
MetricType_GAUGE_HISTOGRAM MetricType = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
var MetricType_name = map[int32]string{
|
var MetricType_name = map[int32]string{
|
||||||
|
|
@ -37,14 +44,16 @@ var MetricType_name = map[int32]string{
|
||||||
2: "SUMMARY",
|
2: "SUMMARY",
|
||||||
3: "UNTYPED",
|
3: "UNTYPED",
|
||||||
4: "HISTOGRAM",
|
4: "HISTOGRAM",
|
||||||
|
5: "GAUGE_HISTOGRAM",
|
||||||
}
|
}
|
||||||
|
|
||||||
var MetricType_value = map[string]int32{
|
var MetricType_value = map[string]int32{
|
||||||
"COUNTER": 0,
|
"COUNTER": 0,
|
||||||
"GAUGE": 1,
|
"GAUGE": 1,
|
||||||
"SUMMARY": 2,
|
"SUMMARY": 2,
|
||||||
"UNTYPED": 3,
|
"UNTYPED": 3,
|
||||||
"HISTOGRAM": 4,
|
"HISTOGRAM": 4,
|
||||||
|
"GAUGE_HISTOGRAM": 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x MetricType) Enum() *MetricType {
|
func (x MetricType) Enum() *MetricType {
|
||||||
|
|
@ -67,7 +76,7 @@ func (x *MetricType) UnmarshalJSON(data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MetricType) EnumDescriptor() ([]byte, []int) {
|
func (MetricType) EnumDescriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{0}
|
return fileDescriptor_d1e5ddb18987a258, []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LabelPair struct {
|
type LabelPair struct {
|
||||||
|
|
@ -82,7 +91,7 @@ func (m *LabelPair) Reset() { *m = LabelPair{} }
|
||||||
func (m *LabelPair) String() string { return proto.CompactTextString(m) }
|
func (m *LabelPair) String() string { return proto.CompactTextString(m) }
|
||||||
func (*LabelPair) ProtoMessage() {}
|
func (*LabelPair) ProtoMessage() {}
|
||||||
func (*LabelPair) Descriptor() ([]byte, []int) {
|
func (*LabelPair) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{0}
|
return fileDescriptor_d1e5ddb18987a258, []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LabelPair) XXX_Unmarshal(b []byte) error {
|
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 (m *Gauge) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Gauge) ProtoMessage() {}
|
func (*Gauge) ProtoMessage() {}
|
||||||
func (*Gauge) Descriptor() ([]byte, []int) {
|
func (*Gauge) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{1}
|
return fileDescriptor_d1e5ddb18987a258, []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Gauge) XXX_Unmarshal(b []byte) error {
|
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 (m *Counter) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Counter) ProtoMessage() {}
|
func (*Counter) ProtoMessage() {}
|
||||||
func (*Counter) Descriptor() ([]byte, []int) {
|
func (*Counter) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{2}
|
return fileDescriptor_d1e5ddb18987a258, []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Counter) XXX_Unmarshal(b []byte) error {
|
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 (m *Quantile) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Quantile) ProtoMessage() {}
|
func (*Quantile) ProtoMessage() {}
|
||||||
func (*Quantile) Descriptor() ([]byte, []int) {
|
func (*Quantile) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{3}
|
return fileDescriptor_d1e5ddb18987a258, []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Quantile) XXX_Unmarshal(b []byte) error {
|
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 (m *Summary) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Summary) ProtoMessage() {}
|
func (*Summary) ProtoMessage() {}
|
||||||
func (*Summary) Descriptor() ([]byte, []int) {
|
func (*Summary) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{4}
|
return fileDescriptor_d1e5ddb18987a258, []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Summary) XXX_Unmarshal(b []byte) error {
|
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 (m *Untyped) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Untyped) ProtoMessage() {}
|
func (*Untyped) ProtoMessage() {}
|
||||||
func (*Untyped) Descriptor() ([]byte, []int) {
|
func (*Untyped) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{5}
|
return fileDescriptor_d1e5ddb18987a258, []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Untyped) XXX_Unmarshal(b []byte) error {
|
func (m *Untyped) XXX_Unmarshal(b []byte) error {
|
||||||
|
|
@ -345,9 +354,34 @@ func (m *Untyped) GetValue() float64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Histogram struct {
|
type Histogram struct {
|
||||||
SampleCount *uint64 `protobuf:"varint,1,opt,name=sample_count,json=sampleCount" json:"sample_count,omitempty"`
|
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"`
|
SampleCountFloat *float64 `protobuf:"fixed64,4,opt,name=sample_count_float,json=sampleCountFloat" json:"sample_count_float,omitempty"`
|
||||||
Bucket []*Bucket `protobuf:"bytes,3,rep,name=bucket" json:"bucket,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_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `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 (m *Histogram) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Histogram) ProtoMessage() {}
|
func (*Histogram) ProtoMessage() {}
|
||||||
func (*Histogram) Descriptor() ([]byte, []int) {
|
func (*Histogram) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{6}
|
return fileDescriptor_d1e5ddb18987a258, []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Histogram) XXX_Unmarshal(b []byte) error {
|
func (m *Histogram) XXX_Unmarshal(b []byte) error {
|
||||||
|
|
@ -385,6 +419,13 @@ func (m *Histogram) GetSampleCount() uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Histogram) GetSampleCountFloat() float64 {
|
||||||
|
if m != nil && m.SampleCountFloat != nil {
|
||||||
|
return *m.SampleCountFloat
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Histogram) GetSampleSum() float64 {
|
func (m *Histogram) GetSampleSum() float64 {
|
||||||
if m != nil && m.SampleSum != nil {
|
if m != nil && m.SampleSum != nil {
|
||||||
return *m.SampleSum
|
return *m.SampleSum
|
||||||
|
|
@ -399,8 +440,81 @@ func (m *Histogram) GetBucket() []*Bucket {
|
||||||
return nil
|
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 {
|
type Bucket struct {
|
||||||
CumulativeCount *uint64 `protobuf:"varint,1,opt,name=cumulative_count,json=cumulativeCount" json:"cumulative_count,omitempty"`
|
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"`
|
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"`
|
Exemplar *Exemplar `protobuf:"bytes,3,opt,name=exemplar" json:"exemplar,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
|
@ -412,7 +526,7 @@ func (m *Bucket) Reset() { *m = Bucket{} }
|
||||||
func (m *Bucket) String() string { return proto.CompactTextString(m) }
|
func (m *Bucket) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Bucket) ProtoMessage() {}
|
func (*Bucket) ProtoMessage() {}
|
||||||
func (*Bucket) Descriptor() ([]byte, []int) {
|
func (*Bucket) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{7}
|
return fileDescriptor_d1e5ddb18987a258, []int{7}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Bucket) XXX_Unmarshal(b []byte) error {
|
func (m *Bucket) XXX_Unmarshal(b []byte) error {
|
||||||
|
|
@ -440,6 +554,13 @@ func (m *Bucket) GetCumulativeCount() uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Bucket) GetCumulativeCountFloat() float64 {
|
||||||
|
if m != nil && m.CumulativeCountFloat != nil {
|
||||||
|
return *m.CumulativeCountFloat
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Bucket) GetUpperBound() float64 {
|
func (m *Bucket) GetUpperBound() float64 {
|
||||||
if m != nil && m.UpperBound != nil {
|
if m != nil && m.UpperBound != nil {
|
||||||
return *m.UpperBound
|
return *m.UpperBound
|
||||||
|
|
@ -454,6 +575,59 @@ func (m *Bucket) GetExemplar() *Exemplar {
|
||||||
return nil
|
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 {
|
type Exemplar struct {
|
||||||
Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
|
Label []*LabelPair `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
|
||||||
Value *float64 `protobuf:"fixed64,2,opt,name=value" json:"value,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 (m *Exemplar) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Exemplar) ProtoMessage() {}
|
func (*Exemplar) ProtoMessage() {}
|
||||||
func (*Exemplar) Descriptor() ([]byte, []int) {
|
func (*Exemplar) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{8}
|
return fileDescriptor_d1e5ddb18987a258, []int{9}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Exemplar) XXX_Unmarshal(b []byte) error {
|
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 (m *Metric) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Metric) ProtoMessage() {}
|
func (*Metric) ProtoMessage() {}
|
||||||
func (*Metric) Descriptor() ([]byte, []int) {
|
func (*Metric) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{9}
|
return fileDescriptor_d1e5ddb18987a258, []int{10}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Metric) XXX_Unmarshal(b []byte) error {
|
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 (m *MetricFamily) String() string { return proto.CompactTextString(m) }
|
||||||
func (*MetricFamily) ProtoMessage() {}
|
func (*MetricFamily) ProtoMessage() {}
|
||||||
func (*MetricFamily) Descriptor() ([]byte, []int) {
|
func (*MetricFamily) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6039342a2ba47b72, []int{10}
|
return fileDescriptor_d1e5ddb18987a258, []int{11}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MetricFamily) XXX_Unmarshal(b []byte) error {
|
func (m *MetricFamily) XXX_Unmarshal(b []byte) error {
|
||||||
|
|
@ -669,55 +843,72 @@ func init() {
|
||||||
proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped")
|
proto.RegisterType((*Untyped)(nil), "io.prometheus.client.Untyped")
|
||||||
proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram")
|
proto.RegisterType((*Histogram)(nil), "io.prometheus.client.Histogram")
|
||||||
proto.RegisterType((*Bucket)(nil), "io.prometheus.client.Bucket")
|
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((*Exemplar)(nil), "io.prometheus.client.Exemplar")
|
||||||
proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric")
|
proto.RegisterType((*Metric)(nil), "io.prometheus.client.Metric")
|
||||||
proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily")
|
proto.RegisterType((*MetricFamily)(nil), "io.prometheus.client.MetricFamily")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72) }
|
func init() {
|
||||||
|
proto.RegisterFile("io/prometheus/client/metrics.proto", fileDescriptor_d1e5ddb18987a258)
|
||||||
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,
|
var fileDescriptor_d1e5ddb18987a258 = []byte{
|
||||||
0x14, 0xfd, 0xdc, 0x38, 0x3f, 0xbe, 0x69, 0x3f, 0xa2, 0x51, 0x17, 0x56, 0xa1, 0x24, 0x78, 0x55,
|
// 896 bytes of a gzipped FileDescriptorProto
|
||||||
0x58, 0x38, 0xa2, 0x6a, 0x05, 0x2a, 0xb0, 0x68, 0x4b, 0x48, 0x91, 0x48, 0x5b, 0x26, 0xc9, 0xa2,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x8e, 0xdb, 0x44,
|
||||||
0xb0, 0x88, 0x1c, 0x77, 0x70, 0x2c, 0x3c, 0xb1, 0xb1, 0x67, 0x2a, 0xb2, 0x66, 0xc1, 0x16, 0x5e,
|
0x18, 0xc5, 0x9b, 0x5f, 0x7f, 0xd9, 0x6c, 0xd3, 0x61, 0x55, 0x59, 0x0b, 0xcb, 0x06, 0x4b, 0x48,
|
||||||
0x81, 0x17, 0x05, 0xcd, 0x8f, 0x6d, 0x2a, 0xb9, 0x95, 0x40, 0xec, 0x66, 0xee, 0x3d, 0xe7, 0xfa,
|
0x0b, 0x42, 0x8e, 0x40, 0x5b, 0x81, 0x0a, 0x5c, 0xec, 0xb6, 0xe9, 0x16, 0x89, 0xb4, 0x65, 0x92,
|
||||||
0xcc, 0xf8, 0x9c, 0x81, 0x0d, 0x4a, 0x58, 0x1a, 0xfa, 0x99, 0x9b, 0xa4, 0x31, 0x8b, 0xd1, 0x66,
|
0x5c, 0x14, 0x2e, 0xac, 0x49, 0x32, 0xeb, 0x58, 0x78, 0x3c, 0xc6, 0x1e, 0x57, 0x2c, 0x2f, 0xc0,
|
||||||
0x18, 0x8b, 0x15, 0x25, 0x6c, 0x41, 0x78, 0xe6, 0xfa, 0x51, 0x48, 0x96, 0x6c, 0xab, 0x1b, 0xc4,
|
0x35, 0xaf, 0xc0, 0xc3, 0xf0, 0x22, 0x3c, 0x08, 0x68, 0xfe, 0xec, 0xdd, 0xe2, 0x94, 0xd2, 0x3b,
|
||||||
0x71, 0x10, 0x91, 0xbe, 0xc4, 0xcc, 0xf9, 0x87, 0x3e, 0x0b, 0x29, 0xc9, 0x98, 0x47, 0x13, 0x45,
|
0x7f, 0x67, 0xce, 0xf7, 0xcd, 0x39, 0xe3, 0xc9, 0x71, 0xc0, 0x8f, 0xf9, 0x24, 0xcb, 0x39, 0xa3,
|
||||||
0x73, 0xf6, 0xc1, 0x7a, 0xe3, 0xcd, 0x49, 0x74, 0xee, 0x85, 0x29, 0x42, 0x60, 0x2e, 0x3d, 0x4a,
|
0x62, 0x4b, 0xcb, 0x62, 0xb2, 0x4e, 0x62, 0x9a, 0x8a, 0x09, 0xa3, 0x22, 0x8f, 0xd7, 0x45, 0x90,
|
||||||
0x6c, 0xa3, 0x67, 0xec, 0x58, 0x58, 0xae, 0xd1, 0x26, 0xd4, 0xaf, 0xbc, 0x88, 0x13, 0x7b, 0x4d,
|
0xe5, 0x5c, 0x70, 0x74, 0x18, 0xf3, 0xa0, 0xe6, 0x04, 0x9a, 0x73, 0x74, 0x12, 0x71, 0x1e, 0x25,
|
||||||
0x16, 0xd5, 0xc6, 0xd9, 0x86, 0xfa, 0xd0, 0xe3, 0xc1, 0x6f, 0x6d, 0xc1, 0x31, 0xf2, 0xf6, 0x7b,
|
0x74, 0xa2, 0x38, 0xab, 0xf2, 0x6a, 0x22, 0x62, 0x46, 0x0b, 0x41, 0x58, 0xa6, 0xdb, 0xfc, 0xfb,
|
||||||
0x68, 0x1e, 0xc7, 0x7c, 0xc9, 0x48, 0x5a, 0x0d, 0x40, 0x07, 0xd0, 0x22, 0x9f, 0x09, 0x4d, 0x22,
|
0xe0, 0x7e, 0x47, 0x56, 0x34, 0x79, 0x4e, 0xe2, 0x1c, 0x21, 0x68, 0xa7, 0x84, 0x51, 0xcf, 0x19,
|
||||||
0x2f, 0x95, 0x83, 0xdb, 0xbb, 0xf7, 0xdd, 0xaa, 0x03, 0xb8, 0x03, 0x8d, 0xc2, 0x05, 0xde, 0x79,
|
0x3b, 0xa7, 0x2e, 0x56, 0xcf, 0xe8, 0x10, 0x3a, 0x2f, 0x49, 0x52, 0x52, 0x6f, 0x4f, 0x81, 0xba,
|
||||||
0x0e, 0xad, 0xb7, 0xdc, 0x5b, 0xb2, 0x30, 0x22, 0x68, 0x0b, 0x5a, 0x9f, 0xf4, 0x5a, 0x7f, 0xa0,
|
0xf0, 0x8f, 0xa1, 0x73, 0x49, 0xca, 0xe8, 0xc6, 0xb2, 0xec, 0x71, 0xec, 0xf2, 0x8f, 0xd0, 0x7b,
|
||||||
0xd8, 0x5f, 0x57, 0x5e, 0x48, 0xfb, 0x6a, 0x40, 0x73, 0xcc, 0x29, 0xf5, 0xd2, 0x15, 0x7a, 0x00,
|
0xc8, 0xcb, 0x54, 0xd0, 0xbc, 0x99, 0x80, 0x1e, 0x40, 0x9f, 0xfe, 0x42, 0x59, 0x96, 0x90, 0x5c,
|
||||||
0xeb, 0x99, 0x47, 0x93, 0x88, 0xcc, 0x7c, 0xa1, 0x56, 0x4e, 0x30, 0x71, 0x5b, 0xd5, 0xe4, 0x01,
|
0x0d, 0x1e, 0x7c, 0xfe, 0x41, 0xd0, 0x64, 0x20, 0x98, 0x1a, 0x16, 0xae, 0xf8, 0xfe, 0xd7, 0xd0,
|
||||||
0xd0, 0x36, 0x80, 0x86, 0x64, 0x9c, 0xea, 0x49, 0x96, 0xaa, 0x8c, 0x39, 0x15, 0xe7, 0x28, 0xbe,
|
0xff, 0xbe, 0x24, 0xa9, 0x88, 0x13, 0x8a, 0x8e, 0xa0, 0xff, 0xb3, 0x79, 0x36, 0x1b, 0x54, 0xf5,
|
||||||
0x5f, 0xeb, 0xd5, 0x6e, 0x3e, 0x47, 0xae, 0xb8, 0xd4, 0xe7, 0x74, 0xa1, 0x39, 0x5d, 0xb2, 0x55,
|
0x6d, 0xe5, 0x95, 0xb4, 0xdf, 0x1c, 0xe8, 0xcd, 0x4b, 0xc6, 0x48, 0x7e, 0x8d, 0x3e, 0x84, 0xfd,
|
||||||
0x42, 0x2e, 0x6f, 0xb8, 0xc5, 0x2f, 0x06, 0x58, 0x27, 0x61, 0xc6, 0xe2, 0x20, 0xf5, 0xe8, 0x3f,
|
0x82, 0xb0, 0x2c, 0xa1, 0xe1, 0x5a, 0xaa, 0x55, 0x13, 0xda, 0x78, 0xa0, 0x31, 0x65, 0x00, 0x1d,
|
||||||
0x10, 0xbb, 0x07, 0x8d, 0x39, 0xf7, 0x3f, 0x12, 0xa6, 0xa5, 0xde, 0xab, 0x96, 0x7a, 0x24, 0x31,
|
0x03, 0x18, 0x4a, 0x51, 0x32, 0x33, 0xc9, 0xd5, 0xc8, 0xbc, 0x64, 0xd2, 0x47, 0xb5, 0x7f, 0x6b,
|
||||||
0x58, 0x63, 0x9d, 0x6f, 0x06, 0x34, 0x54, 0x09, 0x3d, 0x84, 0x8e, 0xcf, 0x29, 0x8f, 0x3c, 0x16,
|
0xdc, 0xda, 0xed, 0xc3, 0x2a, 0xae, 0xf5, 0xf9, 0x27, 0xd0, 0x5b, 0xa6, 0xe2, 0x3a, 0xa3, 0x9b,
|
||||||
0x5e, 0x5d, 0x97, 0x71, 0xa7, 0xac, 0x2b, 0x29, 0x5d, 0x68, 0xf3, 0x24, 0x21, 0xe9, 0x6c, 0x1e,
|
0x1d, 0xa7, 0xf8, 0x57, 0x1b, 0xdc, 0x27, 0x71, 0x21, 0x78, 0x94, 0x13, 0xf6, 0x26, 0x62, 0x3f,
|
||||||
0xf3, 0xe5, 0xa5, 0xd6, 0x02, 0xb2, 0x74, 0x24, 0x2a, 0xd7, 0x1c, 0x50, 0xfb, 0x43, 0x07, 0x7c,
|
0x05, 0x74, 0x93, 0x12, 0x5e, 0x25, 0x9c, 0x08, 0xaf, 0xad, 0x66, 0x8e, 0x6e, 0x10, 0x1f, 0x4b,
|
||||||
0x37, 0xa0, 0x95, 0x97, 0xd1, 0x3e, 0xd4, 0x23, 0xe1, 0x60, 0xdb, 0x90, 0x87, 0xea, 0x56, 0x4f,
|
0xfc, 0xbf, 0xac, 0x9d, 0x41, 0x77, 0x55, 0xae, 0x7f, 0xa2, 0xc2, 0x18, 0x7b, 0xbf, 0xd9, 0xd8,
|
||||||
0x29, 0x4c, 0x8e, 0x15, 0xba, 0xda, 0x1d, 0xe8, 0x29, 0x58, 0x45, 0x42, 0xb4, 0xac, 0x2d, 0x57,
|
0x85, 0xe2, 0x60, 0xc3, 0x45, 0xf7, 0xa0, 0x5b, 0xac, 0xb7, 0x94, 0x11, 0xaf, 0x33, 0x76, 0x4e,
|
||||||
0x65, 0xc8, 0xcd, 0x33, 0xe4, 0x4e, 0x72, 0x04, 0x2e, 0xc1, 0xce, 0xcf, 0x35, 0x68, 0x8c, 0x64,
|
0xef, 0x62, 0x53, 0xa1, 0x8f, 0xe0, 0xe0, 0x57, 0x9a, 0xf3, 0x50, 0x6c, 0x73, 0x5a, 0x6c, 0x79,
|
||||||
0x22, 0xff, 0x56, 0xd1, 0x63, 0xa8, 0x07, 0x22, 0x53, 0x3a, 0x10, 0x77, 0xab, 0x69, 0x32, 0x76,
|
0xb2, 0xf1, 0xba, 0x6a, 0xc3, 0xa1, 0x44, 0x17, 0x16, 0x94, 0x9a, 0x14, 0x4d, 0x5b, 0xec, 0x29,
|
||||||
0x58, 0x21, 0xd1, 0x13, 0x68, 0xfa, 0x2a, 0x67, 0x5a, 0xec, 0x76, 0x35, 0x49, 0x87, 0x11, 0xe7,
|
0x8b, 0xae, 0x44, 0xb4, 0xc1, 0x53, 0x18, 0xd5, 0xcb, 0xc6, 0x5e, 0x5f, 0xcd, 0x39, 0xa8, 0x48,
|
||||||
0x68, 0x41, 0xcc, 0x54, 0x08, 0x6c, 0xf3, 0x36, 0xa2, 0x4e, 0x0a, 0xce, 0xd1, 0x82, 0xc8, 0x95,
|
0xda, 0xdc, 0x14, 0x86, 0x29, 0x8d, 0x88, 0x88, 0x5f, 0xd2, 0xb0, 0xc8, 0x48, 0xea, 0xb9, 0xca,
|
||||||
0x69, 0xed, 0xfa, 0x6d, 0x44, 0xed, 0x6c, 0x9c, 0xa3, 0xd1, 0x0b, 0xb0, 0x16, 0xb9, 0x97, 0xed,
|
0xc4, 0xf8, 0x75, 0x26, 0xe6, 0x19, 0x49, 0xf1, 0xbe, 0x6d, 0x93, 0x95, 0x94, 0x5d, 0x8d, 0xd9,
|
||||||
0xa6, 0xa4, 0xde, 0x70, 0x31, 0x85, 0xe5, 0x71, 0xc9, 0x10, 0xee, 0x2f, 0xee, 0x7a, 0x46, 0x33,
|
0xd0, 0x44, 0x10, 0x0f, 0xc6, 0xad, 0x53, 0x84, 0xab, 0xe1, 0x8f, 0x24, 0x78, 0x8b, 0xa6, 0xa5,
|
||||||
0xbb, 0xd1, 0x33, 0x76, 0x6a, 0xb8, 0x5d, 0xd4, 0x46, 0x99, 0xf3, 0xc3, 0x80, 0x75, 0xf5, 0x07,
|
0x0f, 0xc6, 0x2d, 0xe9, 0xce, 0xa2, 0x5a, 0xfe, 0x14, 0x86, 0x19, 0x2f, 0xe2, 0x5a, 0xd4, 0xfe,
|
||||||
0x5e, 0x79, 0x34, 0x8c, 0x56, 0x95, 0xcf, 0x19, 0x02, 0x73, 0x41, 0xa2, 0x44, 0xbf, 0x66, 0x72,
|
0x9b, 0x8a, 0xb2, 0x6d, 0x56, 0x54, 0x35, 0x46, 0x8b, 0x1a, 0x6a, 0x51, 0x16, 0xad, 0x44, 0x55,
|
||||||
0x8d, 0xf6, 0xc0, 0x14, 0x1a, 0xe5, 0x15, 0xfe, 0xbf, 0xdb, 0xab, 0x56, 0xa5, 0x26, 0x4f, 0x56,
|
0x34, 0x2d, 0xea, 0x40, 0x8b, 0xb2, 0xa8, 0x12, 0xe5, 0xff, 0xe9, 0x40, 0x57, 0x6f, 0x85, 0x3e,
|
||||||
0x09, 0xc1, 0x12, 0x2d, 0xd2, 0xa4, 0x5e, 0x60, 0xdb, 0xbc, 0x2d, 0x4d, 0x8a, 0x87, 0x35, 0xf6,
|
0x86, 0xd1, 0xba, 0x64, 0x65, 0x72, 0xd3, 0x88, 0xbe, 0x66, 0x77, 0x6a, 0x5c, 0x5b, 0x39, 0x83,
|
||||||
0xd1, 0x08, 0xa0, 0x9c, 0x84, 0xda, 0xd0, 0x3c, 0x3e, 0x9b, 0x9e, 0x4e, 0x06, 0xb8, 0xf3, 0x1f,
|
0x7b, 0xaf, 0x52, 0x6f, 0x5d, 0xb7, 0xc3, 0x57, 0x1a, 0xf4, 0x5b, 0x39, 0x81, 0x41, 0x99, 0x65,
|
||||||
0xb2, 0xa0, 0x3e, 0x3c, 0x9c, 0x0e, 0x07, 0x1d, 0x43, 0xd4, 0xc7, 0xd3, 0xd1, 0xe8, 0x10, 0x5f,
|
0x34, 0x0f, 0x57, 0xbc, 0x4c, 0x37, 0xe6, 0xce, 0x81, 0x82, 0x2e, 0x24, 0x72, 0x2b, 0x17, 0x5a,
|
||||||
0x74, 0xd6, 0xc4, 0x66, 0x7a, 0x3a, 0xb9, 0x38, 0x1f, 0xbc, 0xec, 0xd4, 0xd0, 0x06, 0x58, 0x27,
|
0xff, 0x3b, 0x17, 0xa0, 0x3e, 0x32, 0x79, 0x11, 0xf9, 0xd5, 0x55, 0x41, 0xb5, 0x83, 0xbb, 0xd8,
|
||||||
0xaf, 0xc7, 0x93, 0xb3, 0x21, 0x3e, 0x1c, 0x75, 0xcc, 0x23, 0x0c, 0x95, 0xef, 0xfe, 0xbb, 0x83,
|
0x54, 0x12, 0x4f, 0x68, 0x1a, 0x89, 0xad, 0xda, 0x7d, 0x88, 0x4d, 0xe5, 0xff, 0xee, 0x40, 0xdf,
|
||||||
0x20, 0x64, 0x0b, 0x3e, 0x77, 0xfd, 0x98, 0xf6, 0xcb, 0x6e, 0x5f, 0x75, 0x67, 0x34, 0xbe, 0x24,
|
0x0e, 0x45, 0xf7, 0xa1, 0x93, 0xc8, 0x54, 0xf4, 0x1c, 0xf5, 0x82, 0x4e, 0x9a, 0x35, 0x54, 0xc1,
|
||||||
0x51, 0x3f, 0x88, 0x9f, 0x85, 0xf1, 0xac, 0xec, 0xce, 0x54, 0xf7, 0x57, 0x00, 0x00, 0x00, 0xff,
|
0x89, 0x35, 0xbb, 0x39, 0x71, 0xd0, 0x97, 0xe0, 0x56, 0xa9, 0x6b, 0x4c, 0x1d, 0x05, 0x3a, 0x97,
|
||||||
0xff, 0xd0, 0x84, 0x91, 0x73, 0x59, 0x06, 0x00, 0x00,
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
"github.com/shirou/gopsutil/v3/internal/common"
|
"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) {
|
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) {
|
func getFsType(stat unix.Statfs_t) string {
|
||||||
return nil, common.ErrNotImplementedError
|
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
|
//go:build freebsd || linux || darwin || (aix && !cgo)
|
||||||
// +build freebsd linux darwin
|
// +build freebsd linux darwin aix,!cgo
|
||||||
|
|
||||||
package disk
|
package disk
|
||||||
|
|
||||||
|
|
@ -27,20 +27,8 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
||||||
InodesFree: (uint64(stat.Ffree)),
|
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)
|
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 {
|
if (ret.Used + ret.Free) == 0 {
|
||||||
ret.UsedPercent = 0
|
ret.UsedPercent = 0
|
||||||
} else {
|
} 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
|
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
|
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.
|
// ReadLinesOffsetN reads contents from file and splits them by new line.
|
||||||
// The offset tells at which line number to start.
|
// The offset tells at which line number to start.
|
||||||
// The count determines the number of lines to read (starting from offset):
|
// The count determines the number of lines to read (starting from offset):
|
||||||
// n >= 0: at most n lines
|
// n >= 0: at most n lines
|
||||||
// n < 0: whole file
|
// n < 0: whole file
|
||||||
func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
||||||
f, err := os.Open(filename)
|
f, err := os.Open(filename)
|
||||||
if err != nil {
|
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") {
|
if StringsContains(contents, "kvm") {
|
||||||
system = "kvm"
|
system = "kvm"
|
||||||
role = "host"
|
role = "host"
|
||||||
|
} else if StringsContains(contents, "hv_util") {
|
||||||
|
system = "hyperv"
|
||||||
|
role = "guest"
|
||||||
} else if StringsContains(contents, "vboxdrv") {
|
} else if StringsContains(contents, "vboxdrv") {
|
||||||
system = "vbox"
|
system = "vbox"
|
||||||
role = "host"
|
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
|
// If protocols is empty then all protocols are returned, otherwise
|
||||||
// just the protocols in the list are returned.
|
// just the protocols in the list are returned.
|
||||||
// Available protocols:
|
// Available protocols:
|
||||||
// ip,icmp,icmpmsg,tcp,udp,udplite
|
// [ip,icmp,icmpmsg,tcp,udp,udplite]
|
||||||
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
|
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
|
||||||
return ProtoCountersWithContext(context.Background(), protocols)
|
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 {
|
if userProcParams.CurrentDirectoryPathNameLength > 0 {
|
||||||
cwd := readProcessMemory(syscall.Handle(h), procIs32Bits, uint64(userProcParams.CurrentDirectoryPathAddress), uint(userProcParams.CurrentDirectoryPathNameLength))
|
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")
|
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
|
InstanceName string
|
||||||
DeepLinking bool
|
DeepLinking bool
|
||||||
PersistAuthorization bool
|
PersistAuthorization bool
|
||||||
|
SyntaxHighlight bool
|
||||||
|
|
||||||
// The information for OAuth2 integration, if any.
|
// The information for OAuth2 integration, if any.
|
||||||
OAuth *OAuthConfig
|
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.
|
// DocExpansion list, full, none.
|
||||||
func DocExpansion(docExpansion string) func(*Config) {
|
func DocExpansion(docExpansion string) func(*Config) {
|
||||||
return func(c *Config) {
|
return func(c *Config) {
|
||||||
|
|
@ -97,6 +105,7 @@ func newConfig(configFns ...func(*Config)) *Config {
|
||||||
InstanceName: "swagger",
|
InstanceName: "swagger",
|
||||||
DeepLinking: true,
|
DeepLinking: true,
|
||||||
PersistAuthorization: false,
|
PersistAuthorization: false,
|
||||||
|
SyntaxHighlight: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fn := range configFns {
|
for _, fn := range configFns {
|
||||||
|
|
@ -257,6 +266,7 @@ window.onload = function() {
|
||||||
// Build a system
|
// Build a system
|
||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: "{{.URL}}",
|
url: "{{.URL}}",
|
||||||
|
syntaxHighlight: {{.SyntaxHighlight}},
|
||||||
deepLinking: {{.DeepLinking}},
|
deepLinking: {{.DeepLinking}},
|
||||||
docExpansion: "{{.DocExpansion}}",
|
docExpansion: "{{.DocExpansion}}",
|
||||||
persistAuthorization: {{.PersistAuthorization}},
|
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:
|
2. Download swag by using:
|
||||||
```sh
|
```sh
|
||||||
$ go get -u github.com/swaggo/swag/cmd/swag
|
|
||||||
|
|
||||||
# 1.16 or newer
|
|
||||||
$ go install github.com/swaggo/swag/cmd/swag@latest
|
$ 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).
|
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:
|
2. 使用如下命令下载swag:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ go get -u github.com/swaggo/swag/cmd/swag
|
|
||||||
|
|
||||||
# 1.16 及以上版本
|
|
||||||
$ go install github.com/swaggo/swag/cmd/swag@latest
|
$ go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
从源码开始构建的话,需要有Go环境(1.15及以上版本)。
|
从源码开始构建的话,需要有Go环境(1.16及以上版本)。
|
||||||
|
|
||||||
或者从github的release页面下载预编译好的二进制文件。
|
或者从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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/md5"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
goparser "go/parser"
|
goparser "go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
)
|
)
|
||||||
|
|
||||||
const splitTag = "&*"
|
|
||||||
|
|
||||||
// Check of @Param @Success @Failure @Response @Header
|
// Check of @Param @Success @Failure @Response @Header
|
||||||
var specialTagForSplit = map[string]bool{
|
var specialTagForSplit = map[string]bool{
|
||||||
paramAttr: true,
|
paramAttr: true,
|
||||||
|
|
@ -55,48 +52,93 @@ func (f *Formatter) Format(fileName string, contents []byte) ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
formattedComments := bytes.Buffer{}
|
|
||||||
oldComments := map[string]string{}
|
|
||||||
|
|
||||||
if ast.Comments != nil {
|
// Formatting changes are described as an edit list of byte range
|
||||||
for _, comment := range ast.Comments {
|
// replacements. We make these content-level edits directly rather than
|
||||||
formatFuncDoc(comment.List, &formattedComments, oldComments)
|
// 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 {
|
type edit struct {
|
||||||
for _, comment := range bytes.Split(formattedComments, []byte("\n")) {
|
begin int
|
||||||
splits := bytes.SplitN(comment, []byte(splitTag), 2)
|
end int
|
||||||
if len(splits) == 2 {
|
replacement []byte
|
||||||
hash, line := splits[0], splits[1]
|
}
|
||||||
contents = bytes.Replace(contents, []byte(oldComments[string(hash)]), line, 1)
|
|
||||||
}
|
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
|
return contents
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatFuncDoc(commentList []*ast.Comment, formattedComments io.Writer, oldCommentsMap map[string]string) {
|
// formatFuncDoc reformats the comment lines in commentList, and appends any
|
||||||
w := tabwriter.NewWriter(formattedComments, 0, 0, 1, ' ', 0)
|
// 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
|
text := comment.Text
|
||||||
if attr, body, found := swagComment(text); found {
|
if attr, body, found := swagComment(text); found {
|
||||||
cmd5 := fmt.Sprintf("%x", md5.Sum([]byte(text)))
|
|
||||||
oldCommentsMap[cmd5] = text
|
|
||||||
|
|
||||||
formatted := "// " + attr
|
formatted := "// " + attr
|
||||||
if body != "" {
|
if body != "" {
|
||||||
formatted += "\t" + splitComment2(attr, body)
|
formatted += "\t" + splitComment2(attr, body)
|
||||||
}
|
}
|
||||||
// md5 + splitTag + srcCommentLine
|
_, _ = fmt.Fprintln(w, formatted)
|
||||||
// eg. xxx&*@Description get struct array
|
linesToComments[len(linesToComments)] = commentIndex
|
||||||
_, _ = fmt.Fprintln(w, cmd5+splitTag+formatted)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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()
|
_ = 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 {
|
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 (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/go-openapi/spec"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var genericDefinitionsMutex = &sync.RWMutex{}
|
||||||
var genericsDefinitions = map[*TypeSpecDef]map[string]*TypeSpecDef{}
|
var genericsDefinitions = map[*TypeSpecDef]map[string]*TypeSpecDef{}
|
||||||
|
|
||||||
type genericTypeSpec struct {
|
type genericTypeSpec struct {
|
||||||
|
|
@ -55,9 +59,12 @@ func typeSpecFullName(typeSpecDef *TypeSpecDef) string {
|
||||||
return fullName
|
return 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 {
|
||||||
if spec, ok := genericsDefinitions[original][fullGenericForm]; ok {
|
genericDefinitionsMutex.RLock()
|
||||||
return spec
|
tSpec, ok := genericsDefinitions[original][fullGenericForm]
|
||||||
|
genericDefinitionsMutex.RUnlock()
|
||||||
|
if ok {
|
||||||
|
return tSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgName := strings.Split(fullGenericForm, ".")[0]
|
pkgName := strings.Split(fullGenericForm, ".")[0]
|
||||||
|
|
@ -81,7 +88,11 @@ func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, ful
|
||||||
arrayDepth++
|
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{
|
genericParamTypeDefs[original.TypeSpec.TypeParams.List[i].Names[0].Name] = &genericTypeSpec{
|
||||||
ArrayDepth: arrayDepth,
|
ArrayDepth: arrayDepth,
|
||||||
TypeSpec: tdef,
|
TypeSpec: tdef,
|
||||||
|
|
@ -132,31 +143,12 @@ func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, ful
|
||||||
ident.Name = string(IgnoreNameOverridePrefix) + ident.Name
|
ident.Name = string(IgnoreNameOverridePrefix) + ident.Name
|
||||||
|
|
||||||
parametrizedTypeSpec.TypeSpec.Name = ident
|
parametrizedTypeSpec.TypeSpec.Name = ident
|
||||||
origStructType := original.TypeSpec.Type.(*ast.StructType)
|
|
||||||
|
|
||||||
newStructTypeDef := &ast.StructType{
|
newType := pkgDefs.resolveGenericType(original.File, original.TypeSpec.Type, genericParamTypeDefs, parseDependency)
|
||||||
Struct: origStructType.Struct,
|
|
||||||
Incomplete: origStructType.Incomplete,
|
|
||||||
Fields: &ast.FieldList{
|
|
||||||
Opening: origStructType.Fields.Opening,
|
|
||||||
Closing: origStructType.Fields.Closing,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, field := range origStructType.Fields.List {
|
genericDefinitionsMutex.Lock()
|
||||||
newField := &ast.Field{
|
defer genericDefinitionsMutex.Unlock()
|
||||||
Doc: field.Doc,
|
parametrizedTypeSpec.TypeSpec.Type = newType
|
||||||
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
|
|
||||||
if genericsDefinitions[original] == nil {
|
if genericsDefinitions[original] == nil {
|
||||||
genericsDefinitions[original] = map[string]*TypeSpecDef{}
|
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
|
// splitStructName splits a generic struct name in his parts
|
||||||
func splitStructName(fullGenericForm string) (string, []string) {
|
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 ']'
|
// split only at the first '[' and remove the last ']'
|
||||||
if fullGenericForm[len(fullGenericForm)-1] != ']' {
|
if fullGenericForm[len(fullGenericForm)-1] != ']' {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
genericParams := strings.SplitN(strings.TrimSpace(fullGenericForm)[:len(fullGenericForm)-1], "[", 2)
|
genericParams := strings.SplitN(fullGenericForm[:len(fullGenericForm)-1], "[", 2)
|
||||||
if len(genericParams) == 1 {
|
if len(genericParams) == 1 {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
@ -179,73 +179,121 @@ func splitStructName(fullGenericForm string) (string, []string) {
|
||||||
// generic type name
|
// generic type name
|
||||||
genericTypeName := genericParams[0]
|
genericTypeName := genericParams[0]
|
||||||
|
|
||||||
// generic params
|
depth := 0
|
||||||
insideBrackets := 0
|
genericParams = strings.FieldsFunc(genericParams[1], func(r rune) bool {
|
||||||
lastParam := ""
|
if r == '[' {
|
||||||
params := strings.Split(genericParams[1], ",")
|
depth++
|
||||||
genericParams = []string{}
|
} else if r == ']' {
|
||||||
for _, p := range params {
|
depth--
|
||||||
numOpened := strings.Count(p, "[")
|
} else if r == ',' && depth == 0 {
|
||||||
numClosed := strings.Count(p, "]")
|
return true
|
||||||
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 = ""
|
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
if depth != 0 {
|
||||||
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return genericTypeName, genericParams
|
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) {
|
switch astExpr := expr.(type) {
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
if genTypeSpec, ok := genericParamTypeDefs[astExpr.Name]; ok {
|
if genTypeSpec, ok := genericParamTypeDefs[astExpr.Name]; ok {
|
||||||
if genTypeSpec.ArrayDepth > 0 {
|
retType := genTypeSpec.Type()
|
||||||
genTypeSpec.ArrayDepth--
|
for i := 0; i < genTypeSpec.ArrayDepth; i++ {
|
||||||
return &ast.ArrayType{Elt: resolveType(expr, field, genericParamTypeDefs)}
|
retType = &ast.ArrayType{Elt: retType}
|
||||||
}
|
}
|
||||||
return genTypeSpec.Type()
|
return retType
|
||||||
}
|
}
|
||||||
case *ast.ArrayType:
|
case *ast.ArrayType:
|
||||||
return &ast.ArrayType{
|
return &ast.ArrayType{
|
||||||
Elt: resolveType(astExpr.Elt, field, genericParamTypeDefs),
|
Elt: pkgDefs.resolveGenericType(file, astExpr.Elt, genericParamTypeDefs, parseDependency),
|
||||||
Len: astExpr.Len,
|
Len: astExpr.Len,
|
||||||
Lbrack: astExpr.Lbrack,
|
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) {
|
switch fieldType := field.(type) {
|
||||||
case *ast.IndexListExpr:
|
case *ast.IndexListExpr:
|
||||||
fullName, err := getGenericTypeName(file, fieldType.X)
|
baseName, err = getGenericTypeName(file, fieldType.X)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
fullName += "["
|
fullName = baseName + "["
|
||||||
|
|
||||||
for _, index := range fieldType.Indices {
|
for _, index := range fieldType.Indices {
|
||||||
var fieldName string
|
fieldName, err := getExtendedGenericFieldType(file, index, genericParamTypeDefs)
|
||||||
var err error
|
|
||||||
|
|
||||||
switch item := index.(type) {
|
|
||||||
case *ast.ArrayType:
|
|
||||||
fieldName, err = getFieldType(file, item.Elt)
|
|
||||||
fieldName = "[]" + fieldName
|
|
||||||
default:
|
|
||||||
fieldName, err = getFieldType(file, index)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -253,50 +301,85 @@ func getGenericFieldType(file *ast.File, field ast.Expr) (string, error) {
|
||||||
fullName += fieldName + ","
|
fullName += fieldName + ","
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimRight(fullName, ",") + "]", nil
|
fullName = strings.TrimRight(fullName, ",") + "]"
|
||||||
case *ast.IndexExpr:
|
case *ast.IndexExpr:
|
||||||
x, err := getFieldType(file, fieldType.X)
|
baseName, err = getGenericTypeName(file, fieldType.X)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
i, err := getFieldType(file, fieldType.Index)
|
indexName, err := getExtendedGenericFieldType(file, fieldType.Index, genericParamTypeDefs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
packageName := ""
|
fullName = fmt.Sprintf("%s[%s]", baseName, indexName)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
func getGenericTypeName(file *ast.File, field ast.Expr) (string, error) {
|
||||||
switch indexType := field.(type) {
|
switch fieldType := field.(type) {
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
spec := &TypeSpecDef{
|
if fieldType.Obj == nil {
|
||||||
|
return fieldType.Name, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tSpec := &TypeSpecDef{
|
||||||
File: file,
|
File: file,
|
||||||
TypeSpec: indexType.Obj.Decl.(*ast.TypeSpec),
|
TypeSpec: fieldType.Obj.Decl.(*ast.TypeSpec),
|
||||||
PkgPath: file.Name.Name,
|
PkgPath: file.Name.Name,
|
||||||
}
|
}
|
||||||
return spec.FullName(), nil
|
return tSpec.FullName(), nil
|
||||||
case *ast.ArrayType:
|
case *ast.ArrayType:
|
||||||
spec := &TypeSpecDef{
|
tSpec := &TypeSpecDef{
|
||||||
File: file,
|
File: file,
|
||||||
TypeSpec: indexType.Elt.(*ast.Ident).Obj.Decl.(*ast.TypeSpec),
|
TypeSpec: fieldType.Elt.(*ast.Ident).Obj.Decl.(*ast.TypeSpec),
|
||||||
PkgPath: file.Name.Name,
|
PkgPath: file.Name.Name,
|
||||||
}
|
}
|
||||||
return spec.FullName(), nil
|
return tSpec.FullName(), nil
|
||||||
case *ast.SelectorExpr:
|
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)
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/go-openapi/spec"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type genericTypeSpec struct {
|
||||||
|
ArrayDepth int
|
||||||
|
TypeSpec *TypeSpecDef
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
func typeSpecFullName(typeSpecDef *TypeSpecDef) string {
|
func typeSpecFullName(typeSpecDef *TypeSpecDef) string {
|
||||||
return typeSpecDef.FullName()
|
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
|
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)
|
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"
|
"go/ast"
|
||||||
goparser "go/parser"
|
goparser "go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"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 {
|
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)
|
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
|
// ParseParamComment parses params return []string of param properties
|
||||||
// E.g. @Param queryText formData string true "The email for login"
|
// 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".
|
// E.g. @Param some_id path int true "Some ID".
|
||||||
func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.File) error {
|
func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.File) error {
|
||||||
matches := paramPattern.FindStringSubmatch(commentLine)
|
matches := paramPattern.FindStringSubmatch(commentLine)
|
||||||
|
|
@ -824,6 +825,10 @@ var responsePattern = regexp.MustCompile(`^([\w,]+)\s+([\w{}]+)\s+([\w\-.\\{}=,\
|
||||||
var combinedPattern = regexp.MustCompile(`^([\w\-./\[\]]+){(.*)}$`)
|
var combinedPattern = regexp.MustCompile(`^([\w\-./\[\]]+){(.*)}$`)
|
||||||
|
|
||||||
func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File) (*spec.Schema, error) {
|
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 {
|
switch {
|
||||||
case refType == NIL:
|
case refType == NIL:
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -838,7 +843,7 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
|
||||||
case IsPrimitiveType(refType):
|
case IsPrimitiveType(refType):
|
||||||
return PrimitiveSchema(refType), nil
|
return PrimitiveSchema(refType), nil
|
||||||
case strings.HasPrefix(refType, "[]"):
|
case strings.HasPrefix(refType, "[]"):
|
||||||
schema, err := operation.parseObjectSchema(refType[2:], astFile)
|
schema, err := parseObjectSchema(parser, refType[2:], astFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -856,17 +861,17 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
|
||||||
return spec.MapProperty(nil), nil
|
return spec.MapProperty(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
schema, err := operation.parseObjectSchema(refType, astFile)
|
schema, err := parseObjectSchema(parser, refType, astFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return spec.MapProperty(schema), nil
|
return spec.MapProperty(schema), nil
|
||||||
case strings.Contains(refType, "{"):
|
case strings.Contains(refType, "{"):
|
||||||
return operation.parseCombinedObjectSchema(refType, astFile)
|
return parseCombinedObjectSchema(parser, refType, astFile)
|
||||||
default:
|
default:
|
||||||
if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
|
if parser != nil { // checking refType has existing in 'TypeDefinitions'
|
||||||
schema, err := operation.parser.getTypeSchema(refType, astFile, true)
|
schema, err := parser.getTypeSchema(refType, astFile, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
matches := combinedPattern.FindStringSubmatch(refType)
|
||||||
if len(matches) != 3 {
|
if len(matches) != 3 {
|
||||||
return nil, fmt.Errorf("invalid type: %s", refType)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -912,7 +917,7 @@ func (operation *Operation) parseCombinedObjectSchema(refType string, astFile *a
|
||||||
for _, field := range fields {
|
for _, field := range fields {
|
||||||
keyVal := strings.SplitN(field, "=", 2)
|
keyVal := strings.SplitN(field, "=", 2)
|
||||||
if len(keyVal) == 2 {
|
if len(keyVal) == 2 {
|
||||||
schema, err := operation.parseObjectSchema(keyVal[1], astFile)
|
schema, err := parseObjectSchema(parser, keyVal[1], astFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1193,17 +1198,17 @@ func createParameter(paramType, description, paramName, schemaType string, requi
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error) {
|
func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error) {
|
||||||
filesInfos, err := ioutil.ReadDir(dirPath)
|
dirEntries, err := os.ReadDir(dirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fileInfo := range filesInfos {
|
for _, entry := range dirEntries {
|
||||||
if fileInfo.IsDir() {
|
if entry.IsDir() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName := fileInfo.Name()
|
fileName := entry.Name()
|
||||||
|
|
||||||
if !strings.Contains(fileName, ".json") {
|
if !strings.Contains(fileName, ".json") {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1212,7 +1217,7 @@ func getCodeExampleForSummary(summaryName string, dirPath string) ([]byte, error
|
||||||
if strings.Contains(fileName, summaryName) {
|
if strings.Contains(fileName, summaryName) {
|
||||||
fullPath := filepath.Join(dirPath, fileName)
|
fullPath := filepath.Join(dirPath, fileName)
|
||||||
|
|
||||||
commentInfo, err := ioutil.ReadFile(fullPath)
|
commentInfo, err := os.ReadFile(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to read code example file %s error: %s ", fullPath, err)
|
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) {
|
func (pkgDefs *PackagesDefinitions) parseFunctionScopedTypesFromFile(astFile *ast.File, packagePath string, parsedSchemas map[*TypeSpecDef]*Schema) {
|
||||||
for _, astDeclaration := range astFile.Decls {
|
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 {
|
for _, stmt := range funcDeclaration.Body.List {
|
||||||
if declStmt, ok := (stmt).(*ast.DeclStmt); ok {
|
if declStmt, ok := (stmt).(*ast.DeclStmt); ok {
|
||||||
if genDecl, ok := (declStmt.Decl).(*ast.GenDecl); ok && genDecl.Tok == token.TYPE {
|
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, "[") {
|
if def := pkgDefs.findGenericTypeSpec(typeName, file, parseDependency); def != nil {
|
||||||
// joinedParts differs from typeName in that it does not contain any type parameters
|
return def
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pkgDefs.findTypeSpec(pkgPath, parts[1])
|
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)]
|
typeDef, ok := pkgDefs.uniqueDefinitions[fullTypeName(file.Name.Name, typeName)]
|
||||||
if ok {
|
if ok {
|
||||||
return typeDef
|
return typeDef
|
||||||
|
|
@ -428,3 +421,22 @@ func (pkgDefs *PackagesDefinitions) FindTypeSpec(typeName string, file *ast.File
|
||||||
|
|
||||||
return nil
|
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"
|
"go/build"
|
||||||
goparser "go/parser"
|
goparser "go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
@ -733,17 +732,17 @@ func isGeneralAPIComment(comments []string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMarkdownForTag(tagName string, dirPath string) ([]byte, error) {
|
func getMarkdownForTag(tagName string, dirPath string) ([]byte, error) {
|
||||||
filesInfos, err := ioutil.ReadDir(dirPath)
|
dirEntries, err := os.ReadDir(dirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fileInfo := range filesInfos {
|
for _, entry := range dirEntries {
|
||||||
if fileInfo.IsDir() {
|
if entry.IsDir() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName := fileInfo.Name()
|
fileName := entry.Name()
|
||||||
|
|
||||||
if !strings.Contains(fileName, ".md") {
|
if !strings.Contains(fileName, ".md") {
|
||||||
continue
|
continue
|
||||||
|
|
@ -752,7 +751,7 @@ func getMarkdownForTag(tagName string, dirPath string) ([]byte, error) {
|
||||||
if strings.Contains(fileName, tagName) {
|
if strings.Contains(fileName, tagName) {
|
||||||
fullPath := filepath.Join(dirPath, fileName)
|
fullPath := filepath.Join(dirPath, fileName)
|
||||||
|
|
||||||
commentInfo, err := ioutil.ReadFile(fullPath)
|
commentInfo, err := os.ReadFile(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to read markdown file %s error: %s ", fullPath, err)
|
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) {
|
func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (*spec.Schema, error) {
|
||||||
if override, ok := parser.Overrides[typeName]; ok {
|
if override, ok := parser.Overrides[typeName]; ok {
|
||||||
parser.debug.Printf("Override detected for %s: using %s instead", typeName, override)
|
parser.debug.Printf("Override detected for %s: using %s instead", typeName, override)
|
||||||
typeName = override
|
return parseObjectSchema(parser, override, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsInterfaceLike(typeName) {
|
if IsInterfaceLike(typeName) {
|
||||||
|
|
@ -1186,12 +1185,10 @@ func (parser *Parser) parseTypeExpr(file *ast.File, typeExpr ast.Expr, ref bool)
|
||||||
|
|
||||||
case *ast.FuncType:
|
case *ast.FuncType:
|
||||||
return nil, ErrFuncTypeField
|
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) {
|
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
|
return fullName, nil
|
||||||
default:
|
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
|
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 {
|
if err != nil {
|
||||||
return err
|
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
|
package swag
|
||||||
|
|
||||||
// Version of 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
|
// but when f returns an error, ExecuteFuncStringWithErr won't panic like ExecuteFuncString
|
||||||
// it just returns an empty string and the error f returned
|
// it just returns an empty string and the error f returned
|
||||||
func ExecuteFuncStringWithErr(template, startTag, endTag string, f TagFunc) (string, error) {
|
func ExecuteFuncStringWithErr(template, startTag, endTag string, f TagFunc) (string, error) {
|
||||||
tagsCount := bytes.Count(unsafeString2Bytes(template), unsafeString2Bytes(startTag))
|
if n := bytes.Index(unsafeString2Bytes(template), unsafeString2Bytes(startTag)); n < 0 {
|
||||||
if tagsCount == 0 {
|
|
||||||
return template, nil
|
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) {
|
if p.skip(lexer.Bang) {
|
||||||
typ.Position = p.peekPos()
|
|
||||||
typ.NonNull = true
|
typ.NonNull = true
|
||||||
}
|
}
|
||||||
return &typ
|
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
|
# Profiling output
|
||||||
*.prof
|
*.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/),
|
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).
|
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
|
## [1.7.0] - 2020-09-14
|
||||||
### Added
|
### Added
|
||||||
- Support JSON serialization and deserialization of primitive atomic types.
|
- 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
|
### Removed
|
||||||
- Remove dependency on `golang.org/x/{lint, tools}`.
|
- 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
|
## [1.6.0] - 2020-02-24
|
||||||
### Changed
|
### Changed
|
||||||
- Drop library dependency on `golang.org/x/{lint, tools}`.
|
- 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
|
## [1.5.1] - 2019-11-19
|
||||||
- Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together
|
- Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together
|
||||||
causing `CAS` to fail even though the old value matches.
|
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
|
## [1.5.0] - 2019-10-29
|
||||||
### Changed
|
### Changed
|
||||||
- With Go modules, only the `go.uber.org/atomic` import path is supported now.
|
- 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
|
If you need to use the old import path, please add a `replace` directive to
|
||||||
your `go.mod`.
|
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
|
## [1.4.0] - 2019-05-01
|
||||||
### Added
|
### Added
|
||||||
- Add `atomic.Error` type for atomic operations on `error` values.
|
- 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
|
## [1.3.2] - 2018-05-02
|
||||||
### Added
|
### Added
|
||||||
- Add `atomic.Duration` type for atomic operations on `time.Duration` values.
|
- 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
|
## [1.3.1] - 2017-11-14
|
||||||
### Fixed
|
### Fixed
|
||||||
- Revert optimization for `atomic.String.Store("")` which caused data races.
|
- 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
|
## [1.3.0] - 2017-11-13
|
||||||
### Added
|
### Added
|
||||||
- Add `atomic.Bool.CAS` for compare-and-swap semantics on bools.
|
- 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
|
### Changed
|
||||||
- Optimize `atomic.String.Store("")` by avoiding an allocation.
|
- 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
|
## [1.2.0] - 2017-04-12
|
||||||
### Added
|
### Added
|
||||||
- Shadow `atomic.Value` from `sync/atomic`.
|
- 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
|
## [1.1.0] - 2017-03-10
|
||||||
### Added
|
### Added
|
||||||
- Add atomic `Float64` type.
|
- Add atomic `Float64` type.
|
||||||
|
|
@ -59,18 +108,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Changed
|
### Changed
|
||||||
- Support new `go.uber.org/atomic` import path.
|
- 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
|
## [1.0.0] - 2016-07-18
|
||||||
|
|
||||||
- Initial release.
|
- 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.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:
|
generatenodirty:
|
||||||
@[ -z "$$(git status --porcelain)" ] || ( \
|
@[ -z "$$(git status --porcelain)" ] || ( \
|
||||||
echo "Working tree is dirty. Commit your changes first."; \
|
echo "Working tree is dirty. Commit your changes first."; \
|
||||||
|
git status; \
|
||||||
exit 1 )
|
exit 1 )
|
||||||
@make generate
|
@make generate
|
||||||
@status=$$(git status --porcelain); \
|
@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-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
|
||||||
[doc]: https://godoc.org/go.uber.org/atomic
|
[doc]: https://godoc.org/go.uber.org/atomic
|
||||||
[ci-img]: https://travis-ci.com/uber-go/atomic.svg?branch=master
|
[ci-img]: https://github.com/uber-go/atomic/actions/workflows/go.yml/badge.svg
|
||||||
[ci]: https://travis-ci.com/uber-go/atomic
|
[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-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg
|
||||||
[cov]: https://codecov.io/gh/uber-go/atomic
|
[cov]: https://codecov.io/gh/uber-go/atomic
|
||||||
[reportcard-img]: https://goreportcard.com/badge/go.uber.org/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.
|
// @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
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
@ -36,10 +36,10 @@ type Bool struct {
|
||||||
var _zeroBool bool
|
var _zeroBool bool
|
||||||
|
|
||||||
// NewBool creates a new Bool.
|
// NewBool creates a new Bool.
|
||||||
func NewBool(v bool) *Bool {
|
func NewBool(val bool) *Bool {
|
||||||
x := &Bool{}
|
x := &Bool{}
|
||||||
if v != _zeroBool {
|
if val != _zeroBool {
|
||||||
x.Store(v)
|
x.Store(val)
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
@ -50,19 +50,26 @@ func (x *Bool) Load() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store atomically stores the passed bool.
|
// Store atomically stores the passed bool.
|
||||||
func (x *Bool) Store(v bool) {
|
func (x *Bool) Store(val bool) {
|
||||||
x.v.Store(boolToInt(v))
|
x.v.Store(boolToInt(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CAS is an atomic compare-and-swap for bool values.
|
// 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
|
// Swap atomically stores the given bool and returns the old
|
||||||
// value.
|
// value.
|
||||||
func (x *Bool) Swap(o bool) bool {
|
func (x *Bool) Swap(val bool) (old bool) {
|
||||||
return truthy(x.v.Swap(boolToInt(o)))
|
return truthy(x.v.Swap(boolToInt(val)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON encodes the wrapped bool into JSON.
|
// 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.
|
// Toggle atomically negates the Boolean and returns the previous value.
|
||||||
func (b *Bool) Toggle() bool {
|
func (b *Bool) Toggle() (old bool) {
|
||||||
for {
|
for {
|
||||||
old := b.Load()
|
old := b.Load()
|
||||||
if b.CAS(old, !old) {
|
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.
|
// @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
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
@ -37,10 +37,10 @@ type Duration struct {
|
||||||
var _zeroDuration time.Duration
|
var _zeroDuration time.Duration
|
||||||
|
|
||||||
// NewDuration creates a new Duration.
|
// NewDuration creates a new Duration.
|
||||||
func NewDuration(v time.Duration) *Duration {
|
func NewDuration(val time.Duration) *Duration {
|
||||||
x := &Duration{}
|
x := &Duration{}
|
||||||
if v != _zeroDuration {
|
if val != _zeroDuration {
|
||||||
x.Store(v)
|
x.Store(val)
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
@ -51,19 +51,26 @@ func (x *Duration) Load() time.Duration {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store atomically stores the passed time.Duration.
|
// Store atomically stores the passed time.Duration.
|
||||||
func (x *Duration) Store(v time.Duration) {
|
func (x *Duration) Store(val time.Duration) {
|
||||||
x.v.Store(int64(v))
|
x.v.Store(int64(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CAS is an atomic compare-and-swap for time.Duration values.
|
// 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
|
// Swap atomically stores the given time.Duration and returns the old
|
||||||
// value.
|
// value.
|
||||||
func (x *Duration) Swap(o time.Duration) time.Duration {
|
func (x *Duration) Swap(val time.Duration) (old time.Duration) {
|
||||||
return time.Duration(x.v.Swap(int64(o)))
|
return time.Duration(x.v.Swap(int64(val)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON encodes the wrapped time.Duration into JSON.
|
// 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
|
//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.
|
// Add atomically adds to the wrapped time.Duration and returns the new value.
|
||||||
func (d *Duration) Add(n time.Duration) time.Duration {
|
func (d *Duration) Add(delta time.Duration) time.Duration {
|
||||||
return time.Duration(d.v.Add(int64(n)))
|
return time.Duration(d.v.Add(int64(delta)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
|
// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
|
||||||
func (d *Duration) Sub(n time.Duration) time.Duration {
|
func (d *Duration) Sub(delta time.Duration) time.Duration {
|
||||||
return time.Duration(d.v.Sub(int64(n)))
|
return time.Duration(d.v.Sub(int64(delta)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// String encodes the wrapped value as a string.
|
// 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.
|
// @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
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
@ -32,10 +32,10 @@ type Error struct {
|
||||||
var _zeroError error
|
var _zeroError error
|
||||||
|
|
||||||
// NewError creates a new Error.
|
// NewError creates a new Error.
|
||||||
func NewError(v error) *Error {
|
func NewError(val error) *Error {
|
||||||
x := &Error{}
|
x := &Error{}
|
||||||
if v != _zeroError {
|
if val != _zeroError {
|
||||||
x.Store(v)
|
x.Store(val)
|
||||||
}
|
}
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
@ -46,6 +46,17 @@ func (x *Error) Load() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store atomically stores the passed error.
|
// Store atomically stores the passed error.
|
||||||
func (x *Error) Store(v error) {
|
func (x *Error) Store(val error) {
|
||||||
x.v.Store(packError(v))
|
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…
Reference in a new issue