diff --git a/go.mod b/go.mod index 7ce4f16b..c3560d13 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ossrs/srs-bench -go 1.23.0 +go 1.24.0 require ( github.com/bluenviron/gortsplib/v4 v4.13.1 @@ -45,8 +45,8 @@ require ( github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 // indirect github.com/wlynxg/anet v0.0.5 // indirect github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect - golang.org/x/crypto v0.39.0 // indirect - golang.org/x/net v0.41.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/term v0.32.0 // indirect + golang.org/x/crypto v0.45.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect ) diff --git a/go.sum b/go.sum index f680ef9c..2b43d1d8 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,8 @@ github.com/yapingcat/gomedia/mpeg2 v0.0.0-20220617074658-94762898dc25/go.mod h1: golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -130,8 +130,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -148,15 +148,15 @@ golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214095126-aec9a390925b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= -golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE deleted file mode 100644 index bc52e96f..00000000 --- a/vendor/github.com/davecgh/go-spew/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -ISC License - -Copyright (c) 2012-2016 Dave Collins - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go deleted file mode 100644 index 79299478..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is not running on Google App Engine, compiled by GopherJS, and -// "-tags safe" is not added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// Go versions prior to 1.4 are disabled because they use a different layout -// for interfaces which make the implementation of unsafeReflectValue more complex. -// +build !js,!appengine,!safe,!disableunsafe,go1.4 - -package spew - -import ( - "reflect" - "unsafe" -) - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = false - - // ptrSize is the size of a pointer on the current arch. - ptrSize = unsafe.Sizeof((*byte)(nil)) -) - -type flag uintptr - -var ( - // flagRO indicates whether the value field of a reflect.Value - // is read-only. - flagRO flag - - // flagAddr indicates whether the address of the reflect.Value's - // value may be taken. - flagAddr flag -) - -// flagKindMask holds the bits that make up the kind -// part of the flags field. In all the supported versions, -// it is in the lower 5 bits. -const flagKindMask = flag(0x1f) - -// Different versions of Go have used different -// bit layouts for the flags type. This table -// records the known combinations. -var okFlags = []struct { - ro, addr flag -}{{ - // From Go 1.4 to 1.5 - ro: 1 << 5, - addr: 1 << 7, -}, { - // Up to Go tip. - ro: 1<<5 | 1<<6, - addr: 1 << 8, -}} - -var flagValOffset = func() uintptr { - field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") - if !ok { - panic("reflect.Value has no flag field") - } - return field.Offset -}() - -// flagField returns a pointer to the flag field of a reflect.Value. -func flagField(v *reflect.Value) *flag { - return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) -} - -// unsafeReflectValue converts the passed reflect.Value into a one that bypasses -// the typical safety restrictions preventing access to unaddressable and -// unexported data. It works by digging the raw pointer to the underlying -// value out of the protected value and generating a new unprotected (unsafe) -// reflect.Value to it. -// -// This allows us to check for implementations of the Stringer and error -// interfaces to be used for pretty printing ordinarily unaddressable and -// inaccessible values such as unexported struct fields. -func unsafeReflectValue(v reflect.Value) reflect.Value { - if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { - return v - } - flagFieldPtr := flagField(&v) - *flagFieldPtr &^= flagRO - *flagFieldPtr |= flagAddr - return v -} - -// Sanity checks against future reflect package changes -// to the type or semantics of the Value.flag field. -func init() { - field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") - if !ok { - panic("reflect.Value has no flag field") - } - if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { - panic("reflect.Value flag field has changed kind") - } - type t0 int - var t struct { - A t0 - // t0 will have flagEmbedRO set. - t0 - // a will have flagStickyRO set - a t0 - } - vA := reflect.ValueOf(t).FieldByName("A") - va := reflect.ValueOf(t).FieldByName("a") - vt0 := reflect.ValueOf(t).FieldByName("t0") - - // Infer flagRO from the difference between the flags - // for the (otherwise identical) fields in t. - flagPublic := *flagField(&vA) - flagWithRO := *flagField(&va) | *flagField(&vt0) - flagRO = flagPublic ^ flagWithRO - - // Infer flagAddr from the difference between a value - // taken from a pointer and not. - vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") - flagNoPtr := *flagField(&vA) - flagPtr := *flagField(&vPtrA) - flagAddr = flagNoPtr ^ flagPtr - - // Check that the inferred flags tally with one of the known versions. - for _, f := range okFlags { - if flagRO == f.ro && flagAddr == f.addr { - return - } - } - panic("reflect.Value read-only flag has changed semantics") -} diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go deleted file mode 100644 index 205c28d6..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is running on Google App Engine, compiled by GopherJS, or -// "-tags safe" is added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build js appengine safe disableunsafe !go1.4 - -package spew - -import "reflect" - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = true -) - -// unsafeReflectValue typically converts the passed reflect.Value into a one -// that bypasses the typical safety restrictions preventing access to -// unaddressable and unexported data. However, doing this relies on access to -// the unsafe package. This is a stub version which simply returns the passed -// reflect.Value when the unsafe package is not available. -func unsafeReflectValue(v reflect.Value) reflect.Value { - return v -} diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go deleted file mode 100644 index 1be8ce94..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/common.go +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "reflect" - "sort" - "strconv" -) - -// Some constants in the form of bytes to avoid string overhead. This mirrors -// the technique used in the fmt package. -var ( - panicBytes = []byte("(PANIC=") - plusBytes = []byte("+") - iBytes = []byte("i") - trueBytes = []byte("true") - falseBytes = []byte("false") - interfaceBytes = []byte("(interface {})") - commaNewlineBytes = []byte(",\n") - newlineBytes = []byte("\n") - openBraceBytes = []byte("{") - openBraceNewlineBytes = []byte("{\n") - closeBraceBytes = []byte("}") - asteriskBytes = []byte("*") - colonBytes = []byte(":") - colonSpaceBytes = []byte(": ") - openParenBytes = []byte("(") - closeParenBytes = []byte(")") - spaceBytes = []byte(" ") - pointerChainBytes = []byte("->") - nilAngleBytes = []byte("") - maxNewlineBytes = []byte("\n") - maxShortBytes = []byte("") - circularBytes = []byte("") - circularShortBytes = []byte("") - invalidAngleBytes = []byte("") - openBracketBytes = []byte("[") - closeBracketBytes = []byte("]") - percentBytes = []byte("%") - precisionBytes = []byte(".") - openAngleBytes = []byte("<") - closeAngleBytes = []byte(">") - openMapBytes = []byte("map[") - closeMapBytes = []byte("]") - lenEqualsBytes = []byte("len=") - capEqualsBytes = []byte("cap=") -) - -// hexDigits is used to map a decimal value to a hex digit. -var hexDigits = "0123456789abcdef" - -// catchPanic handles any panics that might occur during the handleMethods -// calls. -func catchPanic(w io.Writer, v reflect.Value) { - if err := recover(); err != nil { - w.Write(panicBytes) - fmt.Fprintf(w, "%v", err) - w.Write(closeParenBytes) - } -} - -// handleMethods attempts to call the Error and String methods on the underlying -// type the passed reflect.Value represents and outputes the result to Writer w. -// -// It handles panics in any called methods by catching and displaying the error -// as the formatted value. -func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { - // We need an interface to check if the type implements the error or - // Stringer interface. However, the reflect package won't give us an - // interface on certain things like unexported struct fields in order - // to enforce visibility rules. We use unsafe, when it's available, - // to bypass these restrictions since this package does not mutate the - // values. - if !v.CanInterface() { - if UnsafeDisabled { - return false - } - - v = unsafeReflectValue(v) - } - - // Choose whether or not to do error and Stringer interface lookups against - // the base type or a pointer to the base type depending on settings. - // Technically calling one of these methods with a pointer receiver can - // mutate the value, however, types which choose to satisify an error or - // Stringer interface with a pointer receiver should not be mutating their - // state inside these interface methods. - if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { - v = unsafeReflectValue(v) - } - if v.CanAddr() { - v = v.Addr() - } - - // Is it an error or Stringer? - switch iface := v.Interface().(type) { - case error: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.Error())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - - w.Write([]byte(iface.Error())) - return true - - case fmt.Stringer: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.String())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - w.Write([]byte(iface.String())) - return true - } - return false -} - -// printBool outputs a boolean value as true or false to Writer w. -func printBool(w io.Writer, val bool) { - if val { - w.Write(trueBytes) - } else { - w.Write(falseBytes) - } -} - -// printInt outputs a signed integer value to Writer w. -func printInt(w io.Writer, val int64, base int) { - w.Write([]byte(strconv.FormatInt(val, base))) -} - -// printUint outputs an unsigned integer value to Writer w. -func printUint(w io.Writer, val uint64, base int) { - w.Write([]byte(strconv.FormatUint(val, base))) -} - -// printFloat outputs a floating point value using the specified precision, -// which is expected to be 32 or 64bit, to Writer w. -func printFloat(w io.Writer, val float64, precision int) { - w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) -} - -// printComplex outputs a complex value using the specified float precision -// for the real and imaginary parts to Writer w. -func printComplex(w io.Writer, c complex128, floatPrecision int) { - r := real(c) - w.Write(openParenBytes) - w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) - i := imag(c) - if i >= 0 { - w.Write(plusBytes) - } - w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) - w.Write(iBytes) - w.Write(closeParenBytes) -} - -// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' -// prefix to Writer w. -func printHexPtr(w io.Writer, p uintptr) { - // Null pointer. - num := uint64(p) - if num == 0 { - w.Write(nilAngleBytes) - return - } - - // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix - buf := make([]byte, 18) - - // It's simpler to construct the hex string right to left. - base := uint64(16) - i := len(buf) - 1 - for num >= base { - buf[i] = hexDigits[num%base] - num /= base - i-- - } - buf[i] = hexDigits[num] - - // Add '0x' prefix. - i-- - buf[i] = 'x' - i-- - buf[i] = '0' - - // Strip unused leading bytes. - buf = buf[i:] - w.Write(buf) -} - -// valuesSorter implements sort.Interface to allow a slice of reflect.Value -// elements to be sorted. -type valuesSorter struct { - values []reflect.Value - strings []string // either nil or same len and values - cs *ConfigState -} - -// newValuesSorter initializes a valuesSorter instance, which holds a set of -// surrogate keys on which the data should be sorted. It uses flags in -// ConfigState to decide if and how to populate those surrogate keys. -func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { - vs := &valuesSorter{values: values, cs: cs} - if canSortSimply(vs.values[0].Kind()) { - return vs - } - if !cs.DisableMethods { - vs.strings = make([]string, len(values)) - for i := range vs.values { - b := bytes.Buffer{} - if !handleMethods(cs, &b, vs.values[i]) { - vs.strings = nil - break - } - vs.strings[i] = b.String() - } - } - if vs.strings == nil && cs.SpewKeys { - vs.strings = make([]string, len(values)) - for i := range vs.values { - vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) - } - } - return vs -} - -// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted -// directly, or whether it should be considered for sorting by surrogate keys -// (if the ConfigState allows it). -func canSortSimply(kind reflect.Kind) bool { - // This switch parallels valueSortLess, except for the default case. - switch kind { - case reflect.Bool: - return true - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return true - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return true - case reflect.Float32, reflect.Float64: - return true - case reflect.String: - return true - case reflect.Uintptr: - return true - case reflect.Array: - return true - } - return false -} - -// Len returns the number of values in the slice. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Len() int { - return len(s.values) -} - -// Swap swaps the values at the passed indices. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Swap(i, j int) { - s.values[i], s.values[j] = s.values[j], s.values[i] - if s.strings != nil { - s.strings[i], s.strings[j] = s.strings[j], s.strings[i] - } -} - -// valueSortLess returns whether the first value should sort before the second -// value. It is used by valueSorter.Less as part of the sort.Interface -// implementation. -func valueSortLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Bool: - return !a.Bool() && b.Bool() - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return a.Int() < b.Int() - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return a.Uint() < b.Uint() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.String: - return a.String() < b.String() - case reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Array: - // Compare the contents of both arrays. - l := a.Len() - for i := 0; i < l; i++ { - av := a.Index(i) - bv := b.Index(i) - if av.Interface() == bv.Interface() { - continue - } - return valueSortLess(av, bv) - } - } - return a.String() < b.String() -} - -// Less returns whether the value at index i should sort before the -// value at index j. It is part of the sort.Interface implementation. -func (s *valuesSorter) Less(i, j int) bool { - if s.strings == nil { - return valueSortLess(s.values[i], s.values[j]) - } - return s.strings[i] < s.strings[j] -} - -// sortValues is a sort function that handles both native types and any type that -// can be converted to error or Stringer. Other inputs are sorted according to -// their Value.String() value to ensure display stability. -func sortValues(values []reflect.Value, cs *ConfigState) { - if len(values) == 0 { - return - } - sort.Sort(newValuesSorter(values, cs)) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go deleted file mode 100644 index 2e3d22f3..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/config.go +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "os" -) - -// ConfigState houses the configuration options used by spew to format and -// display values. There is a global instance, Config, that is used to control -// all top-level Formatter and Dump functionality. Each ConfigState instance -// provides methods equivalent to the top-level functions. -// -// The zero value for ConfigState provides no indentation. You would typically -// want to set it to a space or a tab. -// -// Alternatively, you can use NewDefaultConfig to get a ConfigState instance -// with default settings. See the documentation of NewDefaultConfig for default -// values. -type ConfigState struct { - // Indent specifies the string to use for each indentation level. The - // global config instance that all top-level functions use set this to a - // single space by default. If you would like more indentation, you might - // set this to a tab with "\t" or perhaps two spaces with " ". - Indent string - - // MaxDepth controls the maximum number of levels to descend into nested - // data structures. The default, 0, means there is no limit. - // - // NOTE: Circular data structures are properly detected, so it is not - // necessary to set this value unless you specifically want to limit deeply - // nested data structures. - MaxDepth int - - // DisableMethods specifies whether or not error and Stringer interfaces are - // invoked for types that implement them. - DisableMethods bool - - // DisablePointerMethods specifies whether or not to check for and invoke - // error and Stringer interfaces on types which only accept a pointer - // receiver when the current type is not a pointer. - // - // NOTE: This might be an unsafe action since calling one of these methods - // with a pointer receiver could technically mutate the value, however, - // in practice, types which choose to satisify an error or Stringer - // interface with a pointer receiver should not be mutating their state - // inside these interface methods. As a result, this option relies on - // access to the unsafe package, so it will not have any effect when - // running in environments without access to the unsafe package such as - // Google App Engine or with the "safe" build tag specified. - DisablePointerMethods bool - - // DisablePointerAddresses specifies whether to disable the printing of - // pointer addresses. This is useful when diffing data structures in tests. - DisablePointerAddresses bool - - // DisableCapacities specifies whether to disable the printing of capacities - // for arrays, slices, maps and channels. This is useful when diffing - // data structures in tests. - DisableCapacities bool - - // ContinueOnMethod specifies whether or not recursion should continue once - // a custom error or Stringer interface is invoked. The default, false, - // means it will print the results of invoking the custom error or Stringer - // interface and return immediately instead of continuing to recurse into - // the internals of the data type. - // - // NOTE: This flag does not have any effect if method invocation is disabled - // via the DisableMethods or DisablePointerMethods options. - ContinueOnMethod bool - - // SortKeys specifies map keys should be sorted before being printed. Use - // this to have a more deterministic, diffable output. Note that only - // native types (bool, int, uint, floats, uintptr and string) and types - // that support the error or Stringer interfaces (if methods are - // enabled) are supported, with other types sorted according to the - // reflect.Value.String() output which guarantees display stability. - SortKeys bool - - // SpewKeys specifies that, as a last resort attempt, map keys should - // be spewed to strings and sorted by those strings. This is only - // considered if SortKeys is true. - SpewKeys bool -} - -// Config is the active configuration of the top-level functions. -// The configuration can be changed by modifying the contents of spew.Config. -var Config = ConfigState{Indent: " "} - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the formatted string as a value that satisfies error. See NewFormatter -// for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, c.convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, c.convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, c.convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a Formatter interface returned by c.NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, c.convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Print(a ...interface{}) (n int, err error) { - return fmt.Print(c.convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, c.convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Println(a ...interface{}) (n int, err error) { - return fmt.Println(c.convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprint(a ...interface{}) string { - return fmt.Sprint(c.convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, c.convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a Formatter interface returned by c.NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintln(a ...interface{}) string { - return fmt.Sprintln(c.convertArgs(a)...) -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -c.Printf, c.Println, or c.Printf. -*/ -func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(c, v) -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { - fdump(c, w, a...) -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by modifying the public members -of c. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func (c *ConfigState) Dump(a ...interface{}) { - fdump(c, os.Stdout, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func (c *ConfigState) Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(c, &buf, a...) - return buf.String() -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a spew Formatter interface using -// the ConfigState associated with s. -func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = newFormatter(c, arg) - } - return formatters -} - -// NewDefaultConfig returns a ConfigState with the following default settings. -// -// Indent: " " -// MaxDepth: 0 -// DisableMethods: false -// DisablePointerMethods: false -// ContinueOnMethod: false -// SortKeys: false -func NewDefaultConfig() *ConfigState { - return &ConfigState{Indent: " "} -} diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go deleted file mode 100644 index aacaac6f..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/doc.go +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package spew implements a deep pretty printer for Go data structures to aid in -debugging. - -A quick overview of the additional features spew provides over the built-in -printing facilities for Go data types are as follows: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output (only when using - Dump style) - -There are two different approaches spew allows for dumping Go data structures: - - * Dump style which prints with newlines, customizable indentation, - and additional debug information such as types and all pointer addresses - used to indirect to the final value - * A custom Formatter interface that integrates cleanly with the standard fmt - package and replaces %v, %+v, %#v, and %#+v to provide inline printing - similar to the default %v while providing the additional functionality - outlined above and passing unsupported format verbs such as %x and %q - along to fmt - -Quick Start - -This section demonstrates how to quickly get started with spew. See the -sections below for further details on formatting and configuration options. - -To dump a variable with full newlines, indentation, type, and pointer -information use Dump, Fdump, or Sdump: - spew.Dump(myVar1, myVar2, ...) - spew.Fdump(someWriter, myVar1, myVar2, ...) - str := spew.Sdump(myVar1, myVar2, ...) - -Alternatively, if you would prefer to use format strings with a compacted inline -printing style, use the convenience wrappers Printf, Fprintf, etc with -%v (most compact), %+v (adds pointer addresses), %#v (adds types), or -%#+v (adds types and pointer addresses): - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -Configuration Options - -Configuration of spew is handled by fields in the ConfigState type. For -convenience, all of the top-level functions use a global state available -via the spew.Config global. - -It is also possible to create a ConfigState instance that provides methods -equivalent to the top-level functions. This allows concurrent configuration -options. See the ConfigState documentation for more details. - -The following configuration options are available: - * Indent - String to use for each indentation level for Dump functions. - It is a single space by default. A popular alternative is "\t". - - * MaxDepth - Maximum number of levels to descend into nested data structures. - There is no limit by default. - - * DisableMethods - Disables invocation of error and Stringer interface methods. - Method invocation is enabled by default. - - * DisablePointerMethods - Disables invocation of error and Stringer interface methods on types - which only accept pointer receivers from non-pointer variables. - Pointer method invocation is enabled by default. - - * DisablePointerAddresses - DisablePointerAddresses specifies whether to disable the printing of - pointer addresses. This is useful when diffing data structures in tests. - - * DisableCapacities - DisableCapacities specifies whether to disable the printing of - capacities for arrays, slices, maps and channels. This is useful when - diffing data structures in tests. - - * ContinueOnMethod - Enables recursion into types after invoking error and Stringer interface - methods. Recursion after method invocation is disabled by default. - - * SortKeys - Specifies map keys should be sorted before being printed. Use - this to have a more deterministic, diffable output. Note that - only native types (bool, int, uint, floats, uintptr and string) - and types which implement error or Stringer interfaces are - supported with other types sorted according to the - reflect.Value.String() output which guarantees display - stability. Natural map order is used by default. - - * SpewKeys - Specifies that, as a last resort attempt, map keys should be - spewed to strings and sorted by those strings. This is only - considered if SortKeys is true. - -Dump Usage - -Simply call spew.Dump with a list of variables you want to dump: - - spew.Dump(myVar1, myVar2, ...) - -You may also call spew.Fdump if you would prefer to output to an arbitrary -io.Writer. For example, to dump to standard error: - - spew.Fdump(os.Stderr, myVar1, myVar2, ...) - -A third option is to call spew.Sdump to get the formatted output as a string: - - str := spew.Sdump(myVar1, myVar2, ...) - -Sample Dump Output - -See the Dump example for details on the setup of the types and variables being -shown here. - - (main.Foo) { - unexportedField: (*main.Bar)(0xf84002e210)({ - flag: (main.Flag) flagTwo, - data: (uintptr) - }), - ExportedField: (map[interface {}]interface {}) (len=1) { - (string) (len=3) "one": (bool) true - } - } - -Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C -command as shown. - ([]uint8) (len=32 cap=32) { - 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | - 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| - 00000020 31 32 |12| - } - -Custom Formatter - -Spew provides a custom formatter that implements the fmt.Formatter interface -so that it integrates cleanly with standard fmt package printing functions. The -formatter is useful for inline printing of smaller data types similar to the -standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Custom Formatter Usage - -The simplest way to make use of the spew custom formatter is to call one of the -convenience functions such as spew.Printf, spew.Println, or spew.Printf. The -functions have syntax you are most likely already familiar with: - - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Println(myVar, myVar2) - spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -See the Index for the full list convenience functions. - -Sample Formatter Output - -Double pointer to a uint8: - %v: <**>5 - %+v: <**>(0xf8400420d0->0xf8400420c8)5 - %#v: (**uint8)5 - %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 - -Pointer to circular struct with a uint8 field and a pointer to itself: - %v: <*>{1 <*>} - %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} - %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} - %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} - -See the Printf example for details on the setup of variables being shown -here. - -Errors - -Since it is possible for custom Stringer/error interfaces to panic, spew -detects them and handles them internally by printing the panic information -inline with the output. Since spew is intended to provide deep pretty printing -capabilities on structures, it intentionally does not return any errors. -*/ -package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go deleted file mode 100644 index f78d89fc..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/dump.go +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "encoding/hex" - "fmt" - "io" - "os" - "reflect" - "regexp" - "strconv" - "strings" -) - -var ( - // uint8Type is a reflect.Type representing a uint8. It is used to - // convert cgo types to uint8 slices for hexdumping. - uint8Type = reflect.TypeOf(uint8(0)) - - // cCharRE is a regular expression that matches a cgo char. - // It is used to detect character arrays to hexdump them. - cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) - - // cUnsignedCharRE is a regular expression that matches a cgo unsigned - // char. It is used to detect unsigned character arrays to hexdump - // them. - cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) - - // cUint8tCharRE is a regular expression that matches a cgo uint8_t. - // It is used to detect uint8_t arrays to hexdump them. - cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) -) - -// dumpState contains information about the state of a dump operation. -type dumpState struct { - w io.Writer - depth int - pointers map[uintptr]int - ignoreNextType bool - ignoreNextIndent bool - cs *ConfigState -} - -// indent performs indentation according to the depth level and cs.Indent -// option. -func (d *dumpState) indent() { - if d.ignoreNextIndent { - d.ignoreNextIndent = false - return - } - d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) -} - -// unpackValue returns values inside of non-nil interfaces when possible. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - } - return v -} - -// dumpPtr handles formatting of pointers by indirecting them as necessary. -func (d *dumpState) dumpPtr(v reflect.Value) { - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range d.pointers { - if depth >= d.depth { - delete(d.pointers, k) - } - } - - // Keep list of all dereferenced pointers to show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by dereferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := d.pointers[addr]; ok && pd < d.depth { - cycleFound = true - indirects-- - break - } - d.pointers[addr] = d.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type information. - d.w.Write(openParenBytes) - d.w.Write(bytes.Repeat(asteriskBytes, indirects)) - d.w.Write([]byte(ve.Type().String())) - d.w.Write(closeParenBytes) - - // Display pointer information. - if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { - d.w.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - d.w.Write(pointerChainBytes) - } - printHexPtr(d.w, addr) - } - d.w.Write(closeParenBytes) - } - - // Display dereferenced value. - d.w.Write(openParenBytes) - switch { - case nilFound: - d.w.Write(nilAngleBytes) - - case cycleFound: - d.w.Write(circularBytes) - - default: - d.ignoreNextType = true - d.dump(ve) - } - d.w.Write(closeParenBytes) -} - -// dumpSlice handles formatting of arrays and slices. Byte (uint8 under -// reflection) arrays and slices are dumped in hexdump -C fashion. -func (d *dumpState) dumpSlice(v reflect.Value) { - // Determine whether this type should be hex dumped or not. Also, - // for types which should be hexdumped, try to use the underlying data - // first, then fall back to trying to convert them to a uint8 slice. - var buf []uint8 - doConvert := false - doHexDump := false - numEntries := v.Len() - if numEntries > 0 { - vt := v.Index(0).Type() - vts := vt.String() - switch { - // C types that need to be converted. - case cCharRE.MatchString(vts): - fallthrough - case cUnsignedCharRE.MatchString(vts): - fallthrough - case cUint8tCharRE.MatchString(vts): - doConvert = true - - // Try to use existing uint8 slices and fall back to converting - // and copying if that fails. - case vt.Kind() == reflect.Uint8: - // We need an addressable interface to convert the type - // to a byte slice. However, the reflect package won't - // give us an interface on certain things like - // unexported struct fields in order to enforce - // visibility rules. We use unsafe, when available, to - // bypass these restrictions since this package does not - // mutate the values. - vs := v - if !vs.CanInterface() || !vs.CanAddr() { - vs = unsafeReflectValue(vs) - } - if !UnsafeDisabled { - vs = vs.Slice(0, numEntries) - - // Use the existing uint8 slice if it can be - // type asserted. - iface := vs.Interface() - if slice, ok := iface.([]uint8); ok { - buf = slice - doHexDump = true - break - } - } - - // The underlying data needs to be converted if it can't - // be type asserted to a uint8 slice. - doConvert = true - } - - // Copy and convert the underlying type if needed. - if doConvert && vt.ConvertibleTo(uint8Type) { - // Convert and copy each element into a uint8 byte - // slice. - buf = make([]uint8, numEntries) - for i := 0; i < numEntries; i++ { - vv := v.Index(i) - buf[i] = uint8(vv.Convert(uint8Type).Uint()) - } - doHexDump = true - } - } - - // Hexdump the entire slice as needed. - if doHexDump { - indent := strings.Repeat(d.cs.Indent, d.depth) - str := indent + hex.Dump(buf) - str = strings.Replace(str, "\n", "\n"+indent, -1) - str = strings.TrimRight(str, d.cs.Indent) - d.w.Write([]byte(str)) - return - } - - // Recursively call dump for each item. - for i := 0; i < numEntries; i++ { - d.dump(d.unpackValue(v.Index(i))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } -} - -// dump is the main workhorse for dumping a value. It uses the passed reflect -// value to figure out what kind of object we are dealing with and formats it -// appropriately. It is a recursive function, however circular data structures -// are detected and handled properly. -func (d *dumpState) dump(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - d.w.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - d.indent() - d.dumpPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !d.ignoreNextType { - d.indent() - d.w.Write(openParenBytes) - d.w.Write([]byte(v.Type().String())) - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - d.ignoreNextType = false - - // Display length and capacity if the built-in len and cap functions - // work with the value's kind and the len/cap itself is non-zero. - valueLen, valueCap := 0, 0 - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.Chan: - valueLen, valueCap = v.Len(), v.Cap() - case reflect.Map, reflect.String: - valueLen = v.Len() - } - if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { - d.w.Write(openParenBytes) - if valueLen != 0 { - d.w.Write(lenEqualsBytes) - printInt(d.w, int64(valueLen), 10) - } - if !d.cs.DisableCapacities && valueCap != 0 { - if valueLen != 0 { - d.w.Write(spaceBytes) - } - d.w.Write(capEqualsBytes) - printInt(d.w, int64(valueCap), 10) - } - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - - // Call Stringer/error interfaces if they exist and the handle methods flag - // is enabled - if !d.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(d.cs, d.w, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(d.w, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(d.w, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(d.w, v.Uint(), 10) - - case reflect.Float32: - printFloat(d.w, v.Float(), 32) - - case reflect.Float64: - printFloat(d.w, v.Float(), 64) - - case reflect.Complex64: - printComplex(d.w, v.Complex(), 32) - - case reflect.Complex128: - printComplex(d.w, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - d.dumpSlice(v) - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.String: - d.w.Write([]byte(strconv.Quote(v.String()))) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - d.w.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - numEntries := v.Len() - keys := v.MapKeys() - if d.cs.SortKeys { - sortValues(keys, d.cs) - } - for i, key := range keys { - d.dump(d.unpackValue(key)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.MapIndex(key))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Struct: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - vt := v.Type() - numFields := v.NumField() - for i := 0; i < numFields; i++ { - d.indent() - vtf := vt.Field(i) - d.w.Write([]byte(vtf.Name)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.Field(i))) - if i < (numFields - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(d.w, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(d.w, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it in case any new - // types are added. - default: - if v.CanInterface() { - fmt.Fprintf(d.w, "%v", v.Interface()) - } else { - fmt.Fprintf(d.w, "%v", v.String()) - } - } -} - -// fdump is a helper function to consolidate the logic from the various public -// methods which take varying writers and config states. -func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { - for _, arg := range a { - if arg == nil { - w.Write(interfaceBytes) - w.Write(spaceBytes) - w.Write(nilAngleBytes) - w.Write(newlineBytes) - continue - } - - d := dumpState{w: w, cs: cs} - d.pointers = make(map[uintptr]int) - d.dump(reflect.ValueOf(arg)) - d.w.Write(newlineBytes) - } -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func Fdump(w io.Writer, a ...interface{}) { - fdump(&Config, w, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(&Config, &buf, a...) - return buf.String() -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by an exported package global, -spew.Config. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func Dump(a ...interface{}) { - fdump(&Config, os.Stdout, a...) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go deleted file mode 100644 index b04edb7d..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/format.go +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" -) - -// supportedFlags is a list of all the character flags supported by fmt package. -const supportedFlags = "0-+# " - -// formatState implements the fmt.Formatter interface and contains information -// about the state of a formatting operation. The NewFormatter function can -// be used to get a new Formatter which can be used directly as arguments -// in standard fmt package printing calls. -type formatState struct { - value interface{} - fs fmt.State - depth int - pointers map[uintptr]int - ignoreNextType bool - cs *ConfigState -} - -// buildDefaultFormat recreates the original format string without precision -// and width information to pass in to fmt.Sprintf in the case of an -// unrecognized type. Unless new types are added to the language, this -// function won't ever be called. -func (f *formatState) buildDefaultFormat() (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - buf.WriteRune('v') - - format = buf.String() - return format -} - -// constructOrigFormat recreates the original format string including precision -// and width information to pass along to the standard fmt package. This allows -// automatic deferral of all format strings this package doesn't support. -func (f *formatState) constructOrigFormat(verb rune) (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - if width, ok := f.fs.Width(); ok { - buf.WriteString(strconv.Itoa(width)) - } - - if precision, ok := f.fs.Precision(); ok { - buf.Write(precisionBytes) - buf.WriteString(strconv.Itoa(precision)) - } - - buf.WriteRune(verb) - - format = buf.String() - return format -} - -// unpackValue returns values inside of non-nil interfaces when possible and -// ensures that types for values which have been unpacked from an interface -// are displayed when the show types flag is also set. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (f *formatState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface { - f.ignoreNextType = false - if !v.IsNil() { - v = v.Elem() - } - } - return v -} - -// formatPtr handles formatting of pointers by indirecting them as necessary. -func (f *formatState) formatPtr(v reflect.Value) { - // Display nil if top level pointer is nil. - showTypes := f.fs.Flag('#') - if v.IsNil() && (!showTypes || f.ignoreNextType) { - f.fs.Write(nilAngleBytes) - return - } - - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range f.pointers { - if depth >= f.depth { - delete(f.pointers, k) - } - } - - // Keep list of all dereferenced pointers to possibly show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by derferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := f.pointers[addr]; ok && pd < f.depth { - cycleFound = true - indirects-- - break - } - f.pointers[addr] = f.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type or indirection level depending on flags. - if showTypes && !f.ignoreNextType { - f.fs.Write(openParenBytes) - f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) - f.fs.Write([]byte(ve.Type().String())) - f.fs.Write(closeParenBytes) - } else { - if nilFound || cycleFound { - indirects += strings.Count(ve.Type().String(), "*") - } - f.fs.Write(openAngleBytes) - f.fs.Write([]byte(strings.Repeat("*", indirects))) - f.fs.Write(closeAngleBytes) - } - - // Display pointer information depending on flags. - if f.fs.Flag('+') && (len(pointerChain) > 0) { - f.fs.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - f.fs.Write(pointerChainBytes) - } - printHexPtr(f.fs, addr) - } - f.fs.Write(closeParenBytes) - } - - // Display dereferenced value. - switch { - case nilFound: - f.fs.Write(nilAngleBytes) - - case cycleFound: - f.fs.Write(circularShortBytes) - - default: - f.ignoreNextType = true - f.format(ve) - } -} - -// format is the main workhorse for providing the Formatter interface. It -// uses the passed reflect value to figure out what kind of object we are -// dealing with and formats it appropriately. It is a recursive function, -// however circular data structures are detected and handled properly. -func (f *formatState) format(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - f.fs.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - f.formatPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !f.ignoreNextType && f.fs.Flag('#') { - f.fs.Write(openParenBytes) - f.fs.Write([]byte(v.Type().String())) - f.fs.Write(closeParenBytes) - } - f.ignoreNextType = false - - // Call Stringer/error interfaces if they exist and the handle methods - // flag is enabled. - if !f.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(f.cs, f.fs, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(f.fs, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(f.fs, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(f.fs, v.Uint(), 10) - - case reflect.Float32: - printFloat(f.fs, v.Float(), 32) - - case reflect.Float64: - printFloat(f.fs, v.Float(), 64) - - case reflect.Complex64: - printComplex(f.fs, v.Complex(), 32) - - case reflect.Complex128: - printComplex(f.fs, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - f.fs.Write(openBracketBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - numEntries := v.Len() - for i := 0; i < numEntries; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(v.Index(i))) - } - } - f.depth-- - f.fs.Write(closeBracketBytes) - - case reflect.String: - f.fs.Write([]byte(v.String())) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - f.fs.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - - f.fs.Write(openMapBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - keys := v.MapKeys() - if f.cs.SortKeys { - sortValues(keys, f.cs) - } - for i, key := range keys { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(key)) - f.fs.Write(colonBytes) - f.ignoreNextType = true - f.format(f.unpackValue(v.MapIndex(key))) - } - } - f.depth-- - f.fs.Write(closeMapBytes) - - case reflect.Struct: - numFields := v.NumField() - f.fs.Write(openBraceBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - vt := v.Type() - for i := 0; i < numFields; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - vtf := vt.Field(i) - if f.fs.Flag('+') || f.fs.Flag('#') { - f.fs.Write([]byte(vtf.Name)) - f.fs.Write(colonBytes) - } - f.format(f.unpackValue(v.Field(i))) - } - } - f.depth-- - f.fs.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(f.fs, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(f.fs, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it if any get added. - default: - format := f.buildDefaultFormat() - if v.CanInterface() { - fmt.Fprintf(f.fs, format, v.Interface()) - } else { - fmt.Fprintf(f.fs, format, v.String()) - } - } -} - -// Format satisfies the fmt.Formatter interface. See NewFormatter for usage -// details. -func (f *formatState) Format(fs fmt.State, verb rune) { - f.fs = fs - - // Use standard formatting for verbs that are not v. - if verb != 'v' { - format := f.constructOrigFormat(verb) - fmt.Fprintf(fs, format, f.value) - return - } - - if f.value == nil { - if fs.Flag('#') { - fs.Write(interfaceBytes) - } - fs.Write(nilAngleBytes) - return - } - - f.format(reflect.ValueOf(f.value)) -} - -// newFormatter is a helper function to consolidate the logic from the various -// public methods which take varying config states. -func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { - fs := &formatState{value: v, cs: cs} - fs.pointers = make(map[uintptr]int) - return fs -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -Printf, Println, or Fprintf. -*/ -func NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(&Config, v) -} diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go deleted file mode 100644 index 32c0e338..00000000 --- a/vendor/github.com/davecgh/go-spew/spew/spew.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "fmt" - "io" -) - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the formatted string as a value that satisfies error. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a default Formatter interface returned by NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) -func Print(a ...interface{}) (n int, err error) { - return fmt.Print(convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) -func Println(a ...interface{}) (n int, err error) { - return fmt.Println(convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprint(a ...interface{}) string { - return fmt.Sprint(convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintln(a ...interface{}) string { - return fmt.Sprintln(convertArgs(a)...) -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a default spew Formatter interface. -func convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = NewFormatter(arg) - } - return formatters -} diff --git a/vendor/github.com/google/uuid/.travis.yml b/vendor/github.com/google/uuid/.travis.yml deleted file mode 100644 index d8156a60..00000000 --- a/vendor/github.com/google/uuid/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.4.3 - - 1.5.3 - - tip - -script: - - go test -v ./... diff --git a/vendor/github.com/pion/datachannel/AUTHORS.txt b/vendor/github.com/pion/datachannel/AUTHORS.txt deleted file mode 100644 index c5d9d8d3..00000000 --- a/vendor/github.com/pion/datachannel/AUTHORS.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see `.github/generate-authors.sh` for the scripting -Atsushi Watanabe -backkem -Benny Daon -Chinmay Kousik -Eric Daniels -Hugo Arregui -Hugo Arregui -John Bradley -Norman Rasmussen -Sean DuBois -Sean DuBois -Yutaka Takeda diff --git a/vendor/github.com/pion/datachannel/DESIGN.md b/vendor/github.com/pion/datachannel/DESIGN.md deleted file mode 100644 index 55d6c8ff..00000000 --- a/vendor/github.com/pion/datachannel/DESIGN.md +++ /dev/null @@ -1,20 +0,0 @@ -

- Design -

- -### Portable -Pion Data Channels is written in Go and extremely portable. Anywhere Golang runs, Pion Data Channels should work as well! Instead of dealing with complicated -cross-compiling of multiple libraries, you now can run anywhere with one `go build` - -### Simple API -The API is based on an io.ReadWriteCloser. - -### Readable -If code comes from an RFC we try to make sure everything is commented with a link to the spec. -This makes learning and debugging easier, this library was written to also serve as a guide for others. - -### Tested -Every commit is tested via travis-ci Go provides fantastic facilities for testing, and more will be added as time goes on. - -### Shared libraries -Every pion product is built using shared libraries, allowing others to review and reuse our libraries. diff --git a/vendor/github.com/pion/dtls/v2/.editorconfig b/vendor/github.com/pion/dtls/v2/.editorconfig deleted file mode 100644 index 1dca00f8..00000000 --- a/vendor/github.com/pion/dtls/v2/.editorconfig +++ /dev/null @@ -1,23 +0,0 @@ -# http://editorconfig.org/ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -root = true - -[*] -charset = utf-8 -insert_final_newline = true -trim_trailing_whitespace = true -end_of_line = lf - -[*.go] -indent_style = tab -indent_size = 4 - -[{*.yml,*.yaml}] -indent_style = space -indent_size = 2 - -# Makefiles always use tabs for indentation -[Makefile] -indent_style = tab diff --git a/vendor/github.com/pion/dtls/v2/.gitignore b/vendor/github.com/pion/dtls/v2/.gitignore deleted file mode 100644 index 6e2f206a..00000000 --- a/vendor/github.com/pion/dtls/v2/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/dtls/v2/.golangci.yml b/vendor/github.com/pion/dtls/v2/.golangci.yml deleted file mode 100644 index 4e3eddf4..00000000 --- a/vendor/github.com/pion/dtls/v2/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/dtls/v2/.goreleaser.yml b/vendor/github.com/pion/dtls/v2/.goreleaser.yml deleted file mode 100644 index 30093e9d..00000000 --- a/vendor/github.com/pion/dtls/v2/.goreleaser.yml +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -builds: -- skip: true diff --git a/vendor/github.com/pion/dtls/v2/AUTHORS.txt b/vendor/github.com/pion/dtls/v2/AUTHORS.txt deleted file mode 100644 index e14fae4c..00000000 --- a/vendor/github.com/pion/dtls/v2/AUTHORS.txt +++ /dev/null @@ -1,57 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aleksandr Razumov -alvarowolfx -Arlo Breault -Atsushi Watanabe -backkem -bjdgyc -boks1971 -Bragadeesh -Carson Hoffman -Cecylia Bocovich -Chris Hiszpanski -cnderrauber -Daniele Sluijters -folbrich -Hayden James -Hugo Arregui -Hugo Arregui -igolaizola <11333576+igolaizola@users.noreply.github.com> -Jeffrey Stoke -Jeroen de Bruijn -Jeroen de Bruijn -Jim Wert -jinleileiking -Jozef Kralik -Julien Salleyron -Juliusz Chroboczek -Kegan Dougal -Kevin Wang -Lander Noterman -Len -Lukas Lihotzki -ManuelBk <26275612+ManuelBk@users.noreply.github.com> -Michael Zabka -Michiel De Backker -Rachel Chen -Robert Eperjesi -Ryan Gordon -Sam Lancia -Sean DuBois -Sean DuBois -Sean DuBois -Shelikhoo -Stefan Tatschner -Steffen Vogel -Vadim -Vadim Filimonov -wmiao -ZHENK -吕海涛 - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/dtls/v2/LICENSE b/vendor/github.com/pion/dtls/v2/LICENSE deleted file mode 100644 index 491caf6b..00000000 --- a/vendor/github.com/pion/dtls/v2/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2023 The Pion community - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/pion/dtls/v2/README.md b/vendor/github.com/pion/dtls/v2/README.md deleted file mode 100644 index 0c065959..00000000 --- a/vendor/github.com/pion/dtls/v2/README.md +++ /dev/null @@ -1,151 +0,0 @@ -

-
- Pion DTLS -
-

-

A Go implementation of DTLS

-

- Pion DTLS - Sourcegraph Widget - Slack Widget -
- GitHub Workflow Status - Go Reference - Coverage Status - Go Report Card - License: MIT -

-
- -Native [DTLS 1.2][rfc6347] implementation in the Go programming language. - -A long term goal is a professional security review, and maybe an inclusion in stdlib. - -### RFCs -#### Implemented -- **RFC 6347**: [Datagram Transport Layer Security Version 1.2][rfc6347] -- **RFC 5705**: [Keying Material Exporters for Transport Layer Security (TLS)][rfc5705] -- **RFC 7627**: [Transport Layer Security (TLS) - Session Hash and Extended Master Secret Extension][rfc7627] -- **RFC 7301**: [Transport Layer Security (TLS) - Application-Layer Protocol Negotiation Extension][rfc7301] - -[rfc5289]: https://tools.ietf.org/html/rfc5289 -[rfc5487]: https://tools.ietf.org/html/rfc5487 -[rfc5489]: https://tools.ietf.org/html/rfc5489 -[rfc5705]: https://tools.ietf.org/html/rfc5705 -[rfc6347]: https://tools.ietf.org/html/rfc6347 -[rfc6655]: https://tools.ietf.org/html/rfc6655 -[rfc7301]: https://tools.ietf.org/html/rfc7301 -[rfc7627]: https://tools.ietf.org/html/rfc7627 -[rfc8422]: https://tools.ietf.org/html/rfc8422 - -### Goals/Progress -This will only be targeting DTLS 1.2, and the most modern/common cipher suites. -We would love contributions that fall under the 'Planned Features' and any bug fixes! - -#### Current features -* DTLS 1.2 Client/Server -* Key Exchange via ECDHE(curve25519, nistp256, nistp384) and PSK -* Packet loss and re-ordering is handled during handshaking -* Key export ([RFC 5705][rfc5705]) -* Serialization and Resumption of sessions -* Extended Master Secret extension ([RFC 7627][rfc7627]) -* ALPN extension ([RFC 7301][rfc7301]) - -#### Supported ciphers - -##### ECDHE - -* TLS_ECDHE_ECDSA_WITH_AES_128_CCM ([RFC 6655][rfc6655]) -* TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ([RFC 6655][rfc6655]) -* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ([RFC 5289][rfc5289]) -* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ([RFC 5289][rfc5289]) -* TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ([RFC 5289][rfc5289]) -* TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ([RFC 5289][rfc5289]) -* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ([RFC 8422][rfc8422]) -* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ([RFC 8422][rfc8422]) - -##### PSK - -* TLS_PSK_WITH_AES_128_CCM ([RFC 6655][rfc6655]) -* TLS_PSK_WITH_AES_128_CCM_8 ([RFC 6655][rfc6655]) -* TLS_PSK_WITH_AES_256_CCM_8 ([RFC 6655][rfc6655]) -* TLS_PSK_WITH_AES_128_GCM_SHA256 ([RFC 5487][rfc5487]) -* TLS_PSK_WITH_AES_128_CBC_SHA256 ([RFC 5487][rfc5487]) - -##### ECDHE & PSK - -* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 ([RFC 5489][rfc5489]) - -#### Planned Features -* Chacha20Poly1305 - -#### Excluded Features -* DTLS 1.0 -* Renegotiation -* Compression - -### Using - -This library needs at least Go 1.13, and you should have [Go modules -enabled](https://github.com/golang/go/wiki/Modules). - -#### Pion DTLS -For a DTLS 1.2 Server that listens on 127.0.0.1:4444 -```sh -go run examples/listen/selfsign/main.go -``` - -For a DTLS 1.2 Client that connects to 127.0.0.1:4444 -```sh -go run examples/dial/selfsign/main.go -``` - -#### OpenSSL -Pion DTLS can connect to itself and OpenSSL. -``` - // Generate a certificate - openssl ecparam -out key.pem -name prime256v1 -genkey - openssl req -new -sha256 -key key.pem -out server.csr - openssl x509 -req -sha256 -days 365 -in server.csr -signkey key.pem -out cert.pem - - // Use with examples/dial/selfsign/main.go - openssl s_server -dtls1_2 -cert cert.pem -key key.pem -accept 4444 - - // Use with examples/listen/selfsign/main.go - openssl s_client -dtls1_2 -connect 127.0.0.1:4444 -debug -cert cert.pem -key key.pem -``` - -### Using with PSK -Pion DTLS also comes with examples that do key exchange via PSK - -#### Pion DTLS -```sh -go run examples/listen/psk/main.go -``` - -```sh -go run examples/dial/psk/main.go -``` - -#### OpenSSL -``` - // Use with examples/dial/psk/main.go - openssl s_server -dtls1_2 -accept 4444 -nocert -psk abc123 -cipher PSK-AES128-CCM8 - - // Use with examples/listen/psk/main.go - openssl s_client -dtls1_2 -connect 127.0.0.1:4444 -psk abc123 -cipher PSK-AES128-CCM8 -``` - -### Community -Pion has an active community on the [Slack](https://pion.ly/slack). - -Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news. - -We are always looking to support **your projects**. Please reach out if you have something to build! -If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) - -### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) - -### License -MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/dtls/v2/certificate.go b/vendor/github.com/pion/dtls/v2/certificate.go deleted file mode 100644 index 519fc875..00000000 --- a/vendor/github.com/pion/dtls/v2/certificate.go +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "bytes" - "crypto/tls" - "crypto/x509" - "fmt" - "strings" -) - -// ClientHelloInfo contains information from a ClientHello message in order to -// guide application logic in the GetCertificate. -type ClientHelloInfo struct { - // ServerName indicates the name of the server requested by the client - // in order to support virtual hosting. ServerName is only set if the - // client is using SNI (see RFC 4366, Section 3.1). - ServerName string - - // CipherSuites lists the CipherSuites supported by the client (e.g. - // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256). - CipherSuites []CipherSuiteID -} - -// CertificateRequestInfo contains information from a server's -// CertificateRequest message, which is used to demand a certificate and proof -// of control from a client. -type CertificateRequestInfo struct { - // AcceptableCAs contains zero or more, DER-encoded, X.501 - // Distinguished Names. These are the names of root or intermediate CAs - // that the server wishes the returned certificate to be signed by. An - // empty slice indicates that the server has no preference. - AcceptableCAs [][]byte -} - -// SupportsCertificate returns nil if the provided certificate is supported by -// the server that sent the CertificateRequest. Otherwise, it returns an error -// describing the reason for the incompatibility. -// NOTE: original src: https://github.com/golang/go/blob/29b9a328d268d53833d2cc063d1d8b4bf6852675/src/crypto/tls/common.go#L1273 -func (cri *CertificateRequestInfo) SupportsCertificate(c *tls.Certificate) error { - if len(cri.AcceptableCAs) == 0 { - return nil - } - - for j, cert := range c.Certificate { - x509Cert := c.Leaf - // Parse the certificate if this isn't the leaf node, or if - // chain.Leaf was nil. - if j != 0 || x509Cert == nil { - var err error - if x509Cert, err = x509.ParseCertificate(cert); err != nil { - return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err) - } - } - - for _, ca := range cri.AcceptableCAs { - if bytes.Equal(x509Cert.RawIssuer, ca) { - return nil - } - } - } - return errNotAcceptableCertificateChain -} - -func (c *handshakeConfig) setNameToCertificateLocked() { - nameToCertificate := make(map[string]*tls.Certificate) - for i := range c.localCertificates { - cert := &c.localCertificates[i] - x509Cert := cert.Leaf - if x509Cert == nil { - var parseErr error - x509Cert, parseErr = x509.ParseCertificate(cert.Certificate[0]) - if parseErr != nil { - continue - } - } - if len(x509Cert.Subject.CommonName) > 0 { - nameToCertificate[strings.ToLower(x509Cert.Subject.CommonName)] = cert - } - for _, san := range x509Cert.DNSNames { - nameToCertificate[strings.ToLower(san)] = cert - } - } - c.nameToCertificate = nameToCertificate -} - -func (c *handshakeConfig) getCertificate(clientHelloInfo *ClientHelloInfo) (*tls.Certificate, error) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.localGetCertificate != nil && - (len(c.localCertificates) == 0 || len(clientHelloInfo.ServerName) > 0) { - cert, err := c.localGetCertificate(clientHelloInfo) - if cert != nil || err != nil { - return cert, err - } - } - - if c.nameToCertificate == nil { - c.setNameToCertificateLocked() - } - - if len(c.localCertificates) == 0 { - return nil, errNoCertificates - } - - if len(c.localCertificates) == 1 { - // There's only one choice, so no point doing any work. - return &c.localCertificates[0], nil - } - - if len(clientHelloInfo.ServerName) == 0 { - return &c.localCertificates[0], nil - } - - name := strings.TrimRight(strings.ToLower(clientHelloInfo.ServerName), ".") - - if cert, ok := c.nameToCertificate[name]; ok { - return cert, nil - } - - // try replacing labels in the name with wildcards until we get a - // match. - labels := strings.Split(name, ".") - for i := range labels { - labels[i] = "*" - candidate := strings.Join(labels, ".") - if cert, ok := c.nameToCertificate[candidate]; ok { - return cert, nil - } - } - - // If nothing matches, return the first certificate. - return &c.localCertificates[0], nil -} - -// NOTE: original src: https://github.com/golang/go/blob/29b9a328d268d53833d2cc063d1d8b4bf6852675/src/crypto/tls/handshake_client.go#L974 -func (c *handshakeConfig) getClientCertificate(cri *CertificateRequestInfo) (*tls.Certificate, error) { - c.mu.Lock() - defer c.mu.Unlock() - if c.localGetClientCertificate != nil { - return c.localGetClientCertificate(cri) - } - - for i := range c.localCertificates { - chain := c.localCertificates[i] - if err := cri.SupportsCertificate(&chain); err != nil { - continue - } - return &chain, nil - } - - // No acceptable certificate found. Don't send a certificate. - return new(tls.Certificate), nil -} diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite.go b/vendor/github.com/pion/dtls/v2/cipher_suite.go deleted file mode 100644 index 7a5bb4a5..00000000 --- a/vendor/github.com/pion/dtls/v2/cipher_suite.go +++ /dev/null @@ -1,276 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/tls" - "fmt" - "hash" - - "github.com/pion/dtls/v2/internal/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// CipherSuiteID is an ID for our supported CipherSuites -type CipherSuiteID = ciphersuite.ID - -// Supported Cipher Suites -const ( - // AES-128-CCM - TLS_ECDHE_ECDSA_WITH_AES_128_CCM CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM //nolint:revive,stylecheck - TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 //nolint:revive,stylecheck - - // AES-128-GCM-SHA256 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 //nolint:revive,stylecheck - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 CipherSuiteID = ciphersuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 //nolint:revive,stylecheck - - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 //nolint:revive,stylecheck - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 CipherSuiteID = ciphersuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 //nolint:revive,stylecheck - - // AES-256-CBC-SHA - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuiteID = ciphersuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA //nolint:revive,stylecheck - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA CipherSuiteID = ciphersuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA //nolint:revive,stylecheck - - TLS_PSK_WITH_AES_128_CCM CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_CCM //nolint:revive,stylecheck - TLS_PSK_WITH_AES_128_CCM_8 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_CCM_8 //nolint:revive,stylecheck - TLS_PSK_WITH_AES_256_CCM_8 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_256_CCM_8 //nolint:revive,stylecheck - TLS_PSK_WITH_AES_128_GCM_SHA256 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_GCM_SHA256 //nolint:revive,stylecheck - TLS_PSK_WITH_AES_128_CBC_SHA256 CipherSuiteID = ciphersuite.TLS_PSK_WITH_AES_128_CBC_SHA256 //nolint:revive,stylecheck - - TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 CipherSuiteID = ciphersuite.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 //nolint:revive,stylecheck -) - -// CipherSuiteAuthenticationType controls what authentication method is using during the handshake for a CipherSuite -type CipherSuiteAuthenticationType = ciphersuite.AuthenticationType - -// AuthenticationType Enums -const ( - CipherSuiteAuthenticationTypeCertificate CipherSuiteAuthenticationType = ciphersuite.AuthenticationTypeCertificate - CipherSuiteAuthenticationTypePreSharedKey CipherSuiteAuthenticationType = ciphersuite.AuthenticationTypePreSharedKey - CipherSuiteAuthenticationTypeAnonymous CipherSuiteAuthenticationType = ciphersuite.AuthenticationTypeAnonymous -) - -// CipherSuiteKeyExchangeAlgorithm controls what exchange algorithm is using during the handshake for a CipherSuite -type CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithm - -// CipherSuiteKeyExchangeAlgorithm Bitmask -const ( - CipherSuiteKeyExchangeAlgorithmNone CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithmNone - CipherSuiteKeyExchangeAlgorithmPsk CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithmPsk - CipherSuiteKeyExchangeAlgorithmEcdhe CipherSuiteKeyExchangeAlgorithm = ciphersuite.KeyExchangeAlgorithmEcdhe -) - -var _ = allCipherSuites() // Necessary until this function isn't only used by Go 1.14 - -// CipherSuite is an interface that all DTLS CipherSuites must satisfy -type CipherSuite interface { - // String of CipherSuite, only used for logging - String() string - - // ID of CipherSuite. - ID() CipherSuiteID - - // What type of Certificate does this CipherSuite use - CertificateType() clientcertificate.Type - - // What Hash function is used during verification - HashFunc() func() hash.Hash - - // AuthenticationType controls what authentication method is using during the handshake - AuthenticationType() CipherSuiteAuthenticationType - - // KeyExchangeAlgorithm controls what exchange algorithm is using during the handshake - KeyExchangeAlgorithm() CipherSuiteKeyExchangeAlgorithm - - // ECC (Elliptic Curve Cryptography) determines whether ECC extesions will be send during handshake. - // https://datatracker.ietf.org/doc/html/rfc4492#page-10 - ECC() bool - - // Called when keying material has been generated, should initialize the internal cipher - Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error - IsInitialized() bool - Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) - Decrypt(in []byte) ([]byte, error) -} - -// CipherSuiteName provides the same functionality as tls.CipherSuiteName -// that appeared first in Go 1.14. -// -// Our implementation differs slightly in that it takes in a CiperSuiteID, -// like the rest of our library, instead of a uint16 like crypto/tls. -func CipherSuiteName(id CipherSuiteID) string { - suite := cipherSuiteForID(id, nil) - if suite != nil { - return suite.String() - } - return fmt.Sprintf("0x%04X", uint16(id)) -} - -// Taken from https://www.iana.org/assignments/tls-parameters/tls-parameters.xml -// A cipherSuite is a specific combination of key agreement, cipher and MAC -// function. -func cipherSuiteForID(id CipherSuiteID, customCiphers func() []CipherSuite) CipherSuite { - switch id { //nolint:exhaustive - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM: - return ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm() - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: - return ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm8() - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - return &ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{} - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - return &ciphersuite.TLSEcdheRsaWithAes128GcmSha256{} - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - return &ciphersuite.TLSEcdheEcdsaWithAes256CbcSha{} - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return &ciphersuite.TLSEcdheRsaWithAes256CbcSha{} - case TLS_PSK_WITH_AES_128_CCM: - return ciphersuite.NewTLSPskWithAes128Ccm() - case TLS_PSK_WITH_AES_128_CCM_8: - return ciphersuite.NewTLSPskWithAes128Ccm8() - case TLS_PSK_WITH_AES_256_CCM_8: - return ciphersuite.NewTLSPskWithAes256Ccm8() - case TLS_PSK_WITH_AES_128_GCM_SHA256: - return &ciphersuite.TLSPskWithAes128GcmSha256{} - case TLS_PSK_WITH_AES_128_CBC_SHA256: - return &ciphersuite.TLSPskWithAes128CbcSha256{} - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - return &ciphersuite.TLSEcdheEcdsaWithAes256GcmSha384{} - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - return &ciphersuite.TLSEcdheRsaWithAes256GcmSha384{} - case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: - return ciphersuite.NewTLSEcdhePskWithAes128CbcSha256() - } - - if customCiphers != nil { - for _, c := range customCiphers() { - if c.ID() == id { - return c - } - } - } - - return nil -} - -// CipherSuites we support in order of preference -func defaultCipherSuites() []CipherSuite { - return []CipherSuite{ - &ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{}, - &ciphersuite.TLSEcdheRsaWithAes128GcmSha256{}, - &ciphersuite.TLSEcdheEcdsaWithAes256CbcSha{}, - &ciphersuite.TLSEcdheRsaWithAes256CbcSha{}, - &ciphersuite.TLSEcdheEcdsaWithAes256GcmSha384{}, - &ciphersuite.TLSEcdheRsaWithAes256GcmSha384{}, - } -} - -func allCipherSuites() []CipherSuite { - return []CipherSuite{ - ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm(), - ciphersuite.NewTLSEcdheEcdsaWithAes128Ccm8(), - &ciphersuite.TLSEcdheEcdsaWithAes128GcmSha256{}, - &ciphersuite.TLSEcdheRsaWithAes128GcmSha256{}, - &ciphersuite.TLSEcdheEcdsaWithAes256CbcSha{}, - &ciphersuite.TLSEcdheRsaWithAes256CbcSha{}, - ciphersuite.NewTLSPskWithAes128Ccm(), - ciphersuite.NewTLSPskWithAes128Ccm8(), - ciphersuite.NewTLSPskWithAes256Ccm8(), - &ciphersuite.TLSPskWithAes128GcmSha256{}, - &ciphersuite.TLSEcdheEcdsaWithAes256GcmSha384{}, - &ciphersuite.TLSEcdheRsaWithAes256GcmSha384{}, - } -} - -func cipherSuiteIDs(cipherSuites []CipherSuite) []uint16 { - rtrn := []uint16{} - for _, c := range cipherSuites { - rtrn = append(rtrn, uint16(c.ID())) - } - return rtrn -} - -func parseCipherSuites(userSelectedSuites []CipherSuiteID, customCipherSuites func() []CipherSuite, includeCertificateSuites, includePSKSuites bool) ([]CipherSuite, error) { - cipherSuitesForIDs := func(ids []CipherSuiteID) ([]CipherSuite, error) { - cipherSuites := []CipherSuite{} - for _, id := range ids { - c := cipherSuiteForID(id, nil) - if c == nil { - return nil, &invalidCipherSuiteError{id} - } - cipherSuites = append(cipherSuites, c) - } - return cipherSuites, nil - } - - var ( - cipherSuites []CipherSuite - err error - i int - ) - if userSelectedSuites != nil { - cipherSuites, err = cipherSuitesForIDs(userSelectedSuites) - if err != nil { - return nil, err - } - } else { - cipherSuites = defaultCipherSuites() - } - - // Put CustomCipherSuites before ID selected suites - if customCipherSuites != nil { - cipherSuites = append(customCipherSuites(), cipherSuites...) - } - - var foundCertificateSuite, foundPSKSuite, foundAnonymousSuite bool - for _, c := range cipherSuites { - switch { - case includeCertificateSuites && c.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate: - foundCertificateSuite = true - case includePSKSuites && c.AuthenticationType() == CipherSuiteAuthenticationTypePreSharedKey: - foundPSKSuite = true - case c.AuthenticationType() == CipherSuiteAuthenticationTypeAnonymous: - foundAnonymousSuite = true - default: - continue - } - cipherSuites[i] = c - i++ - } - - switch { - case includeCertificateSuites && !foundCertificateSuite && !foundAnonymousSuite: - return nil, errNoAvailableCertificateCipherSuite - case includePSKSuites && !foundPSKSuite: - return nil, errNoAvailablePSKCipherSuite - case i == 0: - return nil, errNoAvailableCipherSuites - } - - return cipherSuites[:i], nil -} - -func filterCipherSuitesForCertificate(cert *tls.Certificate, cipherSuites []CipherSuite) []CipherSuite { - if cert == nil || cert.PrivateKey == nil { - return cipherSuites - } - var certType clientcertificate.Type - switch cert.PrivateKey.(type) { - case ed25519.PrivateKey, *ecdsa.PrivateKey: - certType = clientcertificate.ECDSASign - case *rsa.PrivateKey: - certType = clientcertificate.RSASign - } - - filtered := []CipherSuite{} - for _, c := range cipherSuites { - if c.AuthenticationType() != CipherSuiteAuthenticationTypeCertificate || certType == c.CertificateType() { - filtered = append(filtered, c) - } - } - return filtered -} diff --git a/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go b/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go deleted file mode 100644 index fd46d7bd..00000000 --- a/vendor/github.com/pion/dtls/v2/cipher_suite_go114.go +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build go1.14 -// +build go1.14 - -package dtls - -import ( - "crypto/tls" -) - -// VersionDTLS12 is the DTLS version in the same style as -// VersionTLSXX from crypto/tls -const VersionDTLS12 = 0xfefd - -// Convert from our cipherSuite interface to a tls.CipherSuite struct -func toTLSCipherSuite(c CipherSuite) *tls.CipherSuite { - return &tls.CipherSuite{ - ID: uint16(c.ID()), - Name: c.String(), - SupportedVersions: []uint16{VersionDTLS12}, - Insecure: false, - } -} - -// CipherSuites returns a list of cipher suites currently implemented by this -// package, excluding those with security issues, which are returned by -// InsecureCipherSuites. -func CipherSuites() []*tls.CipherSuite { - suites := allCipherSuites() - res := make([]*tls.CipherSuite, len(suites)) - for i, c := range suites { - res[i] = toTLSCipherSuite(c) - } - return res -} - -// InsecureCipherSuites returns a list of cipher suites currently implemented by -// this package and which have security issues. -func InsecureCipherSuites() []*tls.CipherSuite { - var res []*tls.CipherSuite - return res -} diff --git a/vendor/github.com/pion/dtls/v2/codecov.yml b/vendor/github.com/pion/dtls/v2/codecov.yml deleted file mode 100644 index 263e4d45..00000000 --- a/vendor/github.com/pion/dtls/v2/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/dtls/v2/compression_method.go b/vendor/github.com/pion/dtls/v2/compression_method.go deleted file mode 100644 index 7e44de00..00000000 --- a/vendor/github.com/pion/dtls/v2/compression_method.go +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import "github.com/pion/dtls/v2/pkg/protocol" - -func defaultCompressionMethods() []*protocol.CompressionMethod { - return []*protocol.CompressionMethod{ - {}, - } -} diff --git a/vendor/github.com/pion/dtls/v2/config.go b/vendor/github.com/pion/dtls/v2/config.go deleted file mode 100644 index fbc3ee24..00000000 --- a/vendor/github.com/pion/dtls/v2/config.go +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/tls" - "crypto/x509" - "io" - "time" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/logging" -) - -const keyLogLabelTLS12 = "CLIENT_RANDOM" - -// Config is used to configure a DTLS client or server. -// After a Config is passed to a DTLS function it must not be modified. -type Config struct { - // Certificates contains certificate chain to present to the other side of the connection. - // Server MUST set this if PSK is non-nil - // client SHOULD sets this so CertificateRequests can be handled if PSK is non-nil - Certificates []tls.Certificate - - // CipherSuites is a list of supported cipher suites. - // If CipherSuites is nil, a default list is used - CipherSuites []CipherSuiteID - - // CustomCipherSuites is a list of CipherSuites that can be - // provided by the user. This allow users to user Ciphers that are reserved - // for private usage. - CustomCipherSuites func() []CipherSuite - - // SignatureSchemes contains the signature and hash schemes that the peer requests to verify. - SignatureSchemes []tls.SignatureScheme - - // SRTPProtectionProfiles are the supported protection profiles - // Clients will send this via use_srtp and assert that the server properly responds - // Servers will assert that clients send one of these profiles and will respond as needed - SRTPProtectionProfiles []SRTPProtectionProfile - - // ClientAuth determines the server's policy for - // TLS Client Authentication. The default is NoClientCert. - ClientAuth ClientAuthType - - // RequireExtendedMasterSecret determines if the "Extended Master Secret" extension - // should be disabled, requested, or required (default requested). - ExtendedMasterSecret ExtendedMasterSecretType - - // FlightInterval controls how often we send outbound handshake messages - // defaults to time.Second - FlightInterval time.Duration - - // PSK sets the pre-shared key used by this DTLS connection - // If PSK is non-nil only PSK CipherSuites will be used - PSK PSKCallback - PSKIdentityHint []byte - - // InsecureSkipVerify controls whether a client verifies the - // server's certificate chain and host name. - // If InsecureSkipVerify is true, TLS accepts any certificate - // presented by the server and any host name in that certificate. - // In this mode, TLS is susceptible to man-in-the-middle attacks. - // This should be used only for testing. - InsecureSkipVerify bool - - // InsecureHashes allows the use of hashing algorithms that are known - // to be vulnerable. - InsecureHashes bool - - // VerifyPeerCertificate, if not nil, is called after normal - // certificate verification by either a client or server. It - // receives the certificate provided by the peer and also a flag - // that tells if normal verification has succeedded. If it returns a - // non-nil error, the handshake is aborted and that error results. - // - // If normal verification fails then the handshake will abort before - // considering this callback. If normal verification is disabled by - // setting InsecureSkipVerify, or (for a server) when ClientAuth is - // RequestClientCert or RequireAnyClientCert, then this callback will - // be considered but the verifiedChains will always be nil. - VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error - - // VerifyConnection, if not nil, is called after normal certificate - // verification/PSK and after VerifyPeerCertificate by either a TLS client - // or server. If it returns a non-nil error, the handshake is aborted - // and that error results. - // - // If normal verification fails then the handshake will abort before - // considering this callback. This callback will run for all connections - // regardless of InsecureSkipVerify or ClientAuth settings. - VerifyConnection func(*State) error - - // RootCAs defines the set of root certificate authorities - // that one peer uses when verifying the other peer's certificates. - // If RootCAs is nil, TLS uses the host's root CA set. - RootCAs *x509.CertPool - - // ClientCAs defines the set of root certificate authorities - // that servers use if required to verify a client certificate - // by the policy in ClientAuth. - ClientCAs *x509.CertPool - - // ServerName is used to verify the hostname on the returned - // certificates unless InsecureSkipVerify is given. - ServerName string - - LoggerFactory logging.LoggerFactory - - // ConnectContextMaker is a function to make a context used in Dial(), - // Client(), Server(), and Accept(). If nil, the default ConnectContextMaker - // is used. It can be implemented as following. - // - // func ConnectContextMaker() (context.Context, func()) { - // return context.WithTimeout(context.Background(), 30*time.Second) - // } - ConnectContextMaker func() (context.Context, func()) - - // MTU is the length at which handshake messages will be fragmented to - // fit within the maximum transmission unit (default is 1200 bytes) - MTU int - - // ReplayProtectionWindow is the size of the replay attack protection window. - // Duplication of the sequence number is checked in this window size. - // Packet with sequence number older than this value compared to the latest - // accepted packet will be discarded. (default is 64) - ReplayProtectionWindow int - - // KeyLogWriter optionally specifies a destination for TLS master secrets - // in NSS key log format that can be used to allow external programs - // such as Wireshark to decrypt TLS connections. - // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. - // Use of KeyLogWriter compromises security and should only be - // used for debugging. - KeyLogWriter io.Writer - - // SessionStore is the container to store session for resumption. - SessionStore SessionStore - - // List of application protocols the peer supports, for ALPN - SupportedProtocols []string - - // List of Elliptic Curves to use - // - // If an ECC ciphersuite is configured and EllipticCurves is empty - // it will default to X25519, P-256, P-384 in this specific order. - EllipticCurves []elliptic.Curve - - // GetCertificate returns a Certificate based on the given - // ClientHelloInfo. It will only be called if the client supplies SNI - // information or if Certificates is empty. - // - // If GetCertificate is nil or returns nil, then the certificate is - // retrieved from NameToCertificate. If NameToCertificate is nil, the - // best element of Certificates will be used. - GetCertificate func(*ClientHelloInfo) (*tls.Certificate, error) - - // GetClientCertificate, if not nil, is called when a server requests a - // certificate from a client. If set, the contents of Certificates will - // be ignored. - // - // If GetClientCertificate returns an error, the handshake will be - // aborted and that error will be returned. Otherwise - // GetClientCertificate must return a non-nil Certificate. If - // Certificate.Certificate is empty then no certificate will be sent to - // the server. If this is unacceptable to the server then it may abort - // the handshake. - GetClientCertificate func(*CertificateRequestInfo) (*tls.Certificate, error) - - // InsecureSkipVerifyHello, if true and when acting as server, allow client to - // skip hello verify phase and receive ServerHello after initial ClientHello. - // This have implication on DoS attack resistance. - InsecureSkipVerifyHello bool -} - -func defaultConnectContextMaker() (context.Context, func()) { - return context.WithTimeout(context.Background(), 30*time.Second) -} - -func (c *Config) connectContextMaker() (context.Context, func()) { - if c.ConnectContextMaker == nil { - return defaultConnectContextMaker() - } - return c.ConnectContextMaker() -} - -func (c *Config) includeCertificateSuites() bool { - return c.PSK == nil || len(c.Certificates) > 0 || c.GetCertificate != nil || c.GetClientCertificate != nil -} - -const defaultMTU = 1200 // bytes - -var defaultCurves = []elliptic.Curve{elliptic.X25519, elliptic.P256, elliptic.P384} //nolint:gochecknoglobals - -// PSKCallback is called once we have the remote's PSKIdentityHint. -// If the remote provided none it will be nil -type PSKCallback func([]byte) ([]byte, error) - -// ClientAuthType declares the policy the server will follow for -// TLS Client Authentication. -type ClientAuthType int - -// ClientAuthType enums -const ( - NoClientCert ClientAuthType = iota - RequestClientCert - RequireAnyClientCert - VerifyClientCertIfGiven - RequireAndVerifyClientCert -) - -// ExtendedMasterSecretType declares the policy the client and server -// will follow for the Extended Master Secret extension -type ExtendedMasterSecretType int - -// ExtendedMasterSecretType enums -const ( - RequestExtendedMasterSecret ExtendedMasterSecretType = iota - RequireExtendedMasterSecret - DisableExtendedMasterSecret -) - -func validateConfig(config *Config) error { - switch { - case config == nil: - return errNoConfigProvided - case config.PSKIdentityHint != nil && config.PSK == nil: - return errIdentityNoPSK - } - - for _, cert := range config.Certificates { - if cert.Certificate == nil { - return errInvalidCertificate - } - if cert.PrivateKey != nil { - switch cert.PrivateKey.(type) { - case ed25519.PrivateKey: - case *ecdsa.PrivateKey: - case *rsa.PrivateKey: - default: - return errInvalidPrivateKey - } - } - } - - _, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil) - return err -} diff --git a/vendor/github.com/pion/dtls/v2/conn.go b/vendor/github.com/pion/dtls/v2/conn.go deleted file mode 100644 index 2b758510..00000000 --- a/vendor/github.com/pion/dtls/v2/conn.go +++ /dev/null @@ -1,1032 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "errors" - "fmt" - "io" - "net" - "sync" - "sync/atomic" - "time" - - "github.com/pion/dtls/v2/internal/closer" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" - "github.com/pion/logging" - "github.com/pion/transport/v2/connctx" - "github.com/pion/transport/v2/deadline" - "github.com/pion/transport/v2/replaydetector" -) - -const ( - initialTickerInterval = time.Second - cookieLength = 20 - sessionLength = 32 - defaultNamedCurve = elliptic.X25519 - inboundBufferSize = 8192 - // Default replay protection window is specified by RFC 6347 Section 4.1.2.6 - defaultReplayProtectionWindow = 64 -) - -func invalidKeyingLabels() map[string]bool { - return map[string]bool{ - "client finished": true, - "server finished": true, - "master secret": true, - "key expansion": true, - } -} - -// Conn represents a DTLS connection -type Conn struct { - lock sync.RWMutex // Internal lock (must not be public) - nextConn connctx.ConnCtx // Embedded Conn, typically a udpconn we read/write from - fragmentBuffer *fragmentBuffer // out-of-order and missing fragment handling - handshakeCache *handshakeCache // caching of handshake messages for verifyData generation - decrypted chan interface{} // Decrypted Application Data or error, pull by calling `Read` - - state State // Internal state - - maximumTransmissionUnit int - - handshakeCompletedSuccessfully atomic.Value - - encryptedPackets [][]byte - - connectionClosedByUser bool - closeLock sync.Mutex - closed *closer.Closer - handshakeLoopsFinished sync.WaitGroup - - readDeadline *deadline.Deadline - writeDeadline *deadline.Deadline - - log logging.LeveledLogger - - reading chan struct{} - handshakeRecv chan chan struct{} - cancelHandshaker func() - cancelHandshakeReader func() - - fsm *handshakeFSM - - replayProtectionWindow uint -} - -func createConn(ctx context.Context, nextConn net.Conn, config *Config, isClient bool, initialState *State) (*Conn, error) { - err := validateConfig(config) - if err != nil { - return nil, err - } - - if nextConn == nil { - return nil, errNilNextConn - } - - cipherSuites, err := parseCipherSuites(config.CipherSuites, config.CustomCipherSuites, config.includeCertificateSuites(), config.PSK != nil) - if err != nil { - return nil, err - } - - signatureSchemes, err := signaturehash.ParseSignatureSchemes(config.SignatureSchemes, config.InsecureHashes) - if err != nil { - return nil, err - } - - workerInterval := initialTickerInterval - if config.FlightInterval != 0 { - workerInterval = config.FlightInterval - } - - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - logger := loggerFactory.NewLogger("dtls") - - mtu := config.MTU - if mtu <= 0 { - mtu = defaultMTU - } - - replayProtectionWindow := config.ReplayProtectionWindow - if replayProtectionWindow <= 0 { - replayProtectionWindow = defaultReplayProtectionWindow - } - - c := &Conn{ - nextConn: connctx.New(nextConn), - fragmentBuffer: newFragmentBuffer(), - handshakeCache: newHandshakeCache(), - maximumTransmissionUnit: mtu, - - decrypted: make(chan interface{}, 1), - log: logger, - - readDeadline: deadline.New(), - writeDeadline: deadline.New(), - - reading: make(chan struct{}, 1), - handshakeRecv: make(chan chan struct{}), - closed: closer.NewCloser(), - cancelHandshaker: func() {}, - - replayProtectionWindow: uint(replayProtectionWindow), - - state: State{ - isClient: isClient, - }, - } - - c.setRemoteEpoch(0) - c.setLocalEpoch(0) - - serverName := config.ServerName - // Do not allow the use of an IP address literal as an SNI value. - // See RFC 6066, Section 3. - if net.ParseIP(serverName) != nil { - serverName = "" - } - - curves := config.EllipticCurves - if len(curves) == 0 { - curves = defaultCurves - } - - hsCfg := &handshakeConfig{ - localPSKCallback: config.PSK, - localPSKIdentityHint: config.PSKIdentityHint, - localCipherSuites: cipherSuites, - localSignatureSchemes: signatureSchemes, - extendedMasterSecret: config.ExtendedMasterSecret, - localSRTPProtectionProfiles: config.SRTPProtectionProfiles, - serverName: serverName, - supportedProtocols: config.SupportedProtocols, - clientAuth: config.ClientAuth, - localCertificates: config.Certificates, - insecureSkipVerify: config.InsecureSkipVerify, - verifyPeerCertificate: config.VerifyPeerCertificate, - verifyConnection: config.VerifyConnection, - rootCAs: config.RootCAs, - clientCAs: config.ClientCAs, - customCipherSuites: config.CustomCipherSuites, - retransmitInterval: workerInterval, - log: logger, - initialEpoch: 0, - keyLogWriter: config.KeyLogWriter, - sessionStore: config.SessionStore, - ellipticCurves: curves, - localGetCertificate: config.GetCertificate, - localGetClientCertificate: config.GetClientCertificate, - insecureSkipHelloVerify: config.InsecureSkipVerifyHello, - } - - // rfc5246#section-7.4.3 - // In addition, the hash and signature algorithms MUST be compatible - // with the key in the server's end-entity certificate. - if !isClient { - cert, err := hsCfg.getCertificate(&ClientHelloInfo{}) - if err != nil && !errors.Is(err, errNoCertificates) { - return nil, err - } - hsCfg.localCipherSuites = filterCipherSuitesForCertificate(cert, cipherSuites) - } - - var initialFlight flightVal - var initialFSMState handshakeState - - if initialState != nil { - if c.state.isClient { - initialFlight = flight5 - } else { - initialFlight = flight6 - } - initialFSMState = handshakeFinished - - c.state = *initialState - } else { - if c.state.isClient { - initialFlight = flight1 - } else { - initialFlight = flight0 - } - initialFSMState = handshakePreparing - } - // Do handshake - if err := c.handshake(ctx, hsCfg, initialFlight, initialFSMState); err != nil { - return nil, err - } - - c.log.Trace("Handshake Completed") - - return c, nil -} - -// Dial connects to the given network address and establishes a DTLS connection on top. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, use DialWithContext() instead. -func Dial(network string, raddr *net.UDPAddr, config *Config) (*Conn, error) { - ctx, cancel := config.connectContextMaker() - defer cancel() - - return DialWithContext(ctx, network, raddr, config) -} - -// Client establishes a DTLS connection over an existing connection. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, use ClientWithContext() instead. -func Client(conn net.Conn, config *Config) (*Conn, error) { - ctx, cancel := config.connectContextMaker() - defer cancel() - - return ClientWithContext(ctx, conn, config) -} - -// Server listens for incoming DTLS connections. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, use ServerWithContext() instead. -func Server(conn net.Conn, config *Config) (*Conn, error) { - ctx, cancel := config.connectContextMaker() - defer cancel() - - return ServerWithContext(ctx, conn, config) -} - -// DialWithContext connects to the given network address and establishes a DTLS connection on top. -func DialWithContext(ctx context.Context, network string, raddr *net.UDPAddr, config *Config) (*Conn, error) { - pConn, err := net.DialUDP(network, nil, raddr) - if err != nil { - return nil, err - } - return ClientWithContext(ctx, pConn, config) -} - -// ClientWithContext establishes a DTLS connection over an existing connection. -func ClientWithContext(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) { - switch { - case config == nil: - return nil, errNoConfigProvided - case config.PSK != nil && config.PSKIdentityHint == nil: - return nil, errPSKAndIdentityMustBeSetForClient - } - - return createConn(ctx, conn, config, true, nil) -} - -// ServerWithContext listens for incoming DTLS connections. -func ServerWithContext(ctx context.Context, conn net.Conn, config *Config) (*Conn, error) { - if config == nil { - return nil, errNoConfigProvided - } - - return createConn(ctx, conn, config, false, nil) -} - -// Read reads data from the connection. -func (c *Conn) Read(p []byte) (n int, err error) { - if !c.isHandshakeCompletedSuccessfully() { - return 0, errHandshakeInProgress - } - - select { - case <-c.readDeadline.Done(): - return 0, errDeadlineExceeded - default: - } - - for { - select { - case <-c.readDeadline.Done(): - return 0, errDeadlineExceeded - case out, ok := <-c.decrypted: - if !ok { - return 0, io.EOF - } - switch val := out.(type) { - case ([]byte): - if len(p) < len(val) { - return 0, errBufferTooSmall - } - copy(p, val) - return len(val), nil - case (error): - return 0, val - } - } - } -} - -// Write writes len(p) bytes from p to the DTLS connection -func (c *Conn) Write(p []byte) (int, error) { - if c.isConnectionClosed() { - return 0, ErrConnClosed - } - - select { - case <-c.writeDeadline.Done(): - return 0, errDeadlineExceeded - default: - } - - if !c.isHandshakeCompletedSuccessfully() { - return 0, errHandshakeInProgress - } - - return len(p), c.writePackets(c.writeDeadline, []*packet{ - { - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Epoch: c.state.getLocalEpoch(), - Version: protocol.Version1_2, - }, - Content: &protocol.ApplicationData{ - Data: p, - }, - }, - shouldEncrypt: true, - }, - }) -} - -// Close closes the connection. -func (c *Conn) Close() error { - err := c.close(true) //nolint:contextcheck - c.handshakeLoopsFinished.Wait() - return err -} - -// ConnectionState returns basic DTLS details about the connection. -// Note that this replaced the `Export` function of v1. -func (c *Conn) ConnectionState() State { - c.lock.RLock() - defer c.lock.RUnlock() - return *c.state.clone() -} - -// SelectedSRTPProtectionProfile returns the selected SRTPProtectionProfile -func (c *Conn) SelectedSRTPProtectionProfile() (SRTPProtectionProfile, bool) { - c.lock.RLock() - defer c.lock.RUnlock() - - if c.state.srtpProtectionProfile == 0 { - return 0, false - } - - return c.state.srtpProtectionProfile, true -} - -func (c *Conn) writePackets(ctx context.Context, pkts []*packet) error { - c.lock.Lock() - defer c.lock.Unlock() - - var rawPackets [][]byte - - for _, p := range pkts { - if h, ok := p.record.Content.(*handshake.Handshake); ok { - handshakeRaw, err := p.record.Marshal() - if err != nil { - return err - } - - c.log.Tracef("[handshake:%v] -> %s (epoch: %d, seq: %d)", - srvCliStr(c.state.isClient), h.Header.Type.String(), - p.record.Header.Epoch, h.Header.MessageSequence) - c.handshakeCache.push(handshakeRaw[recordlayer.HeaderSize:], p.record.Header.Epoch, h.Header.MessageSequence, h.Header.Type, c.state.isClient) - - rawHandshakePackets, err := c.processHandshakePacket(p, h) - if err != nil { - return err - } - rawPackets = append(rawPackets, rawHandshakePackets...) - } else { - rawPacket, err := c.processPacket(p) - if err != nil { - return err - } - rawPackets = append(rawPackets, rawPacket) - } - } - if len(rawPackets) == 0 { - return nil - } - compactedRawPackets := c.compactRawPackets(rawPackets) - - for _, compactedRawPackets := range compactedRawPackets { - if _, err := c.nextConn.WriteContext(ctx, compactedRawPackets); err != nil { - return netError(err) - } - } - - return nil -} - -func (c *Conn) compactRawPackets(rawPackets [][]byte) [][]byte { - // avoid a useless copy in the common case - if len(rawPackets) == 1 { - return rawPackets - } - - combinedRawPackets := make([][]byte, 0) - currentCombinedRawPacket := make([]byte, 0) - - for _, rawPacket := range rawPackets { - if len(currentCombinedRawPacket) > 0 && len(currentCombinedRawPacket)+len(rawPacket) >= c.maximumTransmissionUnit { - combinedRawPackets = append(combinedRawPackets, currentCombinedRawPacket) - currentCombinedRawPacket = []byte{} - } - currentCombinedRawPacket = append(currentCombinedRawPacket, rawPacket...) - } - - combinedRawPackets = append(combinedRawPackets, currentCombinedRawPacket) - - return combinedRawPackets -} - -func (c *Conn) processPacket(p *packet) ([]byte, error) { - epoch := p.record.Header.Epoch - for len(c.state.localSequenceNumber) <= int(epoch) { - c.state.localSequenceNumber = append(c.state.localSequenceNumber, uint64(0)) - } - seq := atomic.AddUint64(&c.state.localSequenceNumber[epoch], 1) - 1 - if seq > recordlayer.MaxSequenceNumber { - // RFC 6347 Section 4.1.0 - // The implementation must either abandon an association or rehandshake - // prior to allowing the sequence number to wrap. - return nil, errSequenceNumberOverflow - } - p.record.Header.SequenceNumber = seq - - rawPacket, err := p.record.Marshal() - if err != nil { - return nil, err - } - - if p.shouldEncrypt { - var err error - rawPacket, err = c.state.cipherSuite.Encrypt(p.record, rawPacket) - if err != nil { - return nil, err - } - } - - return rawPacket, nil -} - -func (c *Conn) processHandshakePacket(p *packet, h *handshake.Handshake) ([][]byte, error) { - rawPackets := make([][]byte, 0) - - handshakeFragments, err := c.fragmentHandshake(h) - if err != nil { - return nil, err - } - epoch := p.record.Header.Epoch - for len(c.state.localSequenceNumber) <= int(epoch) { - c.state.localSequenceNumber = append(c.state.localSequenceNumber, uint64(0)) - } - - for _, handshakeFragment := range handshakeFragments { - seq := atomic.AddUint64(&c.state.localSequenceNumber[epoch], 1) - 1 - if seq > recordlayer.MaxSequenceNumber { - return nil, errSequenceNumberOverflow - } - - recordlayerHeader := &recordlayer.Header{ - Version: p.record.Header.Version, - ContentType: p.record.Header.ContentType, - ContentLen: uint16(len(handshakeFragment)), - Epoch: p.record.Header.Epoch, - SequenceNumber: seq, - } - - rawPacket, err := recordlayerHeader.Marshal() - if err != nil { - return nil, err - } - - p.record.Header = *recordlayerHeader - - rawPacket = append(rawPacket, handshakeFragment...) - if p.shouldEncrypt { - var err error - rawPacket, err = c.state.cipherSuite.Encrypt(p.record, rawPacket) - if err != nil { - return nil, err - } - } - - rawPackets = append(rawPackets, rawPacket) - } - - return rawPackets, nil -} - -func (c *Conn) fragmentHandshake(h *handshake.Handshake) ([][]byte, error) { - content, err := h.Message.Marshal() - if err != nil { - return nil, err - } - - fragmentedHandshakes := make([][]byte, 0) - - contentFragments := splitBytes(content, c.maximumTransmissionUnit) - if len(contentFragments) == 0 { - contentFragments = [][]byte{ - {}, - } - } - - offset := 0 - for _, contentFragment := range contentFragments { - contentFragmentLen := len(contentFragment) - - headerFragment := &handshake.Header{ - Type: h.Header.Type, - Length: h.Header.Length, - MessageSequence: h.Header.MessageSequence, - FragmentOffset: uint32(offset), - FragmentLength: uint32(contentFragmentLen), - } - - offset += contentFragmentLen - - fragmentedHandshake, err := headerFragment.Marshal() - if err != nil { - return nil, err - } - - fragmentedHandshake = append(fragmentedHandshake, contentFragment...) - fragmentedHandshakes = append(fragmentedHandshakes, fragmentedHandshake) - } - - return fragmentedHandshakes, nil -} - -var poolReadBuffer = sync.Pool{ //nolint:gochecknoglobals - New: func() interface{} { - b := make([]byte, inboundBufferSize) - return &b - }, -} - -func (c *Conn) readAndBuffer(ctx context.Context) error { - bufptr, ok := poolReadBuffer.Get().(*[]byte) - if !ok { - return errFailedToAccessPoolReadBuffer - } - defer poolReadBuffer.Put(bufptr) - - b := *bufptr - i, err := c.nextConn.ReadContext(ctx, b) - if err != nil { - return netError(err) - } - - pkts, err := recordlayer.UnpackDatagram(b[:i]) - if err != nil { - return err - } - - var hasHandshake bool - for _, p := range pkts { - hs, alert, err := c.handleIncomingPacket(ctx, p, true) - if alert != nil { - if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { - if err == nil { - err = alertErr - } - } - } - if hs { - hasHandshake = true - } - - var e *alertError - if errors.As(err, &e) { - if e.IsFatalOrCloseNotify() { - return e - } - } else if err != nil { - return e - } - } - if hasHandshake { - done := make(chan struct{}) - select { - case c.handshakeRecv <- done: - // If the other party may retransmit the flight, - // we should respond even if it not a new message. - <-done - case <-c.fsm.Done(): - } - } - return nil -} - -func (c *Conn) handleQueuedPackets(ctx context.Context) error { - pkts := c.encryptedPackets - c.encryptedPackets = nil - - for _, p := range pkts { - _, alert, err := c.handleIncomingPacket(ctx, p, false) // don't re-enqueue - if alert != nil { - if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { - if err == nil { - err = alertErr - } - } - } - var e *alertError - if errors.As(err, &e) { - if e.IsFatalOrCloseNotify() { - return e - } - } else if err != nil { - return e - } - } - return nil -} - -func (c *Conn) handleIncomingPacket(ctx context.Context, buf []byte, enqueue bool) (bool, *alert.Alert, error) { //nolint:gocognit - h := &recordlayer.Header{} - if err := h.Unmarshal(buf); err != nil { - // Decode error must be silently discarded - // [RFC6347 Section-4.1.2.7] - c.log.Debugf("discarded broken packet: %v", err) - return false, nil, nil - } - - // Validate epoch - remoteEpoch := c.state.getRemoteEpoch() - if h.Epoch > remoteEpoch { - if h.Epoch > remoteEpoch+1 { - c.log.Debugf("discarded future packet (epoch: %d, seq: %d)", - h.Epoch, h.SequenceNumber, - ) - return false, nil, nil - } - if enqueue { - c.log.Debug("received packet of next epoch, queuing packet") - c.encryptedPackets = append(c.encryptedPackets, buf) - } - return false, nil, nil - } - - // Anti-replay protection - for len(c.state.replayDetector) <= int(h.Epoch) { - c.state.replayDetector = append(c.state.replayDetector, - replaydetector.New(c.replayProtectionWindow, recordlayer.MaxSequenceNumber), - ) - } - markPacketAsValid, ok := c.state.replayDetector[int(h.Epoch)].Check(h.SequenceNumber) - if !ok { - c.log.Debugf("discarded duplicated packet (epoch: %d, seq: %d)", - h.Epoch, h.SequenceNumber, - ) - return false, nil, nil - } - - // Decrypt - if h.Epoch != 0 { - if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() { - if enqueue { - c.encryptedPackets = append(c.encryptedPackets, buf) - c.log.Debug("handshake not finished, queuing packet") - } - return false, nil, nil - } - - var err error - buf, err = c.state.cipherSuite.Decrypt(buf) - if err != nil { - c.log.Debugf("%s: decrypt failed: %s", srvCliStr(c.state.isClient), err) - return false, nil, nil - } - } - - isHandshake, err := c.fragmentBuffer.push(append([]byte{}, buf...)) - if err != nil { - // Decode error must be silently discarded - // [RFC6347 Section-4.1.2.7] - c.log.Debugf("defragment failed: %s", err) - return false, nil, nil - } else if isHandshake { - markPacketAsValid() - for out, epoch := c.fragmentBuffer.pop(); out != nil; out, epoch = c.fragmentBuffer.pop() { - header := &handshake.Header{} - if err := header.Unmarshal(out); err != nil { - c.log.Debugf("%s: handshake parse failed: %s", srvCliStr(c.state.isClient), err) - continue - } - c.handshakeCache.push(out, epoch, header.MessageSequence, header.Type, !c.state.isClient) - } - - return true, nil, nil - } - - r := &recordlayer.RecordLayer{} - if err := r.Unmarshal(buf); err != nil { - return false, &alert.Alert{Level: alert.Fatal, Description: alert.DecodeError}, err - } - - switch content := r.Content.(type) { - case *alert.Alert: - c.log.Tracef("%s: <- %s", srvCliStr(c.state.isClient), content.String()) - var a *alert.Alert - if content.Description == alert.CloseNotify { - // Respond with a close_notify [RFC5246 Section 7.2.1] - a = &alert.Alert{Level: alert.Warning, Description: alert.CloseNotify} - } - markPacketAsValid() - return false, a, &alertError{content} - case *protocol.ChangeCipherSpec: - if c.state.cipherSuite == nil || !c.state.cipherSuite.IsInitialized() { - if enqueue { - c.encryptedPackets = append(c.encryptedPackets, buf) - c.log.Debugf("CipherSuite not initialized, queuing packet") - } - return false, nil, nil - } - - newRemoteEpoch := h.Epoch + 1 - c.log.Tracef("%s: <- ChangeCipherSpec (epoch: %d)", srvCliStr(c.state.isClient), newRemoteEpoch) - - if c.state.getRemoteEpoch()+1 == newRemoteEpoch { - c.setRemoteEpoch(newRemoteEpoch) - markPacketAsValid() - } - case *protocol.ApplicationData: - if h.Epoch == 0 { - return false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, errApplicationDataEpochZero - } - - markPacketAsValid() - - select { - case c.decrypted <- content.Data: - case <-c.closed.Done(): - case <-ctx.Done(): - } - - default: - return false, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, fmt.Errorf("%w: %d", errUnhandledContextType, content.ContentType()) - } - return false, nil, nil -} - -func (c *Conn) recvHandshake() <-chan chan struct{} { - return c.handshakeRecv -} - -func (c *Conn) notify(ctx context.Context, level alert.Level, desc alert.Description) error { - if level == alert.Fatal && len(c.state.SessionID) > 0 { - // According to the RFC, we need to delete the stored session. - // https://datatracker.ietf.org/doc/html/rfc5246#section-7.2 - if ss := c.fsm.cfg.sessionStore; ss != nil { - c.log.Tracef("clean invalid session: %s", c.state.SessionID) - if err := ss.Del(c.sessionKey()); err != nil { - return err - } - } - } - return c.writePackets(ctx, []*packet{ - { - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Epoch: c.state.getLocalEpoch(), - Version: protocol.Version1_2, - }, - Content: &alert.Alert{ - Level: level, - Description: desc, - }, - }, - shouldEncrypt: c.isHandshakeCompletedSuccessfully(), - }, - }) -} - -func (c *Conn) setHandshakeCompletedSuccessfully() { - c.handshakeCompletedSuccessfully.Store(struct{ bool }{true}) -} - -func (c *Conn) isHandshakeCompletedSuccessfully() bool { - boolean, _ := c.handshakeCompletedSuccessfully.Load().(struct{ bool }) - return boolean.bool -} - -func (c *Conn) handshake(ctx context.Context, cfg *handshakeConfig, initialFlight flightVal, initialState handshakeState) error { //nolint:gocognit - c.fsm = newHandshakeFSM(&c.state, c.handshakeCache, cfg, initialFlight) - - done := make(chan struct{}) - ctxRead, cancelRead := context.WithCancel(context.Background()) - c.cancelHandshakeReader = cancelRead - cfg.onFlightState = func(f flightVal, s handshakeState) { - if s == handshakeFinished && !c.isHandshakeCompletedSuccessfully() { - c.setHandshakeCompletedSuccessfully() - close(done) - } - } - - ctxHs, cancel := context.WithCancel(context.Background()) - c.cancelHandshaker = cancel - - firstErr := make(chan error, 1) - - c.handshakeLoopsFinished.Add(2) - - // Handshake routine should be live until close. - // The other party may request retransmission of the last flight to cope with packet drop. - go func() { - defer c.handshakeLoopsFinished.Done() - err := c.fsm.Run(ctxHs, c, initialState) - if !errors.Is(err, context.Canceled) { - select { - case firstErr <- err: - default: - } - } - }() - go func() { - defer func() { - // Escaping read loop. - // It's safe to close decrypted channnel now. - close(c.decrypted) - - // Force stop handshaker when the underlying connection is closed. - cancel() - }() - defer c.handshakeLoopsFinished.Done() - for { - if err := c.readAndBuffer(ctxRead); err != nil { - var e *alertError - if errors.As(err, &e) { - if !e.IsFatalOrCloseNotify() { - if c.isHandshakeCompletedSuccessfully() { - // Pass the error to Read() - select { - case c.decrypted <- err: - case <-c.closed.Done(): - case <-ctxRead.Done(): - } - } - continue // non-fatal alert must not stop read loop - } - } else { - switch { - case errors.Is(err, context.DeadlineExceeded), errors.Is(err, context.Canceled), errors.Is(err, io.EOF): - default: - if c.isHandshakeCompletedSuccessfully() { - // Keep read loop and pass the read error to Read() - select { - case c.decrypted <- err: - case <-c.closed.Done(): - case <-ctxRead.Done(): - } - continue // non-fatal alert must not stop read loop - } - } - } - - select { - case firstErr <- err: - default: - } - - if e != nil { - if e.IsFatalOrCloseNotify() { - _ = c.close(false) //nolint:contextcheck - } - } - if !c.isConnectionClosed() && errors.Is(err, context.Canceled) { - c.log.Trace("handshake timeouts - closing underline connection") - _ = c.close(false) //nolint:contextcheck - } - return - } - } - }() - - select { - case err := <-firstErr: - cancelRead() - cancel() - c.handshakeLoopsFinished.Wait() - return c.translateHandshakeCtxError(err) - case <-ctx.Done(): - cancelRead() - cancel() - c.handshakeLoopsFinished.Wait() - return c.translateHandshakeCtxError(ctx.Err()) - case <-done: - return nil - } -} - -func (c *Conn) translateHandshakeCtxError(err error) error { - if err == nil { - return nil - } - if errors.Is(err, context.Canceled) && c.isHandshakeCompletedSuccessfully() { - return nil - } - return &HandshakeError{Err: err} -} - -func (c *Conn) close(byUser bool) error { - c.cancelHandshaker() - c.cancelHandshakeReader() - - if c.isHandshakeCompletedSuccessfully() && byUser { - // Discard error from notify() to return non-error on the first user call of Close() - // even if the underlying connection is already closed. - _ = c.notify(context.Background(), alert.Warning, alert.CloseNotify) - } - - c.closeLock.Lock() - // Don't return ErrConnClosed at the first time of the call from user. - closedByUser := c.connectionClosedByUser - if byUser { - c.connectionClosedByUser = true - } - isClosed := c.isConnectionClosed() - c.closed.Close() - c.closeLock.Unlock() - - if closedByUser { - return ErrConnClosed - } - - if isClosed { - return nil - } - - return c.nextConn.Close() -} - -func (c *Conn) isConnectionClosed() bool { - select { - case <-c.closed.Done(): - return true - default: - return false - } -} - -func (c *Conn) setLocalEpoch(epoch uint16) { - c.state.localEpoch.Store(epoch) -} - -func (c *Conn) setRemoteEpoch(epoch uint16) { - c.state.remoteEpoch.Store(epoch) -} - -// LocalAddr implements net.Conn.LocalAddr -func (c *Conn) LocalAddr() net.Addr { - return c.nextConn.LocalAddr() -} - -// RemoteAddr implements net.Conn.RemoteAddr -func (c *Conn) RemoteAddr() net.Addr { - return c.nextConn.RemoteAddr() -} - -func (c *Conn) sessionKey() []byte { - if c.state.isClient { - // As ServerName can be like 0.example.com, it's better to add - // delimiter character which is not allowed to be in - // neither address or domain name. - return []byte(c.nextConn.RemoteAddr().String() + "_" + c.fsm.cfg.serverName) - } - return c.state.SessionID -} - -// SetDeadline implements net.Conn.SetDeadline -func (c *Conn) SetDeadline(t time.Time) error { - c.readDeadline.Set(t) - return c.SetWriteDeadline(t) -} - -// SetReadDeadline implements net.Conn.SetReadDeadline -func (c *Conn) SetReadDeadline(t time.Time) error { - c.readDeadline.Set(t) - // Read deadline is fully managed by this layer. - // Don't set read deadline to underlying connection. - return nil -} - -// SetWriteDeadline implements net.Conn.SetWriteDeadline -func (c *Conn) SetWriteDeadline(t time.Time) error { - c.writeDeadline.Set(t) - // Write deadline is also fully managed by this layer. - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/crypto.go b/vendor/github.com/pion/dtls/v2/crypto.go deleted file mode 100644 index 968910c7..00000000 --- a/vendor/github.com/pion/dtls/v2/crypto.go +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/asn1" - "encoding/binary" - "math/big" - "time" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/hash" -) - -type ecdsaSignature struct { - R, S *big.Int -} - -func valueKeyMessage(clientRandom, serverRandom, publicKey []byte, namedCurve elliptic.Curve) []byte { - serverECDHParams := make([]byte, 4) - serverECDHParams[0] = 3 // named curve - binary.BigEndian.PutUint16(serverECDHParams[1:], uint16(namedCurve)) - serverECDHParams[3] = byte(len(publicKey)) - - plaintext := []byte{} - plaintext = append(plaintext, clientRandom...) - plaintext = append(plaintext, serverRandom...) - plaintext = append(plaintext, serverECDHParams...) - plaintext = append(plaintext, publicKey...) - - return plaintext -} - -// If the client provided a "signature_algorithms" extension, then all -// certificates provided by the server MUST be signed by a -// hash/signature algorithm pair that appears in that extension -// -// https://tools.ietf.org/html/rfc5246#section-7.4.2 -func generateKeySignature(clientRandom, serverRandom, publicKey []byte, namedCurve elliptic.Curve, privateKey crypto.PrivateKey, hashAlgorithm hash.Algorithm) ([]byte, error) { - msg := valueKeyMessage(clientRandom, serverRandom, publicKey, namedCurve) - switch p := privateKey.(type) { - case ed25519.PrivateKey: - // https://crypto.stackexchange.com/a/55483 - return p.Sign(rand.Reader, msg, crypto.Hash(0)) - case *ecdsa.PrivateKey: - hashed := hashAlgorithm.Digest(msg) - return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash()) - case *rsa.PrivateKey: - hashed := hashAlgorithm.Digest(msg) - return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash()) - } - - return nil, errKeySignatureGenerateUnimplemented -} - -func verifyKeySignature(message, remoteKeySignature []byte, hashAlgorithm hash.Algorithm, rawCertificates [][]byte) error { //nolint:dupl - if len(rawCertificates) == 0 { - return errLengthMismatch - } - certificate, err := x509.ParseCertificate(rawCertificates[0]) - if err != nil { - return err - } - - switch p := certificate.PublicKey.(type) { - case ed25519.PublicKey: - if ok := ed25519.Verify(p, message, remoteKeySignature); !ok { - return errKeySignatureMismatch - } - return nil - case *ecdsa.PublicKey: - ecdsaSig := &ecdsaSignature{} - if _, err := asn1.Unmarshal(remoteKeySignature, ecdsaSig); err != nil { - return err - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errInvalidECDSASignature - } - hashed := hashAlgorithm.Digest(message) - if !ecdsa.Verify(p, hashed, ecdsaSig.R, ecdsaSig.S) { - return errKeySignatureMismatch - } - return nil - case *rsa.PublicKey: - switch certificate.SignatureAlgorithm { - case x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA: - hashed := hashAlgorithm.Digest(message) - return rsa.VerifyPKCS1v15(p, hashAlgorithm.CryptoHash(), hashed, remoteKeySignature) - default: - return errKeySignatureVerifyUnimplemented - } - } - - return errKeySignatureVerifyUnimplemented -} - -// If the server has sent a CertificateRequest message, the client MUST send the Certificate -// message. The ClientKeyExchange message is now sent, and the content -// of that message will depend on the public key algorithm selected -// between the ClientHello and the ServerHello. If the client has sent -// a certificate with signing ability, a digitally-signed -// CertificateVerify message is sent to explicitly verify possession of -// the private key in the certificate. -// https://tools.ietf.org/html/rfc5246#section-7.3 -func generateCertificateVerify(handshakeBodies []byte, privateKey crypto.PrivateKey, hashAlgorithm hash.Algorithm) ([]byte, error) { - if p, ok := privateKey.(ed25519.PrivateKey); ok { - // https://pkg.go.dev/crypto/ed25519#PrivateKey.Sign - // Sign signs the given message with priv. Ed25519 performs two passes over - // messages to be signed and therefore cannot handle pre-hashed messages. - return p.Sign(rand.Reader, handshakeBodies, crypto.Hash(0)) - } - - h := sha256.New() - if _, err := h.Write(handshakeBodies); err != nil { - return nil, err - } - hashed := h.Sum(nil) - - switch p := privateKey.(type) { - case *ecdsa.PrivateKey: - return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash()) - case *rsa.PrivateKey: - return p.Sign(rand.Reader, hashed, hashAlgorithm.CryptoHash()) - } - - return nil, errInvalidSignatureAlgorithm -} - -func verifyCertificateVerify(handshakeBodies []byte, hashAlgorithm hash.Algorithm, remoteKeySignature []byte, rawCertificates [][]byte) error { //nolint:dupl - if len(rawCertificates) == 0 { - return errLengthMismatch - } - certificate, err := x509.ParseCertificate(rawCertificates[0]) - if err != nil { - return err - } - - switch p := certificate.PublicKey.(type) { - case ed25519.PublicKey: - if ok := ed25519.Verify(p, handshakeBodies, remoteKeySignature); !ok { - return errKeySignatureMismatch - } - return nil - case *ecdsa.PublicKey: - ecdsaSig := &ecdsaSignature{} - if _, err := asn1.Unmarshal(remoteKeySignature, ecdsaSig); err != nil { - return err - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errInvalidECDSASignature - } - hash := hashAlgorithm.Digest(handshakeBodies) - if !ecdsa.Verify(p, hash, ecdsaSig.R, ecdsaSig.S) { - return errKeySignatureMismatch - } - return nil - case *rsa.PublicKey: - switch certificate.SignatureAlgorithm { - case x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA: - hash := hashAlgorithm.Digest(handshakeBodies) - return rsa.VerifyPKCS1v15(p, hashAlgorithm.CryptoHash(), hash, remoteKeySignature) - default: - return errKeySignatureVerifyUnimplemented - } - } - - return errKeySignatureVerifyUnimplemented -} - -func loadCerts(rawCertificates [][]byte) ([]*x509.Certificate, error) { - if len(rawCertificates) == 0 { - return nil, errLengthMismatch - } - - certs := make([]*x509.Certificate, 0, len(rawCertificates)) - for _, rawCert := range rawCertificates { - cert, err := x509.ParseCertificate(rawCert) - if err != nil { - return nil, err - } - certs = append(certs, cert) - } - return certs, nil -} - -func verifyClientCert(rawCertificates [][]byte, roots *x509.CertPool) (chains [][]*x509.Certificate, err error) { - certificate, err := loadCerts(rawCertificates) - if err != nil { - return nil, err - } - intermediateCAPool := x509.NewCertPool() - for _, cert := range certificate[1:] { - intermediateCAPool.AddCert(cert) - } - opts := x509.VerifyOptions{ - Roots: roots, - CurrentTime: time.Now(), - Intermediates: intermediateCAPool, - KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, - } - return certificate[0].Verify(opts) -} - -func verifyServerCert(rawCertificates [][]byte, roots *x509.CertPool, serverName string) (chains [][]*x509.Certificate, err error) { - certificate, err := loadCerts(rawCertificates) - if err != nil { - return nil, err - } - intermediateCAPool := x509.NewCertPool() - for _, cert := range certificate[1:] { - intermediateCAPool.AddCert(cert) - } - opts := x509.VerifyOptions{ - Roots: roots, - CurrentTime: time.Now(), - DNSName: serverName, - Intermediates: intermediateCAPool, - } - return certificate[0].Verify(opts) -} diff --git a/vendor/github.com/pion/dtls/v2/dtls.go b/vendor/github.com/pion/dtls/v2/dtls.go deleted file mode 100644 index b799770d..00000000 --- a/vendor/github.com/pion/dtls/v2/dtls.go +++ /dev/null @@ -1,5 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package dtls implements Datagram Transport Layer Security (DTLS) 1.2 -package dtls diff --git a/vendor/github.com/pion/dtls/v2/errors.go b/vendor/github.com/pion/dtls/v2/errors.go deleted file mode 100644 index 025d8645..00000000 --- a/vendor/github.com/pion/dtls/v2/errors.go +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "errors" - "fmt" - "io" - "net" - "os" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" -) - -// Typed errors -var ( - ErrConnClosed = &FatalError{Err: errors.New("conn is closed")} //nolint:goerr113 - - errDeadlineExceeded = &TimeoutError{Err: fmt.Errorf("read/write timeout: %w", context.DeadlineExceeded)} - errInvalidContentType = &TemporaryError{Err: errors.New("invalid content type")} //nolint:goerr113 - - errBufferTooSmall = &TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 - errContextUnsupported = &TemporaryError{Err: errors.New("context is not supported for ExportKeyingMaterial")} //nolint:goerr113 - errHandshakeInProgress = &TemporaryError{Err: errors.New("handshake is in progress")} //nolint:goerr113 - errReservedExportKeyingMaterial = &TemporaryError{Err: errors.New("ExportKeyingMaterial can not be used with a reserved label")} //nolint:goerr113 - errApplicationDataEpochZero = &TemporaryError{Err: errors.New("ApplicationData with epoch of 0")} //nolint:goerr113 - errUnhandledContextType = &TemporaryError{Err: errors.New("unhandled contentType")} //nolint:goerr113 - - errCertificateVerifyNoCertificate = &FatalError{Err: errors.New("client sent certificate verify but we have no certificate to verify")} //nolint:goerr113 - errCipherSuiteNoIntersection = &FatalError{Err: errors.New("client+server do not support any shared cipher suites")} //nolint:goerr113 - errClientCertificateNotVerified = &FatalError{Err: errors.New("client sent certificate but did not verify it")} //nolint:goerr113 - errClientCertificateRequired = &FatalError{Err: errors.New("server required client verification, but got none")} //nolint:goerr113 - errClientNoMatchingSRTPProfile = &FatalError{Err: errors.New("server responded with SRTP Profile we do not support")} //nolint:goerr113 - errClientRequiredButNoServerEMS = &FatalError{Err: errors.New("client required Extended Master Secret extension, but server does not support it")} //nolint:goerr113 - errCookieMismatch = &FatalError{Err: errors.New("client+server cookie does not match")} //nolint:goerr113 - errIdentityNoPSK = &FatalError{Err: errors.New("PSK Identity Hint provided but PSK is nil")} //nolint:goerr113 - errInvalidCertificate = &FatalError{Err: errors.New("no certificate provided")} //nolint:goerr113 - errInvalidCipherSuite = &FatalError{Err: errors.New("invalid or unknown cipher suite")} //nolint:goerr113 - errInvalidECDSASignature = &FatalError{Err: errors.New("ECDSA signature contained zero or negative values")} //nolint:goerr113 - errInvalidPrivateKey = &FatalError{Err: errors.New("invalid private key type")} //nolint:goerr113 - errInvalidSignatureAlgorithm = &FatalError{Err: errors.New("invalid signature algorithm")} //nolint:goerr113 - errKeySignatureMismatch = &FatalError{Err: errors.New("expected and actual key signature do not match")} //nolint:goerr113 - errNilNextConn = &FatalError{Err: errors.New("Conn can not be created with a nil nextConn")} //nolint:goerr113 - errNoAvailableCipherSuites = &FatalError{Err: errors.New("connection can not be created, no CipherSuites satisfy this Config")} //nolint:goerr113 - errNoAvailablePSKCipherSuite = &FatalError{Err: errors.New("connection can not be created, pre-shared key present but no compatible CipherSuite")} //nolint:goerr113 - errNoAvailableCertificateCipherSuite = &FatalError{Err: errors.New("connection can not be created, certificate present but no compatible CipherSuite")} //nolint:goerr113 - errNoAvailableSignatureSchemes = &FatalError{Err: errors.New("connection can not be created, no SignatureScheme satisfy this Config")} //nolint:goerr113 - errNoCertificates = &FatalError{Err: errors.New("no certificates configured")} //nolint:goerr113 - errNoConfigProvided = &FatalError{Err: errors.New("no config provided")} //nolint:goerr113 - errNoSupportedEllipticCurves = &FatalError{Err: errors.New("client requested zero or more elliptic curves that are not supported by the server")} //nolint:goerr113 - errUnsupportedProtocolVersion = &FatalError{Err: errors.New("unsupported protocol version")} //nolint:goerr113 - errPSKAndIdentityMustBeSetForClient = &FatalError{Err: errors.New("PSK and PSK Identity Hint must both be set for client")} //nolint:goerr113 - errRequestedButNoSRTPExtension = &FatalError{Err: errors.New("SRTP support was requested but server did not respond with use_srtp extension")} //nolint:goerr113 - errServerNoMatchingSRTPProfile = &FatalError{Err: errors.New("client requested SRTP but we have no matching profiles")} //nolint:goerr113 - errServerRequiredButNoClientEMS = &FatalError{Err: errors.New("server requires the Extended Master Secret extension, but the client does not support it")} //nolint:goerr113 - errVerifyDataMismatch = &FatalError{Err: errors.New("expected and actual verify data does not match")} //nolint:goerr113 - errNotAcceptableCertificateChain = &FatalError{Err: errors.New("certificate chain is not signed by an acceptable CA")} //nolint:goerr113 - - errInvalidFlight = &InternalError{Err: errors.New("invalid flight number")} //nolint:goerr113 - errKeySignatureGenerateUnimplemented = &InternalError{Err: errors.New("unable to generate key signature, unimplemented")} //nolint:goerr113 - errKeySignatureVerifyUnimplemented = &InternalError{Err: errors.New("unable to verify key signature, unimplemented")} //nolint:goerr113 - errLengthMismatch = &InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113 - errSequenceNumberOverflow = &InternalError{Err: errors.New("sequence number overflow")} //nolint:goerr113 - errInvalidFSMTransition = &InternalError{Err: errors.New("invalid state machine transition")} //nolint:goerr113 - errFailedToAccessPoolReadBuffer = &InternalError{Err: errors.New("failed to access pool read buffer")} //nolint:goerr113 - errFragmentBufferOverflow = &InternalError{Err: errors.New("fragment buffer overflow")} //nolint:goerr113 -) - -// FatalError indicates that the DTLS connection is no longer available. -// It is mainly caused by wrong configuration of server or client. -type FatalError = protocol.FatalError - -// InternalError indicates and internal error caused by the implementation, and the DTLS connection is no longer available. -// It is mainly caused by bugs or tried to use unimplemented features. -type InternalError = protocol.InternalError - -// TemporaryError indicates that the DTLS connection is still available, but the request was failed temporary. -type TemporaryError = protocol.TemporaryError - -// TimeoutError indicates that the request was timed out. -type TimeoutError = protocol.TimeoutError - -// HandshakeError indicates that the handshake failed. -type HandshakeError = protocol.HandshakeError - -// errInvalidCipherSuite indicates an attempt at using an unsupported cipher suite. -type invalidCipherSuiteError struct { - id CipherSuiteID -} - -func (e *invalidCipherSuiteError) Error() string { - return fmt.Sprintf("CipherSuite with id(%d) is not valid", e.id) -} - -func (e *invalidCipherSuiteError) Is(err error) bool { - var other *invalidCipherSuiteError - if errors.As(err, &other) { - return e.id == other.id - } - return false -} - -// errAlert wraps DTLS alert notification as an error -type alertError struct { - *alert.Alert -} - -func (e *alertError) Error() string { - return fmt.Sprintf("alert: %s", e.Alert.String()) -} - -func (e *alertError) IsFatalOrCloseNotify() bool { - return e.Level == alert.Fatal || e.Description == alert.CloseNotify -} - -func (e *alertError) Is(err error) bool { - var other *alertError - if errors.As(err, &other) { - return e.Level == other.Level && e.Description == other.Description - } - return false -} - -// netError translates an error from underlying Conn to corresponding net.Error. -func netError(err error) error { - switch { - case errors.Is(err, io.EOF), errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded): - // Return io.EOF and context errors as is. - return err - } - - var ( - ne net.Error - opError *net.OpError - se *os.SyscallError - ) - - if errors.As(err, &opError) { - if errors.As(opError, &se) { - if se.Timeout() { - return &TimeoutError{Err: err} - } - if isOpErrorTemporary(se) { - return &TemporaryError{Err: err} - } - } - } - - if errors.As(err, &ne) { - return err - } - - return &FatalError{Err: err} -} diff --git a/vendor/github.com/pion/dtls/v2/errors_errno.go b/vendor/github.com/pion/dtls/v2/errors_errno.go deleted file mode 100644 index f8e424eb..00000000 --- a/vendor/github.com/pion/dtls/v2/errors_errno.go +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build aix || darwin || dragonfly || freebsd || linux || nacl || nacljs || netbsd || openbsd || solaris || windows -// +build aix darwin dragonfly freebsd linux nacl nacljs netbsd openbsd solaris windows - -// For systems having syscall.Errno. -// Update build targets by following command: -// $ grep -R ECONN $(go env GOROOT)/src/syscall/zerrors_*.go \ -// | tr "." "_" | cut -d"_" -f"2" | sort | uniq - -package dtls - -import ( - "errors" - "os" - "syscall" -) - -func isOpErrorTemporary(err *os.SyscallError) bool { - return errors.Is(err.Err, syscall.ECONNREFUSED) -} diff --git a/vendor/github.com/pion/dtls/v2/errors_noerrno.go b/vendor/github.com/pion/dtls/v2/errors_noerrno.go deleted file mode 100644 index 844ff1e7..00000000 --- a/vendor/github.com/pion/dtls/v2/errors_noerrno.go +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !nacl && !nacljs && !netbsd && !openbsd && !solaris && !windows -// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!nacl,!nacljs,!netbsd,!openbsd,!solaris,!windows - -// For systems without syscall.Errno. -// Build targets must be inverse of errors_errno.go - -package dtls - -import ( - "os" -) - -func isOpErrorTemporary(err *os.SyscallError) bool { - return false -} diff --git a/vendor/github.com/pion/dtls/v2/flight.go b/vendor/github.com/pion/dtls/v2/flight.go deleted file mode 100644 index cfa58c57..00000000 --- a/vendor/github.com/pion/dtls/v2/flight.go +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -/* - DTLS messages are grouped into a series of message flights, according - to the diagrams below. Although each flight of messages may consist - of a number of messages, they should be viewed as monolithic for the - purpose of timeout and retransmission. - https://tools.ietf.org/html/rfc4347#section-4.2.4 - - Message flights for full handshake: - - Client Server - ------ ------ - Waiting Flight 0 - - ClientHello --------> Flight 1 - - <------- HelloVerifyRequest Flight 2 - - ClientHello --------> Flight 3 - - ServerHello \ - Certificate* \ - ServerKeyExchange* Flight 4 - CertificateRequest* / - <-------- ServerHelloDone / - - Certificate* \ - ClientKeyExchange \ - CertificateVerify* Flight 5 - [ChangeCipherSpec] / - Finished --------> / - - [ChangeCipherSpec] \ Flight 6 - <-------- Finished / - - Message flights for session-resuming handshake (no cookie exchange): - - Client Server - ------ ------ - Waiting Flight 0 - - ClientHello --------> Flight 1 - - ServerHello \ - [ChangeCipherSpec] Flight 4b - <-------- Finished / - - [ChangeCipherSpec] \ Flight 5b - Finished --------> / - - [ChangeCipherSpec] \ Flight 6 - <-------- Finished / -*/ - -type flightVal uint8 - -const ( - flight0 flightVal = iota + 1 - flight1 - flight2 - flight3 - flight4 - flight4b - flight5 - flight5b - flight6 -) - -func (f flightVal) String() string { - switch f { - case flight0: - return "Flight 0" - case flight1: - return "Flight 1" - case flight2: - return "Flight 2" - case flight3: - return "Flight 3" - case flight4: - return "Flight 4" - case flight4b: - return "Flight 4b" - case flight5: - return "Flight 5" - case flight5b: - return "Flight 5b" - case flight6: - return "Flight 6" - default: - return "Invalid Flight" - } -} - -func (f flightVal) isLastSendFlight() bool { - return f == flight6 || f == flight5b -} - -func (f flightVal) isLastRecvFlight() bool { - return f == flight5 || f == flight4b -} diff --git a/vendor/github.com/pion/dtls/v2/flight0handler.go b/vendor/github.com/pion/dtls/v2/flight0handler.go deleted file mode 100644 index ec766ddf..00000000 --- a/vendor/github.com/pion/dtls/v2/flight0handler.go +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "crypto/rand" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" -) - -func flight0Parse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - seq, msgs, ok := cache.fullPullMap(0, state.cipherSuite, - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - state.handshakeRecvSequence = seq - - var clientHello *handshake.MessageClientHello - - // Validate type - if clientHello, ok = msgs[handshake.TypeClientHello].(*handshake.MessageClientHello); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - - if !clientHello.Version.Equal(protocol.Version1_2) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion - } - - state.remoteRandom = clientHello.Random - - cipherSuites := []CipherSuite{} - for _, id := range clientHello.CipherSuiteIDs { - if c := cipherSuiteForID(CipherSuiteID(id), cfg.customCipherSuites); c != nil { - cipherSuites = append(cipherSuites, c) - } - } - - if state.cipherSuite, ok = findMatchingCipherSuite(cipherSuites, cfg.localCipherSuites); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errCipherSuiteNoIntersection - } - - for _, val := range clientHello.Extensions { - switch e := val.(type) { - case *extension.SupportedEllipticCurves: - if len(e.EllipticCurves) == 0 { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errNoSupportedEllipticCurves - } - state.namedCurve = e.EllipticCurves[0] - case *extension.UseSRTP: - profile, ok := findMatchingSRTPProfile(e.ProtectionProfiles, cfg.localSRTPProtectionProfiles) - if !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerNoMatchingSRTPProfile - } - state.srtpProtectionProfile = profile - case *extension.UseExtendedMasterSecret: - if cfg.extendedMasterSecret != DisableExtendedMasterSecret { - state.extendedMasterSecret = true - } - case *extension.ServerName: - state.serverName = e.ServerName // remote server name - case *extension.ALPN: - state.peerSupportedProtocols = e.ProtocolNameList - } - } - - if cfg.extendedMasterSecret == RequireExtendedMasterSecret && !state.extendedMasterSecret { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errServerRequiredButNoClientEMS - } - - if state.localKeypair == nil { - var err error - state.localKeypair, err = elliptic.GenerateKeypair(state.namedCurve) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, err - } - } - - nextFlight := flight2 - - if cfg.insecureSkipHelloVerify { - nextFlight = flight4 - } - - return handleHelloResume(clientHello.SessionID, state, cfg, nextFlight) -} - -func handleHelloResume(sessionID []byte, state *State, cfg *handshakeConfig, next flightVal) (flightVal, *alert.Alert, error) { - if len(sessionID) > 0 && cfg.sessionStore != nil { - if s, err := cfg.sessionStore.Get(sessionID); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } else if s.ID != nil { - cfg.log.Tracef("[handshake] resume session: %x", sessionID) - - state.SessionID = sessionID - state.masterSecret = s.Secret - - if err := state.initCipherSuite(); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - clientRandom := state.localRandom.MarshalFixed() - cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret) - - return flight4b, nil, nil - } - } - return next, nil, nil -} - -func flight0Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { - // Initialize - if !cfg.insecureSkipHelloVerify { - state.cookie = make([]byte, cookieLength) - if _, err := rand.Read(state.cookie); err != nil { - return nil, nil, err - } - } - - var zeroEpoch uint16 - state.localEpoch.Store(zeroEpoch) - state.remoteEpoch.Store(zeroEpoch) - state.namedCurve = defaultNamedCurve - - if err := state.localRandom.Populate(); err != nil { - return nil, nil, err - } - - return nil, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flight1handler.go b/vendor/github.com/pion/dtls/v2/flight1handler.go deleted file mode 100644 index 94fdc222..00000000 --- a/vendor/github.com/pion/dtls/v2/flight1handler.go +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight1Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - // HelloVerifyRequest can be skipped by the server, - // so allow ServerHello during flight1 also - seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite, - handshakeCachePullRule{handshake.TypeHelloVerifyRequest, cfg.initialEpoch, false, true}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, true}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - - if _, ok := msgs[handshake.TypeServerHello]; ok { - // Flight1 and flight2 were skipped. - // Parse as flight3. - return flight3Parse(ctx, c, state, cache, cfg) - } - - if h, ok := msgs[handshake.TypeHelloVerifyRequest].(*handshake.MessageHelloVerifyRequest); ok { - // DTLS 1.2 clients must not assume that the server will use the protocol version - // specified in HelloVerifyRequest message. RFC 6347 Section 4.2.1 - if !h.Version.Equal(protocol.Version1_0) && !h.Version.Equal(protocol.Version1_2) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion - } - state.cookie = append([]byte{}, h.Cookie...) - state.handshakeRecvSequence = seq - return flight3, nil, nil - } - - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil -} - -func flight1Generate(c flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { - var zeroEpoch uint16 - state.localEpoch.Store(zeroEpoch) - state.remoteEpoch.Store(zeroEpoch) - state.namedCurve = defaultNamedCurve - state.cookie = nil - - if err := state.localRandom.Populate(); err != nil { - return nil, nil, err - } - - extensions := []extension.Extension{ - &extension.SupportedSignatureAlgorithms{ - SignatureHashAlgorithms: cfg.localSignatureSchemes, - }, - &extension.RenegotiationInfo{ - RenegotiatedConnection: 0, - }, - } - - var setEllipticCurveCryptographyClientHelloExtensions bool - for _, c := range cfg.localCipherSuites { - if c.ECC() { - setEllipticCurveCryptographyClientHelloExtensions = true - break - } - } - - if setEllipticCurveCryptographyClientHelloExtensions { - extensions = append(extensions, []extension.Extension{ - &extension.SupportedEllipticCurves{ - EllipticCurves: cfg.ellipticCurves, - }, - &extension.SupportedPointFormats{ - PointFormats: []elliptic.CurvePointFormat{elliptic.CurvePointFormatUncompressed}, - }, - }...) - } - - if len(cfg.localSRTPProtectionProfiles) > 0 { - extensions = append(extensions, &extension.UseSRTP{ - ProtectionProfiles: cfg.localSRTPProtectionProfiles, - }) - } - - if cfg.extendedMasterSecret == RequestExtendedMasterSecret || - cfg.extendedMasterSecret == RequireExtendedMasterSecret { - extensions = append(extensions, &extension.UseExtendedMasterSecret{ - Supported: true, - }) - } - - if len(cfg.serverName) > 0 { - extensions = append(extensions, &extension.ServerName{ServerName: cfg.serverName}) - } - - if len(cfg.supportedProtocols) > 0 { - extensions = append(extensions, &extension.ALPN{ProtocolNameList: cfg.supportedProtocols}) - } - - if cfg.sessionStore != nil { - cfg.log.Tracef("[handshake] try to resume session") - if s, err := cfg.sessionStore.Get(c.sessionKey()); err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } else if s.ID != nil { - cfg.log.Tracef("[handshake] get saved session: %x", s.ID) - - state.SessionID = s.ID - state.masterSecret = s.Secret - } - } - - return []*packet{ - { - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageClientHello{ - Version: protocol.Version1_2, - SessionID: state.SessionID, - Cookie: state.cookie, - Random: state.localRandom, - CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites), - CompressionMethods: defaultCompressionMethods(), - Extensions: extensions, - }, - }, - }, - }, - }, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flight2handler.go b/vendor/github.com/pion/dtls/v2/flight2handler.go deleted file mode 100644 index 26e57d2f..00000000 --- a/vendor/github.com/pion/dtls/v2/flight2handler.go +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "bytes" - "context" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight2Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite, - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - ) - if !ok { - // Client may retransmit the first ClientHello when HelloVerifyRequest is dropped. - // Parse as flight 0 in this case. - return flight0Parse(ctx, c, state, cache, cfg) - } - state.handshakeRecvSequence = seq - - var clientHello *handshake.MessageClientHello - - // Validate type - if clientHello, ok = msgs[handshake.TypeClientHello].(*handshake.MessageClientHello); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - - if !clientHello.Version.Equal(protocol.Version1_2) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion - } - - if len(clientHello.Cookie) == 0 { - return 0, nil, nil - } - if !bytes.Equal(state.cookie, clientHello.Cookie) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.AccessDenied}, errCookieMismatch - } - return flight4, nil, nil -} - -func flight2Generate(_ flightConn, state *State, _ *handshakeCache, _ *handshakeConfig) ([]*packet, *alert.Alert, error) { - state.handshakeSendSequence = 0 - return []*packet{ - { - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageHelloVerifyRequest{ - Version: protocol.Version1_2, - Cookie: state.cookie, - }, - }, - }, - }, - }, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flight3handler.go b/vendor/github.com/pion/dtls/v2/flight3handler.go deleted file mode 100644 index 5a763dc0..00000000 --- a/vendor/github.com/pion/dtls/v2/flight3handler.go +++ /dev/null @@ -1,291 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "bytes" - "context" - - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight3Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { //nolint:gocognit - // Clients may receive multiple HelloVerifyRequest messages with different cookies. - // Clients SHOULD handle this by sending a new ClientHello with a cookie in response - // to the new HelloVerifyRequest. RFC 6347 Section 4.2.1 - seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite, - handshakeCachePullRule{handshake.TypeHelloVerifyRequest, cfg.initialEpoch, false, true}, - ) - if ok { - if h, msgOk := msgs[handshake.TypeHelloVerifyRequest].(*handshake.MessageHelloVerifyRequest); msgOk { - // DTLS 1.2 clients must not assume that the server will use the protocol version - // specified in HelloVerifyRequest message. RFC 6347 Section 4.2.1 - if !h.Version.Equal(protocol.Version1_0) && !h.Version.Equal(protocol.Version1_2) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion - } - state.cookie = append([]byte{}, h.Cookie...) - state.handshakeRecvSequence = seq - return flight3, nil, nil - } - } - - _, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - ) - if !ok { - // Don't have enough messages. Keep reading - return 0, nil, nil - } - - if h, msgOk := msgs[handshake.TypeServerHello].(*handshake.MessageServerHello); msgOk { - if !h.Version.Equal(protocol.Version1_2) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion - } - for _, v := range h.Extensions { - switch e := v.(type) { - case *extension.UseSRTP: - profile, found := findMatchingSRTPProfile(e.ProtectionProfiles, cfg.localSRTPProtectionProfiles) - if !found { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, errClientNoMatchingSRTPProfile - } - state.srtpProtectionProfile = profile - case *extension.UseExtendedMasterSecret: - if cfg.extendedMasterSecret != DisableExtendedMasterSecret { - state.extendedMasterSecret = true - } - case *extension.ALPN: - if len(e.ProtocolNameList) > 1 { // This should be exactly 1, the zero case is handle when unmarshalling - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, extension.ErrALPNInvalidFormat // Meh, internal error? - } - state.NegotiatedProtocol = e.ProtocolNameList[0] - } - } - if cfg.extendedMasterSecret == RequireExtendedMasterSecret && !state.extendedMasterSecret { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errClientRequiredButNoServerEMS - } - if len(cfg.localSRTPProtectionProfiles) > 0 && state.srtpProtectionProfile == 0 { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errRequestedButNoSRTPExtension - } - - remoteCipherSuite := cipherSuiteForID(CipherSuiteID(*h.CipherSuiteID), cfg.customCipherSuites) - if remoteCipherSuite == nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errCipherSuiteNoIntersection - } - - selectedCipherSuite, found := findMatchingCipherSuite([]CipherSuite{remoteCipherSuite}, cfg.localCipherSuites) - if !found { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errInvalidCipherSuite - } - - state.cipherSuite = selectedCipherSuite - state.remoteRandom = h.Random - cfg.log.Tracef("[handshake] use cipher suite: %s", selectedCipherSuite.String()) - - if len(h.SessionID) > 0 && bytes.Equal(state.SessionID, h.SessionID) { - return handleResumption(ctx, c, state, cache, cfg) - } - - if len(state.SessionID) > 0 { - cfg.log.Tracef("[handshake] clean old session : %s", state.SessionID) - if err := cfg.sessionStore.Del(state.SessionID); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - if cfg.sessionStore == nil { - state.SessionID = []byte{} - } else { - state.SessionID = h.SessionID - } - - state.masterSecret = []byte{} - } - - if cfg.localPSKCallback != nil { - seq, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence+1, state.cipherSuite, - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, true}, - handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false}, - ) - } else { - seq, msgs, ok = cache.fullPullMap(state.handshakeRecvSequence+1, state.cipherSuite, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, true}, - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, true}, - handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false}, - ) - } - if !ok { - // Don't have enough messages. Keep reading - return 0, nil, nil - } - state.handshakeRecvSequence = seq - - if h, ok := msgs[handshake.TypeCertificate].(*handshake.MessageCertificate); ok { - state.PeerCertificates = h.Certificate - } else if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errInvalidCertificate - } - - if h, ok := msgs[handshake.TypeServerKeyExchange].(*handshake.MessageServerKeyExchange); ok { - alertPtr, err := handleServerKeyExchange(c, state, cfg, h) - if err != nil { - return 0, alertPtr, err - } - } - - if _, ok := msgs[handshake.TypeCertificateRequest].(*handshake.MessageCertificateRequest); ok { - state.remoteRequestedCertificate = true - } - - return flight5, nil, nil -} - -func handleResumption(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - if err := state.initCipherSuite(); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - // Now, encrypted packets can be handled - if err := c.handleQueuedPackets(ctx); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence+1, state.cipherSuite, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - - var finished *handshake.MessageFinished - if finished, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - ) - - expectedVerifyData, err := prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc()) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - if !bytes.Equal(expectedVerifyData, finished.VerifyData) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errVerifyDataMismatch - } - - clientRandom := state.localRandom.MarshalFixed() - cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret) - - return flight5b, nil, nil -} - -func handleServerKeyExchange(_ flightConn, state *State, cfg *handshakeConfig, h *handshake.MessageServerKeyExchange) (*alert.Alert, error) { - var err error - if state.cipherSuite == nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errInvalidCipherSuite - } - if cfg.localPSKCallback != nil { - var psk []byte - if psk, err = cfg.localPSKCallback(h.IdentityHint); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - state.IdentityHint = h.IdentityHint - switch state.cipherSuite.KeyExchangeAlgorithm() { - case types.KeyExchangeAlgorithmPsk: - state.preMasterSecret = prf.PSKPreMasterSecret(psk) - case (types.KeyExchangeAlgorithmEcdhe | types.KeyExchangeAlgorithmPsk): - if state.localKeypair, err = elliptic.GenerateKeypair(h.NamedCurve); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - state.preMasterSecret, err = prf.EcdhePSKPreMasterSecret(psk, h.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve) - if err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - default: - return &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errInvalidCipherSuite - } - } else { - if state.localKeypair, err = elliptic.GenerateKeypair(h.NamedCurve); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - if state.preMasterSecret, err = prf.PreMasterSecret(h.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - return nil, nil //nolint:nilnil -} - -func flight3Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { - extensions := []extension.Extension{ - &extension.SupportedSignatureAlgorithms{ - SignatureHashAlgorithms: cfg.localSignatureSchemes, - }, - &extension.RenegotiationInfo{ - RenegotiatedConnection: 0, - }, - } - if state.namedCurve != 0 { - extensions = append(extensions, []extension.Extension{ - &extension.SupportedEllipticCurves{ - EllipticCurves: []elliptic.Curve{elliptic.X25519, elliptic.P256, elliptic.P384}, - }, - &extension.SupportedPointFormats{ - PointFormats: []elliptic.CurvePointFormat{elliptic.CurvePointFormatUncompressed}, - }, - }...) - } - - if len(cfg.localSRTPProtectionProfiles) > 0 { - extensions = append(extensions, &extension.UseSRTP{ - ProtectionProfiles: cfg.localSRTPProtectionProfiles, - }) - } - - if cfg.extendedMasterSecret == RequestExtendedMasterSecret || - cfg.extendedMasterSecret == RequireExtendedMasterSecret { - extensions = append(extensions, &extension.UseExtendedMasterSecret{ - Supported: true, - }) - } - - if len(cfg.serverName) > 0 { - extensions = append(extensions, &extension.ServerName{ServerName: cfg.serverName}) - } - - if len(cfg.supportedProtocols) > 0 { - extensions = append(extensions, &extension.ALPN{ProtocolNameList: cfg.supportedProtocols}) - } - - return []*packet{ - { - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageClientHello{ - Version: protocol.Version1_2, - SessionID: state.SessionID, - Cookie: state.cookie, - Random: state.localRandom, - CipherSuiteIDs: cipherSuiteIDs(cfg.localCipherSuites), - CompressionMethods: defaultCompressionMethods(), - Extensions: extensions, - }, - }, - }, - }, - }, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flight4bhandler.go b/vendor/github.com/pion/dtls/v2/flight4bhandler.go deleted file mode 100644 index 6bbbc597..00000000 --- a/vendor/github.com/pion/dtls/v2/flight4bhandler.go +++ /dev/null @@ -1,144 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "bytes" - "context" - - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight4bParse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - - var finished *handshake.MessageFinished - if finished, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false}, - ) - - expectedVerifyData, err := prf.VerifyDataClient(state.masterSecret, plainText, state.cipherSuite.HashFunc()) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - if !bytes.Equal(expectedVerifyData, finished.VerifyData) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errVerifyDataMismatch - } - - // Other party may re-transmit the last flight. Keep state to be flight4b. - return flight4b, nil, nil -} - -func flight4bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { - var pkts []*packet - - extensions := []extension.Extension{&extension.RenegotiationInfo{ - RenegotiatedConnection: 0, - }} - if (cfg.extendedMasterSecret == RequestExtendedMasterSecret || - cfg.extendedMasterSecret == RequireExtendedMasterSecret) && state.extendedMasterSecret { - extensions = append(extensions, &extension.UseExtendedMasterSecret{ - Supported: true, - }) - } - if state.srtpProtectionProfile != 0 { - extensions = append(extensions, &extension.UseSRTP{ - ProtectionProfiles: []SRTPProtectionProfile{state.srtpProtectionProfile}, - }) - } - - selectedProto, err := extension.ALPNProtocolSelection(cfg.supportedProtocols, state.peerSupportedProtocols) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.NoApplicationProtocol}, err - } - if selectedProto != "" { - extensions = append(extensions, &extension.ALPN{ - ProtocolNameList: []string{selectedProto}, - }) - state.NegotiatedProtocol = selectedProto - } - - cipherSuiteID := uint16(state.cipherSuite.ID()) - serverHello := &handshake.Handshake{ - Message: &handshake.MessageServerHello{ - Version: protocol.Version1_2, - Random: state.localRandom, - SessionID: state.SessionID, - CipherSuiteID: &cipherSuiteID, - CompressionMethod: defaultCompressionMethods()[0], - Extensions: extensions, - }, - } - - serverHello.Header.MessageSequence = uint16(state.handshakeSendSequence) - - if len(state.localVerifyData) == 0 { - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - ) - raw, err := serverHello.Marshal() - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - plainText = append(plainText, raw...) - - state.localVerifyData, err = prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc()) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: serverHello, - }, - }, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &protocol.ChangeCipherSpec{}, - }, - }, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - Epoch: 1, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageFinished{ - VerifyData: state.localVerifyData, - }, - }, - }, - shouldEncrypt: true, - resetLocalSequenceNumber: true, - }, - ) - - return pkts, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flight4handler.go b/vendor/github.com/pion/dtls/v2/flight4handler.go deleted file mode 100644 index 67a48646..00000000 --- a/vendor/github.com/pion/dtls/v2/flight4handler.go +++ /dev/null @@ -1,402 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "crypto/rand" - "crypto/x509" - - "github.com/pion/dtls/v2/internal/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/extension" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight4Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { //nolint:gocognit - seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, true}, - handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, true}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - - // Validate type - var clientKeyExchange *handshake.MessageClientKeyExchange - if clientKeyExchange, ok = msgs[handshake.TypeClientKeyExchange].(*handshake.MessageClientKeyExchange); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - - if h, hasCert := msgs[handshake.TypeCertificate].(*handshake.MessageCertificate); hasCert { - state.PeerCertificates = h.Certificate - // If the client offer its certificate, just disable session resumption. - // Otherwise, we have to store the certificate identitfication and expire time. - // And we have to check whether this certificate expired, revoked or changed. - // - // https://curl.se/docs/CVE-2016-5419.html - state.SessionID = nil - } - - if h, hasCertVerify := msgs[handshake.TypeCertificateVerify].(*handshake.MessageCertificateVerify); hasCertVerify { - if state.PeerCertificates == nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errCertificateVerifyNoCertificate - } - - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false}, - ) - - // Verify that the pair of hash algorithm and signiture is listed. - var validSignatureScheme bool - for _, ss := range cfg.localSignatureSchemes { - if ss.Hash == h.HashAlgorithm && ss.Signature == h.SignatureAlgorithm { - validSignatureScheme = true - break - } - } - if !validSignatureScheme { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errNoAvailableSignatureSchemes - } - - if err := verifyCertificateVerify(plainText, h.HashAlgorithm, h.Signature, state.PeerCertificates); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - var chains [][]*x509.Certificate - var err error - var verified bool - if cfg.clientAuth >= VerifyClientCertIfGiven { - if chains, err = verifyClientCert(state.PeerCertificates, cfg.clientCAs); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - verified = true - } - if cfg.verifyPeerCertificate != nil { - if err := cfg.verifyPeerCertificate(state.PeerCertificates, chains); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - } - state.peerCertificatesVerified = verified - } else if state.PeerCertificates != nil { - // A certificate was received, but we haven't seen a CertificateVerify - // keep reading until we receive one - return 0, nil, nil - } - - if !state.cipherSuite.IsInitialized() { - serverRandom := state.localRandom.MarshalFixed() - clientRandom := state.remoteRandom.MarshalFixed() - - var err error - var preMasterSecret []byte - if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypePreSharedKey { - var psk []byte - if psk, err = cfg.localPSKCallback(clientKeyExchange.IdentityHint); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - state.IdentityHint = clientKeyExchange.IdentityHint - switch state.cipherSuite.KeyExchangeAlgorithm() { - case CipherSuiteKeyExchangeAlgorithmPsk: - preMasterSecret = prf.PSKPreMasterSecret(psk) - case (CipherSuiteKeyExchangeAlgorithmPsk | CipherSuiteKeyExchangeAlgorithmEcdhe): - if preMasterSecret, err = prf.EcdhePSKPreMasterSecret(psk, clientKeyExchange.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - default: - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, errInvalidCipherSuite - } - } else { - preMasterSecret, err = prf.PreMasterSecret(clientKeyExchange.PublicKey, state.localKeypair.PrivateKey, state.localKeypair.Curve) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, err - } - } - - if state.extendedMasterSecret { - var sessionHash []byte - sessionHash, err = cache.sessionHash(state.cipherSuite.HashFunc(), cfg.initialEpoch) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - state.masterSecret, err = prf.ExtendedMasterSecret(preMasterSecret, sessionHash, state.cipherSuite.HashFunc()) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } else { - state.masterSecret, err = prf.MasterSecret(preMasterSecret, clientRandom[:], serverRandom[:], state.cipherSuite.HashFunc()) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - if err := state.cipherSuite.Init(state.masterSecret, clientRandom[:], serverRandom[:], false); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret) - } - - if len(state.SessionID) > 0 { - s := Session{ - ID: state.SessionID, - Secret: state.masterSecret, - } - cfg.log.Tracef("[handshake] save new session: %x", s.ID) - if err := cfg.sessionStore.Set(state.SessionID, s); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - // Now, encrypted packets can be handled - if err := c.handleQueuedPackets(ctx); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - seq, msgs, ok = cache.fullPullMap(seq, state.cipherSuite, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - state.handshakeRecvSequence = seq - - if _, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - - if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeAnonymous { - if cfg.verifyConnection != nil { - if err := cfg.verifyConnection(state.clone()); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - } - return flight6, nil, nil - } - - switch cfg.clientAuth { - case RequireAnyClientCert: - if state.PeerCertificates == nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errClientCertificateRequired - } - case VerifyClientCertIfGiven: - if state.PeerCertificates != nil && !state.peerCertificatesVerified { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, errClientCertificateNotVerified - } - case RequireAndVerifyClientCert: - if state.PeerCertificates == nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.NoCertificate}, errClientCertificateRequired - } - if !state.peerCertificatesVerified { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, errClientCertificateNotVerified - } - case NoClientCert, RequestClientCert: - // go to flight6 - } - if cfg.verifyConnection != nil { - if err := cfg.verifyConnection(state.clone()); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - } - - return flight6, nil, nil -} - -func flight4Generate(_ flightConn, state *State, _ *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { - extensions := []extension.Extension{&extension.RenegotiationInfo{ - RenegotiatedConnection: 0, - }} - if (cfg.extendedMasterSecret == RequestExtendedMasterSecret || - cfg.extendedMasterSecret == RequireExtendedMasterSecret) && state.extendedMasterSecret { - extensions = append(extensions, &extension.UseExtendedMasterSecret{ - Supported: true, - }) - } - if state.srtpProtectionProfile != 0 { - extensions = append(extensions, &extension.UseSRTP{ - ProtectionProfiles: []SRTPProtectionProfile{state.srtpProtectionProfile}, - }) - } - if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate { - extensions = append(extensions, &extension.SupportedPointFormats{ - PointFormats: []elliptic.CurvePointFormat{elliptic.CurvePointFormatUncompressed}, - }) - } - - selectedProto, err := extension.ALPNProtocolSelection(cfg.supportedProtocols, state.peerSupportedProtocols) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.NoApplicationProtocol}, err - } - if selectedProto != "" { - extensions = append(extensions, &extension.ALPN{ - ProtocolNameList: []string{selectedProto}, - }) - state.NegotiatedProtocol = selectedProto - } - - var pkts []*packet - cipherSuiteID := uint16(state.cipherSuite.ID()) - - if cfg.sessionStore != nil { - state.SessionID = make([]byte, sessionLength) - if _, err := rand.Read(state.SessionID); err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - pkts = append(pkts, &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageServerHello{ - Version: protocol.Version1_2, - Random: state.localRandom, - SessionID: state.SessionID, - CipherSuiteID: &cipherSuiteID, - CompressionMethod: defaultCompressionMethods()[0], - Extensions: extensions, - }, - }, - }, - }) - - switch { - case state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate: - certificate, err := cfg.getCertificate(&ClientHelloInfo{ - ServerName: state.serverName, - CipherSuites: []ciphersuite.ID{state.cipherSuite.ID()}, - }) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, err - } - - pkts = append(pkts, &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageCertificate{ - Certificate: certificate.Certificate, - }, - }, - }, - }) - - serverRandom := state.localRandom.MarshalFixed() - clientRandom := state.remoteRandom.MarshalFixed() - - // Find compatible signature scheme - signatureHashAlgo, err := signaturehash.SelectSignatureScheme(cfg.localSignatureSchemes, certificate.PrivateKey) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, err - } - - signature, err := generateKeySignature(clientRandom[:], serverRandom[:], state.localKeypair.PublicKey, state.namedCurve, certificate.PrivateKey, signatureHashAlgo.Hash) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - state.localKeySignature = signature - - pkts = append(pkts, &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageServerKeyExchange{ - EllipticCurveType: elliptic.CurveTypeNamedCurve, - NamedCurve: state.namedCurve, - PublicKey: state.localKeypair.PublicKey, - HashAlgorithm: signatureHashAlgo.Hash, - SignatureAlgorithm: signatureHashAlgo.Signature, - Signature: state.localKeySignature, - }, - }, - }, - }) - - if cfg.clientAuth > NoClientCert { - // An empty list of certificateAuthorities signals to - // the client that it may send any certificate in response - // to our request. When we know the CAs we trust, then - // we can send them down, so that the client can choose - // an appropriate certificate to give to us. - var certificateAuthorities [][]byte - if cfg.clientCAs != nil { - // nolint:staticcheck // ignoring tlsCert.RootCAs.Subjects is deprecated ERR because cert does not come from SystemCertPool and it's ok if certificate authorities is empty. - certificateAuthorities = cfg.clientCAs.Subjects() - } - pkts = append(pkts, &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageCertificateRequest{ - CertificateTypes: []clientcertificate.Type{clientcertificate.RSASign, clientcertificate.ECDSASign}, - SignatureHashAlgorithms: cfg.localSignatureSchemes, - CertificateAuthoritiesNames: certificateAuthorities, - }, - }, - }, - }) - } - case cfg.localPSKIdentityHint != nil || state.cipherSuite.KeyExchangeAlgorithm().Has(CipherSuiteKeyExchangeAlgorithmEcdhe): - // To help the client in selecting which identity to use, the server - // can provide a "PSK identity hint" in the ServerKeyExchange message. - // If no hint is provided and cipher suite doesn't use elliptic curve, - // the ServerKeyExchange message is omitted. - // - // https://tools.ietf.org/html/rfc4279#section-2 - srvExchange := &handshake.MessageServerKeyExchange{ - IdentityHint: cfg.localPSKIdentityHint, - } - if state.cipherSuite.KeyExchangeAlgorithm().Has(CipherSuiteKeyExchangeAlgorithmEcdhe) { - srvExchange.EllipticCurveType = elliptic.CurveTypeNamedCurve - srvExchange.NamedCurve = state.namedCurve - srvExchange.PublicKey = state.localKeypair.PublicKey - } - pkts = append(pkts, &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: srvExchange, - }, - }, - }) - } - - pkts = append(pkts, &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageServerHelloDone{}, - }, - }, - }) - - return pkts, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flight5bhandler.go b/vendor/github.com/pion/dtls/v2/flight5bhandler.go deleted file mode 100644 index ddd37324..00000000 --- a/vendor/github.com/pion/dtls/v2/flight5bhandler.go +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight5bParse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-1, state.cipherSuite, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - - if _, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - - // Other party may re-transmit the last flight. Keep state to be flight5b. - return flight5b, nil, nil -} - -func flight5bGenerate(_ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { //nolint:gocognit - var pkts []*packet - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &protocol.ChangeCipherSpec{}, - }, - }) - - if len(state.localVerifyData) == 0 { - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false}, - ) - - var err error - state.localVerifyData, err = prf.VerifyDataClient(state.masterSecret, plainText, state.cipherSuite.HashFunc()) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - Epoch: 1, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageFinished{ - VerifyData: state.localVerifyData, - }, - }, - }, - shouldEncrypt: true, - resetLocalSequenceNumber: true, - }) - - return pkts, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flight5handler.go b/vendor/github.com/pion/dtls/v2/flight5handler.go deleted file mode 100644 index e8adf4f3..00000000 --- a/vendor/github.com/pion/dtls/v2/flight5handler.go +++ /dev/null @@ -1,357 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "bytes" - "context" - "crypto" - "crypto/x509" - - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight5Parse(_ context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, false, false}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - - var finished *handshake.MessageFinished - if finished, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false}, - ) - - expectedVerifyData, err := prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc()) - if err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - if !bytes.Equal(expectedVerifyData, finished.VerifyData) { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errVerifyDataMismatch - } - - if len(state.SessionID) > 0 { - s := Session{ - ID: state.SessionID, - Secret: state.masterSecret, - } - cfg.log.Tracef("[handshake] save new session: %x", s.ID) - if err := cfg.sessionStore.Set(c.sessionKey(), s); err != nil { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - return flight5, nil, nil -} - -func flight5Generate(c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { //nolint:gocognit - var privateKey crypto.PrivateKey - var pkts []*packet - if state.remoteRequestedCertificate { - _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-2, state.cipherSuite, - handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false}) - if !ok { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errClientCertificateRequired - } - reqInfo := CertificateRequestInfo{} - if r, ok := msgs[handshake.TypeCertificateRequest].(*handshake.MessageCertificateRequest); ok { - reqInfo.AcceptableCAs = r.CertificateAuthoritiesNames - } else { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errClientCertificateRequired - } - certificate, err := cfg.getClientCertificate(&reqInfo) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, err - } - if certificate == nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.HandshakeFailure}, errNotAcceptableCertificateChain - } - if certificate.Certificate != nil { - privateKey = certificate.PrivateKey - } - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageCertificate{ - Certificate: certificate.Certificate, - }, - }, - }, - }) - } - - clientKeyExchange := &handshake.MessageClientKeyExchange{} - if cfg.localPSKCallback == nil { - clientKeyExchange.PublicKey = state.localKeypair.PublicKey - } else { - clientKeyExchange.IdentityHint = cfg.localPSKIdentityHint - } - if state != nil && state.localKeypair != nil && len(state.localKeypair.PublicKey) > 0 { - clientKeyExchange.PublicKey = state.localKeypair.PublicKey - } - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: clientKeyExchange, - }, - }, - }) - - serverKeyExchangeData := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false}, - ) - - serverKeyExchange := &handshake.MessageServerKeyExchange{} - - // handshakeMessageServerKeyExchange is optional for PSK - if len(serverKeyExchangeData) == 0 { - alertPtr, err := handleServerKeyExchange(c, state, cfg, &handshake.MessageServerKeyExchange{}) - if err != nil { - return nil, alertPtr, err - } - } else { - rawHandshake := &handshake.Handshake{ - KeyExchangeAlgorithm: state.cipherSuite.KeyExchangeAlgorithm(), - } - err := rawHandshake.Unmarshal(serverKeyExchangeData) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, err - } - - switch h := rawHandshake.Message.(type) { - case *handshake.MessageServerKeyExchange: - serverKeyExchange = h - default: - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.UnexpectedMessage}, errInvalidContentType - } - } - - // Append not-yet-sent packets - merged := []byte{} - seqPred := uint16(state.handshakeSendSequence) - for _, p := range pkts { - h, ok := p.record.Content.(*handshake.Handshake) - if !ok { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, errInvalidContentType - } - h.Header.MessageSequence = seqPred - seqPred++ - raw, err := h.Marshal() - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - merged = append(merged, raw...) - } - - if alertPtr, err := initalizeCipherSuite(state, cache, cfg, serverKeyExchange, merged); err != nil { - return nil, alertPtr, err - } - - // If the client has sent a certificate with signing ability, a digitally-signed - // CertificateVerify message is sent to explicitly verify possession of the - // private key in the certificate. - if state.remoteRequestedCertificate && privateKey != nil { - plainText := append(cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false}, - ), merged...) - - // Find compatible signature scheme - signatureHashAlgo, err := signaturehash.SelectSignatureScheme(cfg.localSignatureSchemes, privateKey) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, err - } - - certVerify, err := generateCertificateVerify(plainText, privateKey, signatureHashAlgo.Hash) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - state.localCertificatesVerify = certVerify - - p := &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageCertificateVerify{ - HashAlgorithm: signatureHashAlgo.Hash, - SignatureAlgorithm: signatureHashAlgo.Signature, - Signature: state.localCertificatesVerify, - }, - }, - }, - } - pkts = append(pkts, p) - - h, ok := p.record.Content.(*handshake.Handshake) - if !ok { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, errInvalidContentType - } - h.Header.MessageSequence = seqPred - // seqPred++ // this is the last use of seqPred - raw, err := h.Marshal() - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - merged = append(merged, raw...) - } - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &protocol.ChangeCipherSpec{}, - }, - }) - - if len(state.localVerifyData) == 0 { - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false}, - ) - - var err error - state.localVerifyData, err = prf.VerifyDataClient(state.masterSecret, append(plainText, merged...), state.cipherSuite.HashFunc()) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - Epoch: 1, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageFinished{ - VerifyData: state.localVerifyData, - }, - }, - }, - shouldEncrypt: true, - resetLocalSequenceNumber: true, - }) - - return pkts, nil, nil -} - -func initalizeCipherSuite(state *State, cache *handshakeCache, cfg *handshakeConfig, h *handshake.MessageServerKeyExchange, sendingPlainText []byte) (*alert.Alert, error) { //nolint:gocognit - if state.cipherSuite.IsInitialized() { - return nil, nil //nolint - } - - clientRandom := state.localRandom.MarshalFixed() - serverRandom := state.remoteRandom.MarshalFixed() - - var err error - - if state.extendedMasterSecret { - var sessionHash []byte - sessionHash, err = cache.sessionHash(state.cipherSuite.HashFunc(), cfg.initialEpoch, sendingPlainText) - if err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - state.masterSecret, err = prf.ExtendedMasterSecret(state.preMasterSecret, sessionHash, state.cipherSuite.HashFunc()) - if err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.IllegalParameter}, err - } - } else { - state.masterSecret, err = prf.MasterSecret(state.preMasterSecret, clientRandom[:], serverRandom[:], state.cipherSuite.HashFunc()) - if err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - if state.cipherSuite.AuthenticationType() == CipherSuiteAuthenticationTypeCertificate { - // Verify that the pair of hash algorithm and signiture is listed. - var validSignatureScheme bool - for _, ss := range cfg.localSignatureSchemes { - if ss.Hash == h.HashAlgorithm && ss.Signature == h.SignatureAlgorithm { - validSignatureScheme = true - break - } - } - if !validSignatureScheme { - return &alert.Alert{Level: alert.Fatal, Description: alert.InsufficientSecurity}, errNoAvailableSignatureSchemes - } - - expectedMsg := valueKeyMessage(clientRandom[:], serverRandom[:], h.PublicKey, h.NamedCurve) - if err = verifyKeySignature(expectedMsg, h.Signature, h.HashAlgorithm, state.PeerCertificates); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - var chains [][]*x509.Certificate - if !cfg.insecureSkipVerify { - if chains, err = verifyServerCert(state.PeerCertificates, cfg.rootCAs, cfg.serverName); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - } - if cfg.verifyPeerCertificate != nil { - if err = cfg.verifyPeerCertificate(state.PeerCertificates, chains); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - } - } - if cfg.verifyConnection != nil { - if err = cfg.verifyConnection(state.clone()); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.BadCertificate}, err - } - } - - if err = state.cipherSuite.Init(state.masterSecret, clientRandom[:], serverRandom[:], true); err != nil { - return &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - - cfg.writeKeyLog(keyLogLabelTLS12, clientRandom[:], state.masterSecret) - - return nil, nil //nolint -} diff --git a/vendor/github.com/pion/dtls/v2/flight6handler.go b/vendor/github.com/pion/dtls/v2/flight6handler.go deleted file mode 100644 index 57ac1436..00000000 --- a/vendor/github.com/pion/dtls/v2/flight6handler.go +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -func flight6Parse(_ context.Context, _ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) { - _, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence-1, state.cipherSuite, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false}, - ) - if !ok { - // No valid message received. Keep reading - return 0, nil, nil - } - - if _, ok = msgs[handshake.TypeFinished].(*handshake.MessageFinished); !ok { - return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil - } - - // Other party may re-transmit the last flight. Keep state to be flight6. - return flight6, nil, nil -} - -func flight6Generate(_ flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) ([]*packet, *alert.Alert, error) { - var pkts []*packet - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - }, - Content: &protocol.ChangeCipherSpec{}, - }, - }) - - if len(state.localVerifyData) == 0 { - plainText := cache.pullAndMerge( - handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerKeyExchange, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificateRequest, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeServerHelloDone, cfg.initialEpoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeClientKeyExchange, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeCertificateVerify, cfg.initialEpoch, true, false}, - handshakeCachePullRule{handshake.TypeFinished, cfg.initialEpoch + 1, true, false}, - ) - - var err error - state.localVerifyData, err = prf.VerifyDataServer(state.masterSecret, plainText, state.cipherSuite.HashFunc()) - if err != nil { - return nil, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, err - } - } - - pkts = append(pkts, - &packet{ - record: &recordlayer.RecordLayer{ - Header: recordlayer.Header{ - Version: protocol.Version1_2, - Epoch: 1, - }, - Content: &handshake.Handshake{ - Message: &handshake.MessageFinished{ - VerifyData: state.localVerifyData, - }, - }, - }, - shouldEncrypt: true, - resetLocalSequenceNumber: true, - }, - ) - return pkts, nil, nil -} diff --git a/vendor/github.com/pion/dtls/v2/flighthandler.go b/vendor/github.com/pion/dtls/v2/flighthandler.go deleted file mode 100644 index ceb4a992..00000000 --- a/vendor/github.com/pion/dtls/v2/flighthandler.go +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - - "github.com/pion/dtls/v2/pkg/protocol/alert" -) - -// Parse received handshakes and return next flightVal -type flightParser func(context.Context, flightConn, *State, *handshakeCache, *handshakeConfig) (flightVal, *alert.Alert, error) - -// Generate flights -type flightGenerator func(flightConn, *State, *handshakeCache, *handshakeConfig) ([]*packet, *alert.Alert, error) - -func (f flightVal) getFlightParser() (flightParser, error) { - switch f { - case flight0: - return flight0Parse, nil - case flight1: - return flight1Parse, nil - case flight2: - return flight2Parse, nil - case flight3: - return flight3Parse, nil - case flight4: - return flight4Parse, nil - case flight4b: - return flight4bParse, nil - case flight5: - return flight5Parse, nil - case flight5b: - return flight5bParse, nil - case flight6: - return flight6Parse, nil - default: - return nil, errInvalidFlight - } -} - -func (f flightVal) getFlightGenerator() (gen flightGenerator, retransmit bool, err error) { - switch f { - case flight0: - return flight0Generate, true, nil - case flight1: - return flight1Generate, true, nil - case flight2: - // https://tools.ietf.org/html/rfc6347#section-3.2.1 - // HelloVerifyRequests must not be retransmitted. - return flight2Generate, false, nil - case flight3: - return flight3Generate, true, nil - case flight4: - return flight4Generate, true, nil - case flight4b: - return flight4bGenerate, true, nil - case flight5: - return flight5Generate, true, nil - case flight5b: - return flight5bGenerate, true, nil - case flight6: - return flight6Generate, true, nil - default: - return nil, false, errInvalidFlight - } -} diff --git a/vendor/github.com/pion/dtls/v2/fragment_buffer.go b/vendor/github.com/pion/dtls/v2/fragment_buffer.go deleted file mode 100644 index f2003375..00000000 --- a/vendor/github.com/pion/dtls/v2/fragment_buffer.go +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// 2 megabytes -const fragmentBufferMaxSize = 2000000 - -type fragment struct { - recordLayerHeader recordlayer.Header - handshakeHeader handshake.Header - data []byte -} - -type fragmentBuffer struct { - // map of MessageSequenceNumbers that hold slices of fragments - cache map[uint16][]*fragment - - currentMessageSequenceNumber uint16 -} - -func newFragmentBuffer() *fragmentBuffer { - return &fragmentBuffer{cache: map[uint16][]*fragment{}} -} - -// current total size of buffer -func (f *fragmentBuffer) size() int { - size := 0 - for i := range f.cache { - for j := range f.cache[i] { - size += len(f.cache[i][j].data) - } - } - return size -} - -// Attempts to push a DTLS packet to the fragmentBuffer -// when it returns true it means the fragmentBuffer has inserted and the buffer shouldn't be handled -// when an error returns it is fatal, and the DTLS connection should be stopped -func (f *fragmentBuffer) push(buf []byte) (bool, error) { - if f.size()+len(buf) >= fragmentBufferMaxSize { - return false, errFragmentBufferOverflow - } - - frag := new(fragment) - if err := frag.recordLayerHeader.Unmarshal(buf); err != nil { - return false, err - } - - // fragment isn't a handshake, we don't need to handle it - if frag.recordLayerHeader.ContentType != protocol.ContentTypeHandshake { - return false, nil - } - - for buf = buf[recordlayer.HeaderSize:]; len(buf) != 0; frag = new(fragment) { - if err := frag.handshakeHeader.Unmarshal(buf); err != nil { - return false, err - } - - if _, ok := f.cache[frag.handshakeHeader.MessageSequence]; !ok { - f.cache[frag.handshakeHeader.MessageSequence] = []*fragment{} - } - - // end index should be the length of handshake header but if the handshake - // was fragmented, we should keep them all - end := int(handshake.HeaderLength + frag.handshakeHeader.Length) - if size := len(buf); end > size { - end = size - } - - // Discard all headers, when rebuilding the packet we will re-build - frag.data = append([]byte{}, buf[handshake.HeaderLength:end]...) - f.cache[frag.handshakeHeader.MessageSequence] = append(f.cache[frag.handshakeHeader.MessageSequence], frag) - buf = buf[end:] - } - - return true, nil -} - -func (f *fragmentBuffer) pop() (content []byte, epoch uint16) { - frags, ok := f.cache[f.currentMessageSequenceNumber] - if !ok { - return nil, 0 - } - - // Go doesn't support recursive lambdas - var appendMessage func(targetOffset uint32) bool - - rawMessage := []byte{} - appendMessage = func(targetOffset uint32) bool { - for _, f := range frags { - if f.handshakeHeader.FragmentOffset == targetOffset { - fragmentEnd := (f.handshakeHeader.FragmentOffset + f.handshakeHeader.FragmentLength) - if fragmentEnd != f.handshakeHeader.Length && f.handshakeHeader.FragmentLength != 0 { - if !appendMessage(fragmentEnd) { - return false - } - } - - rawMessage = append(f.data, rawMessage...) - return true - } - } - return false - } - - // Recursively collect up - if !appendMessage(0) { - return nil, 0 - } - - firstHeader := frags[0].handshakeHeader - firstHeader.FragmentOffset = 0 - firstHeader.FragmentLength = firstHeader.Length - - rawHeader, err := firstHeader.Marshal() - if err != nil { - return nil, 0 - } - - messageEpoch := frags[0].recordLayerHeader.Epoch - - delete(f.cache, f.currentMessageSequenceNumber) - f.currentMessageSequenceNumber++ - return append(rawHeader, rawMessage...), messageEpoch -} diff --git a/vendor/github.com/pion/dtls/v2/handshake_cache.go b/vendor/github.com/pion/dtls/v2/handshake_cache.go deleted file mode 100644 index 8d596056..00000000 --- a/vendor/github.com/pion/dtls/v2/handshake_cache.go +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "sync" - - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/handshake" -) - -type handshakeCacheItem struct { - typ handshake.Type - isClient bool - epoch uint16 - messageSequence uint16 - data []byte -} - -type handshakeCachePullRule struct { - typ handshake.Type - epoch uint16 - isClient bool - optional bool -} - -type handshakeCache struct { - cache []*handshakeCacheItem - mu sync.Mutex -} - -func newHandshakeCache() *handshakeCache { - return &handshakeCache{} -} - -func (h *handshakeCache) push(data []byte, epoch, messageSequence uint16, typ handshake.Type, isClient bool) { - h.mu.Lock() - defer h.mu.Unlock() - - h.cache = append(h.cache, &handshakeCacheItem{ - data: append([]byte{}, data...), - epoch: epoch, - messageSequence: messageSequence, - typ: typ, - isClient: isClient, - }) -} - -// returns a list handshakes that match the requested rules -// the list will contain null entries for rules that can't be satisfied -// multiple entries may match a rule, but only the last match is returned (ie ClientHello with cookies) -func (h *handshakeCache) pull(rules ...handshakeCachePullRule) []*handshakeCacheItem { - h.mu.Lock() - defer h.mu.Unlock() - - out := make([]*handshakeCacheItem, len(rules)) - for i, r := range rules { - for _, c := range h.cache { - if c.typ == r.typ && c.isClient == r.isClient && c.epoch == r.epoch { - switch { - case out[i] == nil: - out[i] = c - case out[i].messageSequence < c.messageSequence: - out[i] = c - } - } - } - } - - return out -} - -// fullPullMap pulls all handshakes between rules[0] to rules[len(rules)-1] as map. -func (h *handshakeCache) fullPullMap(startSeq int, cipherSuite CipherSuite, rules ...handshakeCachePullRule) (int, map[handshake.Type]handshake.Message, bool) { - h.mu.Lock() - defer h.mu.Unlock() - - ci := make(map[handshake.Type]*handshakeCacheItem) - for _, r := range rules { - var item *handshakeCacheItem - for _, c := range h.cache { - if c.typ == r.typ && c.isClient == r.isClient && c.epoch == r.epoch { - switch { - case item == nil: - item = c - case item.messageSequence < c.messageSequence: - item = c - } - } - } - if !r.optional && item == nil { - // Missing mandatory message. - return startSeq, nil, false - } - ci[r.typ] = item - } - out := make(map[handshake.Type]handshake.Message) - seq := startSeq - for _, r := range rules { - t := r.typ - i := ci[t] - if i == nil { - continue - } - var keyExchangeAlgorithm CipherSuiteKeyExchangeAlgorithm - if cipherSuite != nil { - keyExchangeAlgorithm = cipherSuite.KeyExchangeAlgorithm() - } - rawHandshake := &handshake.Handshake{ - KeyExchangeAlgorithm: keyExchangeAlgorithm, - } - if err := rawHandshake.Unmarshal(i.data); err != nil { - return startSeq, nil, false - } - if uint16(seq) != rawHandshake.Header.MessageSequence { - // There is a gap. Some messages are not arrived. - return startSeq, nil, false - } - seq++ - out[t] = rawHandshake.Message - } - return seq, out, true -} - -// pullAndMerge calls pull and then merges the results, ignoring any null entries -func (h *handshakeCache) pullAndMerge(rules ...handshakeCachePullRule) []byte { - merged := []byte{} - - for _, p := range h.pull(rules...) { - if p != nil { - merged = append(merged, p.data...) - } - } - return merged -} - -// sessionHash returns the session hash for Extended Master Secret support -// https://tools.ietf.org/html/draft-ietf-tls-session-hash-06#section-4 -func (h *handshakeCache) sessionHash(hf prf.HashFunc, epoch uint16, additional ...[]byte) ([]byte, error) { - merged := []byte{} - - // Order defined by https://tools.ietf.org/html/rfc5246#section-7.3 - handshakeBuffer := h.pull( - handshakeCachePullRule{handshake.TypeClientHello, epoch, true, false}, - handshakeCachePullRule{handshake.TypeServerHello, epoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, epoch, false, false}, - handshakeCachePullRule{handshake.TypeServerKeyExchange, epoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificateRequest, epoch, false, false}, - handshakeCachePullRule{handshake.TypeServerHelloDone, epoch, false, false}, - handshakeCachePullRule{handshake.TypeCertificate, epoch, true, false}, - handshakeCachePullRule{handshake.TypeClientKeyExchange, epoch, true, false}, - ) - - for _, p := range handshakeBuffer { - if p == nil { - continue - } - - merged = append(merged, p.data...) - } - for _, a := range additional { - merged = append(merged, a...) - } - - hash := hf() - if _, err := hash.Write(merged); err != nil { - return []byte{}, err - } - - return hash.Sum(nil), nil -} diff --git a/vendor/github.com/pion/dtls/v2/handshaker.go b/vendor/github.com/pion/dtls/v2/handshaker.go deleted file mode 100644 index 1c6d58fe..00000000 --- a/vendor/github.com/pion/dtls/v2/handshaker.go +++ /dev/null @@ -1,350 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "crypto/tls" - "crypto/x509" - "fmt" - "io" - "sync" - "time" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/logging" -) - -// [RFC6347 Section-4.2.4] -// +-----------+ -// +---> | PREPARING | <--------------------+ -// | +-----------+ | -// | | | -// | | Buffer next flight | -// | | | -// | \|/ | -// | +-----------+ | -// | | SENDING |<------------------+ | Send -// | +-----------+ | | HelloRequest -// Receive | | | | -// next | | Send flight | | or -// flight | +--------+ | | -// | | | Set retransmit timer | | Receive -// | | \|/ | | HelloRequest -// | | +-----------+ | | Send -// +--)--| WAITING |-------------------+ | ClientHello -// | | +-----------+ Timer expires | | -// | | | | | -// | | +------------------------+ | -// Receive | | Send Read retransmit | -// last | | last | -// flight | | flight | -// | | | -// \|/\|/ | -// +-----------+ | -// | FINISHED | -------------------------------+ -// +-----------+ -// | /|\ -// | | -// +---+ -// Read retransmit -// Retransmit last flight - -type handshakeState uint8 - -const ( - handshakeErrored handshakeState = iota - handshakePreparing - handshakeSending - handshakeWaiting - handshakeFinished -) - -func (s handshakeState) String() string { - switch s { - case handshakeErrored: - return "Errored" - case handshakePreparing: - return "Preparing" - case handshakeSending: - return "Sending" - case handshakeWaiting: - return "Waiting" - case handshakeFinished: - return "Finished" - default: - return "Unknown" - } -} - -type handshakeFSM struct { - currentFlight flightVal - flights []*packet - retransmit bool - state *State - cache *handshakeCache - cfg *handshakeConfig - closed chan struct{} -} - -type handshakeConfig struct { - localPSKCallback PSKCallback - localPSKIdentityHint []byte - localCipherSuites []CipherSuite // Available CipherSuites - localSignatureSchemes []signaturehash.Algorithm // Available signature schemes - extendedMasterSecret ExtendedMasterSecretType // Policy for the Extended Master Support extension - localSRTPProtectionProfiles []SRTPProtectionProfile // Available SRTPProtectionProfiles, if empty no SRTP support - serverName string - supportedProtocols []string - clientAuth ClientAuthType // If we are a client should we request a client certificate - localCertificates []tls.Certificate - nameToCertificate map[string]*tls.Certificate - insecureSkipVerify bool - verifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error - verifyConnection func(*State) error - sessionStore SessionStore - rootCAs *x509.CertPool - clientCAs *x509.CertPool - retransmitInterval time.Duration - customCipherSuites func() []CipherSuite - ellipticCurves []elliptic.Curve - insecureSkipHelloVerify bool - - onFlightState func(flightVal, handshakeState) - log logging.LeveledLogger - keyLogWriter io.Writer - - localGetCertificate func(*ClientHelloInfo) (*tls.Certificate, error) - localGetClientCertificate func(*CertificateRequestInfo) (*tls.Certificate, error) - - initialEpoch uint16 - - mu sync.Mutex -} - -type flightConn interface { - notify(ctx context.Context, level alert.Level, desc alert.Description) error - writePackets(context.Context, []*packet) error - recvHandshake() <-chan chan struct{} - setLocalEpoch(epoch uint16) - handleQueuedPackets(context.Context) error - sessionKey() []byte -} - -func (c *handshakeConfig) writeKeyLog(label string, clientRandom, secret []byte) { - if c.keyLogWriter == nil { - return - } - c.mu.Lock() - defer c.mu.Unlock() - _, err := c.keyLogWriter.Write([]byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret))) - if err != nil { - c.log.Debugf("failed to write key log file: %s", err) - } -} - -func srvCliStr(isClient bool) string { - if isClient { - return "client" - } - return "server" -} - -func newHandshakeFSM( - s *State, cache *handshakeCache, cfg *handshakeConfig, - initialFlight flightVal, -) *handshakeFSM { - return &handshakeFSM{ - currentFlight: initialFlight, - state: s, - cache: cache, - cfg: cfg, - closed: make(chan struct{}), - } -} - -func (s *handshakeFSM) Run(ctx context.Context, c flightConn, initialState handshakeState) error { - state := initialState - defer func() { - close(s.closed) - }() - for { - s.cfg.log.Tracef("[handshake:%s] %s: %s", srvCliStr(s.state.isClient), s.currentFlight.String(), state.String()) - if s.cfg.onFlightState != nil { - s.cfg.onFlightState(s.currentFlight, state) - } - var err error - switch state { - case handshakePreparing: - state, err = s.prepare(ctx, c) - case handshakeSending: - state, err = s.send(ctx, c) - case handshakeWaiting: - state, err = s.wait(ctx, c) - case handshakeFinished: - state, err = s.finish(ctx, c) - default: - return errInvalidFSMTransition - } - if err != nil { - return err - } - } -} - -func (s *handshakeFSM) Done() <-chan struct{} { - return s.closed -} - -func (s *handshakeFSM) prepare(ctx context.Context, c flightConn) (handshakeState, error) { - s.flights = nil - // Prepare flights - var ( - a *alert.Alert - err error - pkts []*packet - ) - gen, retransmit, errFlight := s.currentFlight.getFlightGenerator() - if errFlight != nil { - err = errFlight - a = &alert.Alert{Level: alert.Fatal, Description: alert.InternalError} - } else { - pkts, a, err = gen(c, s.state, s.cache, s.cfg) - s.retransmit = retransmit - } - if a != nil { - if alertErr := c.notify(ctx, a.Level, a.Description); alertErr != nil { - if err != nil { - err = alertErr - } - } - } - if err != nil { - return handshakeErrored, err - } - - s.flights = pkts - epoch := s.cfg.initialEpoch - nextEpoch := epoch - for _, p := range s.flights { - p.record.Header.Epoch += epoch - if p.record.Header.Epoch > nextEpoch { - nextEpoch = p.record.Header.Epoch - } - if h, ok := p.record.Content.(*handshake.Handshake); ok { - h.Header.MessageSequence = uint16(s.state.handshakeSendSequence) - s.state.handshakeSendSequence++ - } - } - if epoch != nextEpoch { - s.cfg.log.Tracef("[handshake:%s] -> changeCipherSpec (epoch: %d)", srvCliStr(s.state.isClient), nextEpoch) - c.setLocalEpoch(nextEpoch) - } - return handshakeSending, nil -} - -func (s *handshakeFSM) send(ctx context.Context, c flightConn) (handshakeState, error) { - // Send flights - if err := c.writePackets(ctx, s.flights); err != nil { - return handshakeErrored, err - } - - if s.currentFlight.isLastSendFlight() { - return handshakeFinished, nil - } - return handshakeWaiting, nil -} - -func (s *handshakeFSM) wait(ctx context.Context, c flightConn) (handshakeState, error) { //nolint:gocognit - parse, errFlight := s.currentFlight.getFlightParser() - if errFlight != nil { - if alertErr := c.notify(ctx, alert.Fatal, alert.InternalError); alertErr != nil { - if errFlight != nil { - return handshakeErrored, alertErr - } - } - return handshakeErrored, errFlight - } - - retransmitTimer := time.NewTimer(s.cfg.retransmitInterval) - for { - select { - case done := <-c.recvHandshake(): - nextFlight, alert, err := parse(ctx, c, s.state, s.cache, s.cfg) - close(done) - if alert != nil { - if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { - if err != nil { - err = alertErr - } - } - } - if err != nil { - return handshakeErrored, err - } - if nextFlight == 0 { - break - } - s.cfg.log.Tracef("[handshake:%s] %s -> %s", srvCliStr(s.state.isClient), s.currentFlight.String(), nextFlight.String()) - if nextFlight.isLastRecvFlight() && s.currentFlight == nextFlight { - return handshakeFinished, nil - } - s.currentFlight = nextFlight - return handshakePreparing, nil - - case <-retransmitTimer.C: - if !s.retransmit { - return handshakeWaiting, nil - } - return handshakeSending, nil - case <-ctx.Done(): - return handshakeErrored, ctx.Err() - } - } -} - -func (s *handshakeFSM) finish(ctx context.Context, c flightConn) (handshakeState, error) { - parse, errFlight := s.currentFlight.getFlightParser() - if errFlight != nil { - if alertErr := c.notify(ctx, alert.Fatal, alert.InternalError); alertErr != nil { - if errFlight != nil { - return handshakeErrored, alertErr - } - } - return handshakeErrored, errFlight - } - - retransmitTimer := time.NewTimer(s.cfg.retransmitInterval) - select { - case done := <-c.recvHandshake(): - nextFlight, alert, err := parse(ctx, c, s.state, s.cache, s.cfg) - close(done) - if alert != nil { - if alertErr := c.notify(ctx, alert.Level, alert.Description); alertErr != nil { - if err != nil { - err = alertErr - } - } - } - if err != nil { - return handshakeErrored, err - } - if nextFlight == 0 { - break - } - if nextFlight.isLastRecvFlight() && s.currentFlight == nextFlight { - return handshakeFinished, nil - } - <-retransmitTimer.C - // Retransmit last flight - return handshakeSending, nil - - case <-ctx.Done(): - return handshakeErrored, ctx.Err() - } - return handshakeFinished, nil -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go deleted file mode 100644 index f78b6dc2..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_128_ccm.go +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" -) - -// Aes128Ccm is a base class used by multiple AES-CCM Ciphers -type Aes128Ccm struct { - AesCcm -} - -func newAes128Ccm(clientCertificateType clientcertificate.Type, id ID, psk bool, cryptoCCMTagLen ciphersuite.CCMTagLen, keyExchangeAlgorithm KeyExchangeAlgorithm, ecc bool) *Aes128Ccm { - return &Aes128Ccm{ - AesCcm: AesCcm{ - clientCertificateType: clientCertificateType, - id: id, - psk: psk, - cryptoCCMTagLen: cryptoCCMTagLen, - keyExchangeAlgorithm: keyExchangeAlgorithm, - ecc: ecc, - }, - } -} - -// Init initializes the internal Cipher with keying material -func (c *Aes128Ccm) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { - const prfKeyLen = 16 - return c.AesCcm.Init(masterSecret, clientRandom, serverRandom, isClient, prfKeyLen) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go deleted file mode 100644 index bb812862..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_256_ccm.go +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" -) - -// Aes256Ccm is a base class used by multiple AES-CCM Ciphers -type Aes256Ccm struct { - AesCcm -} - -func newAes256Ccm(clientCertificateType clientcertificate.Type, id ID, psk bool, cryptoCCMTagLen ciphersuite.CCMTagLen, keyExchangeAlgorithm KeyExchangeAlgorithm, ecc bool) *Aes256Ccm { - return &Aes256Ccm{ - AesCcm: AesCcm{ - clientCertificateType: clientCertificateType, - id: id, - psk: psk, - cryptoCCMTagLen: cryptoCCMTagLen, - keyExchangeAlgorithm: keyExchangeAlgorithm, - ecc: ecc, - }, - } -} - -// Init initializes the internal Cipher with keying material -func (c *Aes256Ccm) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { - const prfKeyLen = 32 - return c.AesCcm.Init(masterSecret, clientRandom, serverRandom, isClient, prfKeyLen) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go deleted file mode 100644 index dc511982..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/aes_ccm.go +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/sha256" - "fmt" - "hash" - "sync/atomic" - - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// AesCcm is a base class used by multiple AES-CCM Ciphers -type AesCcm struct { - ccm atomic.Value // *cryptoCCM - clientCertificateType clientcertificate.Type - id ID - psk bool - keyExchangeAlgorithm KeyExchangeAlgorithm - cryptoCCMTagLen ciphersuite.CCMTagLen - ecc bool -} - -// CertificateType returns what type of certificate this CipherSuite exchanges -func (c *AesCcm) CertificateType() clientcertificate.Type { - return c.clientCertificateType -} - -// ID returns the ID of the CipherSuite -func (c *AesCcm) ID() ID { - return c.id -} - -func (c *AesCcm) String() string { - return c.id.String() -} - -// ECC uses Elliptic Curve Cryptography -func (c *AesCcm) ECC() bool { - return c.ecc -} - -// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake -func (c *AesCcm) KeyExchangeAlgorithm() KeyExchangeAlgorithm { - return c.keyExchangeAlgorithm -} - -// HashFunc returns the hashing func for this CipherSuite -func (c *AesCcm) HashFunc() func() hash.Hash { - return sha256.New -} - -// AuthenticationType controls what authentication method is using during the handshake -func (c *AesCcm) AuthenticationType() AuthenticationType { - if c.psk { - return AuthenticationTypePreSharedKey - } - return AuthenticationTypeCertificate -} - -// IsInitialized returns if the CipherSuite has keying material and can -// encrypt/decrypt packets -func (c *AesCcm) IsInitialized() bool { - return c.ccm.Load() != nil -} - -// Init initializes the internal Cipher with keying material -func (c *AesCcm) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool, prfKeyLen int) error { - const ( - prfMacLen = 0 - prfIvLen = 4 - ) - - keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) - if err != nil { - return err - } - - var ccm *ciphersuite.CCM - if isClient { - ccm, err = ciphersuite.NewCCM(c.cryptoCCMTagLen, keys.ClientWriteKey, keys.ClientWriteIV, keys.ServerWriteKey, keys.ServerWriteIV) - } else { - ccm, err = ciphersuite.NewCCM(c.cryptoCCMTagLen, keys.ServerWriteKey, keys.ServerWriteIV, keys.ClientWriteKey, keys.ClientWriteIV) - } - c.ccm.Store(ccm) - - return err -} - -// Encrypt encrypts a single TLS RecordLayer -func (c *AesCcm) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - cipherSuite, ok := c.ccm.Load().(*ciphersuite.CCM) - if !ok { - return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Encrypt(pkt, raw) -} - -// Decrypt decrypts a single TLS RecordLayer -func (c *AesCcm) Decrypt(raw []byte) ([]byte, error) { - cipherSuite, ok := c.ccm.Load().(*ciphersuite.CCM) - if !ok { - return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Decrypt(raw) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go deleted file mode 100644 index f44f29fd..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/ciphersuite.go +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package ciphersuite provides TLS Ciphers as registered with the IANA https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4 -package ciphersuite - -import ( - "errors" - "fmt" - - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/pkg/protocol" -) - -var errCipherSuiteNotInit = &protocol.TemporaryError{Err: errors.New("CipherSuite has not been initialized")} //nolint:goerr113 - -// ID is an ID for our supported CipherSuites -type ID uint16 - -func (i ID) String() string { - switch i { - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM" - case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" - case TLS_PSK_WITH_AES_128_CCM: - return "TLS_PSK_WITH_AES_128_CCM" - case TLS_PSK_WITH_AES_128_CCM_8: - return "TLS_PSK_WITH_AES_128_CCM_8" - case TLS_PSK_WITH_AES_256_CCM_8: - return "TLS_PSK_WITH_AES_256_CCM_8" - case TLS_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_PSK_WITH_AES_128_GCM_SHA256" - case TLS_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_PSK_WITH_AES_128_CBC_SHA256" - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" - case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256" - default: - return fmt.Sprintf("unknown(%v)", uint16(i)) - } -} - -// Supported Cipher Suites -const ( - // AES-128-CCM - TLS_ECDHE_ECDSA_WITH_AES_128_CCM ID = 0xc0ac //nolint:revive,stylecheck - TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ID = 0xc0ae //nolint:revive,stylecheck - - // AES-128-GCM-SHA256 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ID = 0xc02b //nolint:revive,stylecheck - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ID = 0xc02f //nolint:revive,stylecheck - - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ID = 0xc02c //nolint:revive,stylecheck - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ID = 0xc030 //nolint:revive,stylecheck - // AES-256-CBC-SHA - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ID = 0xc00a //nolint:revive,stylecheck - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ID = 0xc014 //nolint:revive,stylecheck - - TLS_PSK_WITH_AES_128_CCM ID = 0xc0a4 //nolint:revive,stylecheck - TLS_PSK_WITH_AES_128_CCM_8 ID = 0xc0a8 //nolint:revive,stylecheck - TLS_PSK_WITH_AES_256_CCM_8 ID = 0xc0a9 //nolint:revive,stylecheck - TLS_PSK_WITH_AES_128_GCM_SHA256 ID = 0x00a8 //nolint:revive,stylecheck - TLS_PSK_WITH_AES_128_CBC_SHA256 ID = 0x00ae //nolint:revive,stylecheck - - TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 ID = 0xC037 //nolint:revive,stylecheck -) - -// AuthenticationType controls what authentication method is using during the handshake -type AuthenticationType = types.AuthenticationType - -// AuthenticationType Enums -const ( - AuthenticationTypeCertificate AuthenticationType = types.AuthenticationTypeCertificate - AuthenticationTypePreSharedKey AuthenticationType = types.AuthenticationTypePreSharedKey - AuthenticationTypeAnonymous AuthenticationType = types.AuthenticationTypeAnonymous -) - -// KeyExchangeAlgorithm controls what exchange algorithm was chosen. -type KeyExchangeAlgorithm = types.KeyExchangeAlgorithm - -// KeyExchangeAlgorithm Bitmask -const ( - KeyExchangeAlgorithmNone KeyExchangeAlgorithm = types.KeyExchangeAlgorithmNone - KeyExchangeAlgorithmPsk KeyExchangeAlgorithm = types.KeyExchangeAlgorithmPsk - KeyExchangeAlgorithmEcdhe KeyExchangeAlgorithm = types.KeyExchangeAlgorithmEcdhe -) diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go deleted file mode 100644 index 8367b2c6..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" -) - -// NewTLSEcdheEcdsaWithAes128Ccm constructs a TLS_ECDHE_ECDSA_WITH_AES_128_CCM Cipher -func NewTLSEcdheEcdsaWithAes128Ccm() *Aes128Ccm { - return newAes128Ccm(clientcertificate.ECDSASign, TLS_ECDHE_ECDSA_WITH_AES_128_CCM, false, ciphersuite.CCMTagLength, KeyExchangeAlgorithmEcdhe, true) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go deleted file mode 100644 index 11b68732..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_ccm8.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" -) - -// NewTLSEcdheEcdsaWithAes128Ccm8 creates a new TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 CipherSuite -func NewTLSEcdheEcdsaWithAes128Ccm8() *Aes128Ccm { - return newAes128Ccm(clientcertificate.ECDSASign, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, false, ciphersuite.CCMTagLength8, KeyExchangeAlgorithmEcdhe, true) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go deleted file mode 100644 index 0c919fe4..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_128_gcm_sha256.go +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/sha256" - "fmt" - "hash" - "sync/atomic" - - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// TLSEcdheEcdsaWithAes128GcmSha256 represents a TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuite -type TLSEcdheEcdsaWithAes128GcmSha256 struct { - gcm atomic.Value // *cryptoGCM -} - -// CertificateType returns what type of certficate this CipherSuite exchanges -func (c *TLSEcdheEcdsaWithAes128GcmSha256) CertificateType() clientcertificate.Type { - return clientcertificate.ECDSASign -} - -// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake -func (c *TLSEcdheEcdsaWithAes128GcmSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm { - return KeyExchangeAlgorithmEcdhe -} - -// ECC uses Elliptic Curve Cryptography -func (c *TLSEcdheEcdsaWithAes128GcmSha256) ECC() bool { - return true -} - -// ID returns the ID of the CipherSuite -func (c *TLSEcdheEcdsaWithAes128GcmSha256) ID() ID { - return TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -} - -func (c *TLSEcdheEcdsaWithAes128GcmSha256) String() string { - return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" -} - -// HashFunc returns the hashing func for this CipherSuite -func (c *TLSEcdheEcdsaWithAes128GcmSha256) HashFunc() func() hash.Hash { - return sha256.New -} - -// AuthenticationType controls what authentication method is using during the handshake -func (c *TLSEcdheEcdsaWithAes128GcmSha256) AuthenticationType() AuthenticationType { - return AuthenticationTypeCertificate -} - -// IsInitialized returns if the CipherSuite has keying material and can -// encrypt/decrypt packets -func (c *TLSEcdheEcdsaWithAes128GcmSha256) IsInitialized() bool { - return c.gcm.Load() != nil -} - -func (c *TLSEcdheEcdsaWithAes128GcmSha256) init(masterSecret, clientRandom, serverRandom []byte, isClient bool, prfMacLen, prfKeyLen, prfIvLen int, hashFunc func() hash.Hash) error { - keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, hashFunc) - if err != nil { - return err - } - - var gcm *ciphersuite.GCM - if isClient { - gcm, err = ciphersuite.NewGCM(keys.ClientWriteKey, keys.ClientWriteIV, keys.ServerWriteKey, keys.ServerWriteIV) - } else { - gcm, err = ciphersuite.NewGCM(keys.ServerWriteKey, keys.ServerWriteIV, keys.ClientWriteKey, keys.ClientWriteIV) - } - c.gcm.Store(gcm) - return err -} - -// Init initializes the internal Cipher with keying material -func (c *TLSEcdheEcdsaWithAes128GcmSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { - const ( - prfMacLen = 0 - prfKeyLen = 16 - prfIvLen = 4 - ) - - return c.init(masterSecret, clientRandom, serverRandom, isClient, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) -} - -// Encrypt encrypts a single TLS RecordLayer -func (c *TLSEcdheEcdsaWithAes128GcmSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - cipherSuite, ok := c.gcm.Load().(*ciphersuite.GCM) - if !ok { - return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Encrypt(pkt, raw) -} - -// Decrypt decrypts a single TLS RecordLayer -func (c *TLSEcdheEcdsaWithAes128GcmSha256) Decrypt(raw []byte) ([]byte, error) { - cipherSuite, ok := c.gcm.Load().(*ciphersuite.GCM) - if !ok { - return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Decrypt(raw) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go deleted file mode 100644 index 577192c8..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_cbc_sha.go +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/sha1" //nolint: gosec,gci - "crypto/sha256" - "fmt" - "hash" - "sync/atomic" - - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// TLSEcdheEcdsaWithAes256CbcSha represents a TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CipherSuite -type TLSEcdheEcdsaWithAes256CbcSha struct { - cbc atomic.Value // *cryptoCBC -} - -// CertificateType returns what type of certficate this CipherSuite exchanges -func (c *TLSEcdheEcdsaWithAes256CbcSha) CertificateType() clientcertificate.Type { - return clientcertificate.ECDSASign -} - -// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake -func (c *TLSEcdheEcdsaWithAes256CbcSha) KeyExchangeAlgorithm() KeyExchangeAlgorithm { - return KeyExchangeAlgorithmEcdhe -} - -// ECC uses Elliptic Curve Cryptography -func (c *TLSEcdheEcdsaWithAes256CbcSha) ECC() bool { - return true -} - -// ID returns the ID of the CipherSuite -func (c *TLSEcdheEcdsaWithAes256CbcSha) ID() ID { - return TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA -} - -func (c *TLSEcdheEcdsaWithAes256CbcSha) String() string { - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" -} - -// HashFunc returns the hashing func for this CipherSuite -func (c *TLSEcdheEcdsaWithAes256CbcSha) HashFunc() func() hash.Hash { - return sha256.New -} - -// AuthenticationType controls what authentication method is using during the handshake -func (c *TLSEcdheEcdsaWithAes256CbcSha) AuthenticationType() AuthenticationType { - return AuthenticationTypeCertificate -} - -// IsInitialized returns if the CipherSuite has keying material and can -// encrypt/decrypt packets -func (c *TLSEcdheEcdsaWithAes256CbcSha) IsInitialized() bool { - return c.cbc.Load() != nil -} - -// Init initializes the internal Cipher with keying material -func (c *TLSEcdheEcdsaWithAes256CbcSha) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { - const ( - prfMacLen = 20 - prfKeyLen = 32 - prfIvLen = 16 - ) - - keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) - if err != nil { - return err - } - - var cbc *ciphersuite.CBC - if isClient { - cbc, err = ciphersuite.NewCBC( - keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, - keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, - sha1.New, - ) - } else { - cbc, err = ciphersuite.NewCBC( - keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, - keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, - sha1.New, - ) - } - c.cbc.Store(cbc) - - return err -} - -// Encrypt encrypts a single TLS RecordLayer -func (c *TLSEcdheEcdsaWithAes256CbcSha) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) - if !ok { - return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Encrypt(pkt, raw) -} - -// Decrypt decrypts a single TLS RecordLayer -func (c *TLSEcdheEcdsaWithAes256CbcSha) Decrypt(raw []byte) ([]byte, error) { - cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) - if !ok { - return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Decrypt(raw) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go deleted file mode 100644 index 2a3cfa4f..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_ecdsa_with_aes_256_gcm_sha384.go +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/sha512" - "hash" -) - -// TLSEcdheEcdsaWithAes256GcmSha384 represents a TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CipherSuite -type TLSEcdheEcdsaWithAes256GcmSha384 struct { - TLSEcdheEcdsaWithAes128GcmSha256 -} - -// ID returns the ID of the CipherSuite -func (c *TLSEcdheEcdsaWithAes256GcmSha384) ID() ID { - return TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 -} - -func (c *TLSEcdheEcdsaWithAes256GcmSha384) String() string { - return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" -} - -// HashFunc returns the hashing func for this CipherSuite -func (c *TLSEcdheEcdsaWithAes256GcmSha384) HashFunc() func() hash.Hash { - return sha512.New384 -} - -// Init initializes the internal Cipher with keying material -func (c *TLSEcdheEcdsaWithAes256GcmSha384) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { - const ( - prfMacLen = 0 - prfKeyLen = 32 - prfIvLen = 4 - ) - - return c.init(masterSecret, clientRandom, serverRandom, isClient, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go deleted file mode 100644 index 75a25633..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_psk_with_aes_128_cbc_sha256.go +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/sha256" - "fmt" - "hash" - "sync/atomic" - - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// TLSEcdhePskWithAes128CbcSha256 implements the TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 CipherSuite -type TLSEcdhePskWithAes128CbcSha256 struct { - cbc atomic.Value // *cryptoCBC -} - -// NewTLSEcdhePskWithAes128CbcSha256 creates TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher. -func NewTLSEcdhePskWithAes128CbcSha256() *TLSEcdhePskWithAes128CbcSha256 { - return &TLSEcdhePskWithAes128CbcSha256{} -} - -// CertificateType returns what type of certificate this CipherSuite exchanges -func (c *TLSEcdhePskWithAes128CbcSha256) CertificateType() clientcertificate.Type { - return clientcertificate.Type(0) -} - -// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake -func (c *TLSEcdhePskWithAes128CbcSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm { - return (KeyExchangeAlgorithmPsk | KeyExchangeAlgorithmEcdhe) -} - -// ECC uses Elliptic Curve Cryptography -func (c *TLSEcdhePskWithAes128CbcSha256) ECC() bool { - return true -} - -// ID returns the ID of the CipherSuite -func (c *TLSEcdhePskWithAes128CbcSha256) ID() ID { - return TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 -} - -func (c *TLSEcdhePskWithAes128CbcSha256) String() string { - return "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256" -} - -// HashFunc returns the hashing func for this CipherSuite -func (c *TLSEcdhePskWithAes128CbcSha256) HashFunc() func() hash.Hash { - return sha256.New -} - -// AuthenticationType controls what authentication method is using during the handshake -func (c *TLSEcdhePskWithAes128CbcSha256) AuthenticationType() AuthenticationType { - return AuthenticationTypePreSharedKey -} - -// IsInitialized returns if the CipherSuite has keying material and can -// encrypt/decrypt packets -func (c *TLSEcdhePskWithAes128CbcSha256) IsInitialized() bool { - return c.cbc.Load() != nil -} - -// Init initializes the internal Cipher with keying material -func (c *TLSEcdhePskWithAes128CbcSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { - const ( - prfMacLen = 32 - prfKeyLen = 16 - prfIvLen = 16 - ) - - keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) - if err != nil { - return err - } - - var cbc *ciphersuite.CBC - if isClient { - cbc, err = ciphersuite.NewCBC( - keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, - keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, - c.HashFunc(), - ) - } else { - cbc, err = ciphersuite.NewCBC( - keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, - keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, - c.HashFunc(), - ) - } - c.cbc.Store(cbc) - - return err -} - -// Encrypt encrypts a single TLS RecordLayer -func (c *TLSEcdhePskWithAes128CbcSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) - if !ok { // !c.isInitialized() - return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Encrypt(pkt, raw) -} - -// Decrypt decrypts a single TLS RecordLayer -func (c *TLSEcdhePskWithAes128CbcSha256) Decrypt(raw []byte) ([]byte, error) { - cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) - if !ok { // !c.isInitialized() - return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Decrypt(raw) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go deleted file mode 100644 index 478a2e0d..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_128_gcm_sha256.go +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - -// TLSEcdheRsaWithAes128GcmSha256 implements the TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 CipherSuite -type TLSEcdheRsaWithAes128GcmSha256 struct { - TLSEcdheEcdsaWithAes128GcmSha256 -} - -// CertificateType returns what type of certificate this CipherSuite exchanges -func (c *TLSEcdheRsaWithAes128GcmSha256) CertificateType() clientcertificate.Type { - return clientcertificate.RSASign -} - -// ID returns the ID of the CipherSuite -func (c *TLSEcdheRsaWithAes128GcmSha256) ID() ID { - return TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -} - -func (c *TLSEcdheRsaWithAes128GcmSha256) String() string { - return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go deleted file mode 100644 index 8e88ee63..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_cbc_sha.go +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - -// TLSEcdheRsaWithAes256CbcSha implements the TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA CipherSuite -type TLSEcdheRsaWithAes256CbcSha struct { - TLSEcdheEcdsaWithAes256CbcSha -} - -// CertificateType returns what type of certificate this CipherSuite exchanges -func (c *TLSEcdheRsaWithAes256CbcSha) CertificateType() clientcertificate.Type { - return clientcertificate.RSASign -} - -// ID returns the ID of the CipherSuite -func (c *TLSEcdheRsaWithAes256CbcSha) ID() ID { - return TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA -} - -func (c *TLSEcdheRsaWithAes256CbcSha) String() string { - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go deleted file mode 100644 index 752fb529..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_ecdhe_rsa_with_aes_256_gcm_sha384.go +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - -// TLSEcdheRsaWithAes256GcmSha384 implements the TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 CipherSuite -type TLSEcdheRsaWithAes256GcmSha384 struct { - TLSEcdheEcdsaWithAes256GcmSha384 -} - -// CertificateType returns what type of certificate this CipherSuite exchanges -func (c *TLSEcdheRsaWithAes256GcmSha384) CertificateType() clientcertificate.Type { - return clientcertificate.RSASign -} - -// ID returns the ID of the CipherSuite -func (c *TLSEcdheRsaWithAes256GcmSha384) ID() ID { - return TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 -} - -func (c *TLSEcdheRsaWithAes256GcmSha384) String() string { - return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go deleted file mode 100644 index 7336ad94..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_cbc_sha256.go +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/sha256" - "fmt" - "hash" - "sync/atomic" - - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// TLSPskWithAes128CbcSha256 implements the TLS_PSK_WITH_AES_128_CBC_SHA256 CipherSuite -type TLSPskWithAes128CbcSha256 struct { - cbc atomic.Value // *cryptoCBC -} - -// CertificateType returns what type of certificate this CipherSuite exchanges -func (c *TLSPskWithAes128CbcSha256) CertificateType() clientcertificate.Type { - return clientcertificate.Type(0) -} - -// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake -func (c *TLSPskWithAes128CbcSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm { - return KeyExchangeAlgorithmPsk -} - -// ECC uses Elliptic Curve Cryptography -func (c *TLSPskWithAes128CbcSha256) ECC() bool { - return false -} - -// ID returns the ID of the CipherSuite -func (c *TLSPskWithAes128CbcSha256) ID() ID { - return TLS_PSK_WITH_AES_128_CBC_SHA256 -} - -func (c *TLSPskWithAes128CbcSha256) String() string { - return "TLS_PSK_WITH_AES_128_CBC_SHA256" -} - -// HashFunc returns the hashing func for this CipherSuite -func (c *TLSPskWithAes128CbcSha256) HashFunc() func() hash.Hash { - return sha256.New -} - -// AuthenticationType controls what authentication method is using during the handshake -func (c *TLSPskWithAes128CbcSha256) AuthenticationType() AuthenticationType { - return AuthenticationTypePreSharedKey -} - -// IsInitialized returns if the CipherSuite has keying material and can -// encrypt/decrypt packets -func (c *TLSPskWithAes128CbcSha256) IsInitialized() bool { - return c.cbc.Load() != nil -} - -// Init initializes the internal Cipher with keying material -func (c *TLSPskWithAes128CbcSha256) Init(masterSecret, clientRandom, serverRandom []byte, isClient bool) error { - const ( - prfMacLen = 32 - prfKeyLen = 16 - prfIvLen = 16 - ) - - keys, err := prf.GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom, prfMacLen, prfKeyLen, prfIvLen, c.HashFunc()) - if err != nil { - return err - } - - var cbc *ciphersuite.CBC - if isClient { - cbc, err = ciphersuite.NewCBC( - keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, - keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, - c.HashFunc(), - ) - } else { - cbc, err = ciphersuite.NewCBC( - keys.ServerWriteKey, keys.ServerWriteIV, keys.ServerMACKey, - keys.ClientWriteKey, keys.ClientWriteIV, keys.ClientMACKey, - c.HashFunc(), - ) - } - c.cbc.Store(cbc) - - return err -} - -// Encrypt encrypts a single TLS RecordLayer -func (c *TLSPskWithAes128CbcSha256) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) - if !ok { - return nil, fmt.Errorf("%w, unable to encrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Encrypt(pkt, raw) -} - -// Decrypt decrypts a single TLS RecordLayer -func (c *TLSPskWithAes128CbcSha256) Decrypt(raw []byte) ([]byte, error) { - cipherSuite, ok := c.cbc.Load().(*ciphersuite.CBC) - if !ok { - return nil, fmt.Errorf("%w, unable to decrypt", errCipherSuiteNotInit) - } - - return cipherSuite.Decrypt(raw) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go deleted file mode 100644 index 1ded09b8..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" -) - -// NewTLSPskWithAes128Ccm returns the TLS_PSK_WITH_AES_128_CCM CipherSuite -func NewTLSPskWithAes128Ccm() *Aes128Ccm { - return newAes128Ccm(clientcertificate.Type(0), TLS_PSK_WITH_AES_128_CCM, true, ciphersuite.CCMTagLength, KeyExchangeAlgorithmPsk, false) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go deleted file mode 100644 index 47819707..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_ccm8.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" -) - -// NewTLSPskWithAes128Ccm8 returns the TLS_PSK_WITH_AES_128_CCM_8 CipherSuite -func NewTLSPskWithAes128Ccm8() *Aes128Ccm { - return newAes128Ccm(clientcertificate.Type(0), TLS_PSK_WITH_AES_128_CCM_8, true, ciphersuite.CCMTagLength8, KeyExchangeAlgorithmPsk, false) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go deleted file mode 100644 index 8ab5b89a..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_128_gcm_sha256.go +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - -// TLSPskWithAes128GcmSha256 implements the TLS_PSK_WITH_AES_128_GCM_SHA256 CipherSuite -type TLSPskWithAes128GcmSha256 struct { - TLSEcdheEcdsaWithAes128GcmSha256 -} - -// CertificateType returns what type of certificate this CipherSuite exchanges -func (c *TLSPskWithAes128GcmSha256) CertificateType() clientcertificate.Type { - return clientcertificate.Type(0) -} - -// KeyExchangeAlgorithm controls what key exchange algorithm is using during the handshake -func (c *TLSPskWithAes128GcmSha256) KeyExchangeAlgorithm() KeyExchangeAlgorithm { - return KeyExchangeAlgorithmPsk -} - -// ID returns the ID of the CipherSuite -func (c *TLSPskWithAes128GcmSha256) ID() ID { - return TLS_PSK_WITH_AES_128_GCM_SHA256 -} - -func (c *TLSPskWithAes128GcmSha256) String() string { - return "TLS_PSK_WITH_AES_128_GCM_SHA256" -} - -// AuthenticationType controls what authentication method is using during the handshake -func (c *TLSPskWithAes128GcmSha256) AuthenticationType() AuthenticationType { - return AuthenticationTypePreSharedKey -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go deleted file mode 100644 index 32d50301..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/tls_psk_with_aes_256_ccm8.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "github.com/pion/dtls/v2/pkg/crypto/ciphersuite" - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" -) - -// NewTLSPskWithAes256Ccm8 returns the TLS_PSK_WITH_AES_256_CCM_8 CipherSuite -func NewTLSPskWithAes256Ccm8() *Aes256Ccm { - return newAes256Ccm(clientcertificate.Type(0), TLS_PSK_WITH_AES_256_CCM_8, true, ciphersuite.CCMTagLength8, KeyExchangeAlgorithmPsk, false) -} diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go deleted file mode 100644 index 2da21e64..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/authentication_type.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package types - -// AuthenticationType controls what authentication method is using during the handshake -type AuthenticationType int - -// AuthenticationType Enums -const ( - AuthenticationTypeCertificate AuthenticationType = iota + 1 - AuthenticationTypePreSharedKey - AuthenticationTypeAnonymous -) diff --git a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go b/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go deleted file mode 100644 index c2c39113..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/ciphersuite/types/key_exchange_algorithm.go +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package types provides types for TLS Ciphers -package types - -// KeyExchangeAlgorithm controls what exchange algorithm was chosen. -type KeyExchangeAlgorithm int - -// KeyExchangeAlgorithm Bitmask -const ( - KeyExchangeAlgorithmNone KeyExchangeAlgorithm = 0 - KeyExchangeAlgorithmPsk KeyExchangeAlgorithm = iota << 1 - KeyExchangeAlgorithmEcdhe -) - -// Has check if keyExchangeAlgorithm is supported. -func (a KeyExchangeAlgorithm) Has(v KeyExchangeAlgorithm) bool { - return (a & v) == v -} diff --git a/vendor/github.com/pion/dtls/v2/internal/closer/closer.go b/vendor/github.com/pion/dtls/v2/internal/closer/closer.go deleted file mode 100644 index bfa171cd..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/closer/closer.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package closer provides signaling channel for shutdown -package closer - -import ( - "context" -) - -// Closer allows for each signaling a channel for shutdown -type Closer struct { - ctx context.Context - closeFunc func() -} - -// NewCloser creates a new instance of Closer -func NewCloser() *Closer { - ctx, closeFunc := context.WithCancel(context.Background()) - return &Closer{ - ctx: ctx, - closeFunc: closeFunc, - } -} - -// NewCloserWithParent creates a new instance of Closer with a parent context -func NewCloserWithParent(ctx context.Context) *Closer { - ctx, closeFunc := context.WithCancel(ctx) - return &Closer{ - ctx: ctx, - closeFunc: closeFunc, - } -} - -// Done returns a channel signaling when it is done -func (c *Closer) Done() <-chan struct{} { - return c.ctx.Done() -} - -// Err returns an error of the context -func (c *Closer) Err() error { - return c.ctx.Err() -} - -// Close sends a signal to trigger the ctx done channel -func (c *Closer) Close() { - c.closeFunc() -} diff --git a/vendor/github.com/pion/dtls/v2/internal/util/util.go b/vendor/github.com/pion/dtls/v2/internal/util/util.go deleted file mode 100644 index 685910fc..00000000 --- a/vendor/github.com/pion/dtls/v2/internal/util/util.go +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package util contains small helpers used across the repo -package util - -import ( - "encoding/binary" -) - -// BigEndianUint24 returns the value of a big endian uint24 -func BigEndianUint24(raw []byte) uint32 { - if len(raw) < 3 { - return 0 - } - - rawCopy := make([]byte, 4) - copy(rawCopy[1:], raw) - return binary.BigEndian.Uint32(rawCopy) -} - -// PutBigEndianUint24 encodes a uint24 and places into out -func PutBigEndianUint24(out []byte, in uint32) { - tmp := make([]byte, 4) - binary.BigEndian.PutUint32(tmp, in) - copy(out, tmp[1:]) -} - -// PutBigEndianUint48 encodes a uint64 and places into out -func PutBigEndianUint48(out []byte, in uint64) { - tmp := make([]byte, 8) - binary.BigEndian.PutUint64(tmp, in) - copy(out, tmp[2:]) -} - -// Max returns the larger value -func Max(a, b int) int { - if a > b { - return a - } - return b -} diff --git a/vendor/github.com/pion/dtls/v2/listener.go b/vendor/github.com/pion/dtls/v2/listener.go deleted file mode 100644 index 190d236c..00000000 --- a/vendor/github.com/pion/dtls/v2/listener.go +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "net" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" - "github.com/pion/transport/v2/udp" -) - -// Listen creates a DTLS listener -func Listen(network string, laddr *net.UDPAddr, config *Config) (net.Listener, error) { - if err := validateConfig(config); err != nil { - return nil, err - } - - lc := udp.ListenConfig{ - AcceptFilter: func(packet []byte) bool { - pkts, err := recordlayer.UnpackDatagram(packet) - if err != nil || len(pkts) < 1 { - return false - } - h := &recordlayer.Header{} - if err := h.Unmarshal(pkts[0]); err != nil { - return false - } - return h.ContentType == protocol.ContentTypeHandshake - }, - } - parent, err := lc.Listen(network, laddr) - if err != nil { - return nil, err - } - return &listener{ - config: config, - parent: parent, - }, nil -} - -// NewListener creates a DTLS listener which accepts connections from an inner Listener. -func NewListener(inner net.Listener, config *Config) (net.Listener, error) { - if err := validateConfig(config); err != nil { - return nil, err - } - - return &listener{ - config: config, - parent: inner, - }, nil -} - -// listener represents a DTLS listener -type listener struct { - config *Config - parent net.Listener -} - -// Accept waits for and returns the next connection to the listener. -// You have to either close or read on all connection that are created. -// Connection handshake will timeout using ConnectContextMaker in the Config. -// If you want to specify the timeout duration, set ConnectContextMaker. -func (l *listener) Accept() (net.Conn, error) { - c, err := l.parent.Accept() - if err != nil { - return nil, err - } - return Server(c, l.config) -} - -// Close closes the listener. -// Any blocked Accept operations will be unblocked and return errors. -// Already Accepted connections are not closed. -func (l *listener) Close() error { - return l.parent.Close() -} - -// Addr returns the listener's network address. -func (l *listener) Addr() net.Addr { - return l.parent.Addr() -} diff --git a/vendor/github.com/pion/dtls/v2/packet.go b/vendor/github.com/pion/dtls/v2/packet.go deleted file mode 100644 index 55d6272e..00000000 --- a/vendor/github.com/pion/dtls/v2/packet.go +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import "github.com/pion/dtls/v2/pkg/protocol/recordlayer" - -type packet struct { - record *recordlayer.RecordLayer - shouldEncrypt bool - resetLocalSequenceNumber bool -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go deleted file mode 100644 index d6e6fc47..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ccm/ccm.go +++ /dev/null @@ -1,254 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package ccm implements a CCM, Counter with CBC-MAC -// as per RFC 3610. -// -// See https://tools.ietf.org/html/rfc3610 -// -// This code was lifted from https://github.com/bocajim/dtls/blob/a3300364a283fcb490d28a93d7fcfa7ba437fbbe/ccm/ccm.go -// and as such was not written by the Pions authors. Like Pions this -// code is licensed under MIT. -// -// A request for including CCM into the Go standard library -// can be found as issue #27484 on the https://github.com/golang/go/ -// repository. -package ccm - -import ( - "crypto/cipher" - "crypto/subtle" - "encoding/binary" - "errors" - "math" -) - -// ccm represents a Counter with CBC-MAC with a specific key. -type ccm struct { - b cipher.Block - M uint8 - L uint8 -} - -const ccmBlockSize = 16 - -// CCM is a block cipher in Counter with CBC-MAC mode. -// Providing authenticated encryption with associated data via the cipher.AEAD interface. -type CCM interface { - cipher.AEAD - // MaxLength returns the maxium length of plaintext in calls to Seal. - // The maximum length of ciphertext in calls to Open is MaxLength()+Overhead(). - // The maximum length is related to CCM's `L` parameter (15-noncesize) and - // is 1<<(8*L) - 1 (but also limited by the maxium size of an int). - MaxLength() int -} - -var ( - errInvalidBlockSize = errors.New("ccm: NewCCM requires 128-bit block cipher") - errInvalidTagSize = errors.New("ccm: tagsize must be 4, 6, 8, 10, 12, 14, or 16") - errInvalidNonceSize = errors.New("ccm: invalid nonce size") -) - -// NewCCM returns the given 128-bit block cipher wrapped in CCM. -// The tagsize must be an even integer between 4 and 16 inclusive -// and is used as CCM's `M` parameter. -// The noncesize must be an integer between 7 and 13 inclusive, -// 15-noncesize is used as CCM's `L` parameter. -func NewCCM(b cipher.Block, tagsize, noncesize int) (CCM, error) { - if b.BlockSize() != ccmBlockSize { - return nil, errInvalidBlockSize - } - if tagsize < 4 || tagsize > 16 || tagsize&1 != 0 { - return nil, errInvalidTagSize - } - lensize := 15 - noncesize - if lensize < 2 || lensize > 8 { - return nil, errInvalidNonceSize - } - c := &ccm{b: b, M: uint8(tagsize), L: uint8(lensize)} - return c, nil -} - -func (c *ccm) NonceSize() int { return 15 - int(c.L) } -func (c *ccm) Overhead() int { return int(c.M) } -func (c *ccm) MaxLength() int { return maxlen(c.L, c.Overhead()) } - -func maxlen(l uint8, tagsize int) int { - max := (uint64(1) << (8 * l)) - 1 - if m64 := uint64(math.MaxInt64) - uint64(tagsize); l > 8 || max > m64 { - max = m64 // The maximum lentgh on a 64bit arch - } - if max != uint64(int(max)) { - return math.MaxInt32 - tagsize // We have only 32bit int's - } - return int(max) -} - -// MaxNonceLength returns the maximum nonce length for a given plaintext length. -// A return value <= 0 indicates that plaintext length is too large for -// any nonce length. -func MaxNonceLength(pdatalen int) int { - const tagsize = 16 - for L := 2; L <= 8; L++ { - if maxlen(uint8(L), tagsize) >= pdatalen { - return 15 - L - } - } - return 0 -} - -func (c *ccm) cbcRound(mac, data []byte) { - for i := 0; i < ccmBlockSize; i++ { - mac[i] ^= data[i] - } - c.b.Encrypt(mac, mac) -} - -func (c *ccm) cbcData(mac, data []byte) { - for len(data) >= ccmBlockSize { - c.cbcRound(mac, data[:ccmBlockSize]) - data = data[ccmBlockSize:] - } - if len(data) > 0 { - var block [ccmBlockSize]byte - copy(block[:], data) - c.cbcRound(mac, block[:]) - } -} - -var errPlaintextTooLong = errors.New("ccm: plaintext too large") - -func (c *ccm) tag(nonce, plaintext, adata []byte) ([]byte, error) { - var mac [ccmBlockSize]byte - - if len(adata) > 0 { - mac[0] |= 1 << 6 - } - mac[0] |= (c.M - 2) << 2 - mac[0] |= c.L - 1 - if len(nonce) != c.NonceSize() { - return nil, errInvalidNonceSize - } - if len(plaintext) > c.MaxLength() { - return nil, errPlaintextTooLong - } - binary.BigEndian.PutUint64(mac[ccmBlockSize-8:], uint64(len(plaintext))) - copy(mac[1:ccmBlockSize-c.L], nonce) - c.b.Encrypt(mac[:], mac[:]) - - var block [ccmBlockSize]byte - if n := uint64(len(adata)); n > 0 { - // First adata block includes adata length - i := 2 - if n <= 0xfeff { - binary.BigEndian.PutUint16(block[:i], uint16(n)) - } else { - block[0] = 0xfe - block[1] = 0xff - if n < uint64(1<<32) { - i = 2 + 4 - binary.BigEndian.PutUint32(block[2:i], uint32(n)) - } else { - i = 2 + 8 - binary.BigEndian.PutUint64(block[2:i], n) - } - } - i = copy(block[i:], adata) - c.cbcRound(mac[:], block[:]) - c.cbcData(mac[:], adata[i:]) - } - - if len(plaintext) > 0 { - c.cbcData(mac[:], plaintext) - } - - return mac[:c.M], nil -} - -// sliceForAppend takes a slice and a requested number of bytes. It returns a -// slice with the contents of the given slice followed by that many bytes and a -// second slice that aliases into it and contains only the extra bytes. If the -// original slice has sufficient capacity then no allocation is performed. -// From crypto/cipher/gcm.go -func sliceForAppend(in []byte, n int) (head, tail []byte) { - if total := len(in) + n; cap(in) >= total { - head = in[:total] - } else { - head = make([]byte, total) - copy(head, in) - } - tail = head[len(in):] - return -} - -// Seal encrypts and authenticates plaintext, authenticates the -// additional data and appends the result to dst, returning the updated -// slice. The nonce must be NonceSize() bytes long and unique for all -// time, for a given key. -// The plaintext must be no longer than MaxLength() bytes long. -// -// The plaintext and dst may alias exactly or not at all. -func (c *ccm) Seal(dst, nonce, plaintext, adata []byte) []byte { - tag, err := c.tag(nonce, plaintext, adata) - if err != nil { - // The cipher.AEAD interface doesn't allow for an error return. - panic(err) // nolint - } - - var iv, s0 [ccmBlockSize]byte - iv[0] = c.L - 1 - copy(iv[1:ccmBlockSize-c.L], nonce) - c.b.Encrypt(s0[:], iv[:]) - for i := 0; i < int(c.M); i++ { - tag[i] ^= s0[i] - } - iv[len(iv)-1] |= 1 - stream := cipher.NewCTR(c.b, iv[:]) - ret, out := sliceForAppend(dst, len(plaintext)+int(c.M)) - stream.XORKeyStream(out, plaintext) - copy(out[len(plaintext):], tag) - return ret -} - -var ( - errOpen = errors.New("ccm: message authentication failed") - errCiphertextTooShort = errors.New("ccm: ciphertext too short") - errCiphertextTooLong = errors.New("ccm: ciphertext too long") -) - -func (c *ccm) Open(dst, nonce, ciphertext, adata []byte) ([]byte, error) { - if len(ciphertext) < int(c.M) { - return nil, errCiphertextTooShort - } - if len(ciphertext) > c.MaxLength()+c.Overhead() { - return nil, errCiphertextTooLong - } - - tag := make([]byte, int(c.M)) - copy(tag, ciphertext[len(ciphertext)-int(c.M):]) - ciphertextWithoutTag := ciphertext[:len(ciphertext)-int(c.M)] - - var iv, s0 [ccmBlockSize]byte - iv[0] = c.L - 1 - copy(iv[1:ccmBlockSize-c.L], nonce) - c.b.Encrypt(s0[:], iv[:]) - for i := 0; i < int(c.M); i++ { - tag[i] ^= s0[i] - } - iv[len(iv)-1] |= 1 - stream := cipher.NewCTR(c.b, iv[:]) - - // Cannot decrypt directly to dst since we're not supposed to - // reveal the plaintext to the caller if authentication fails. - plaintext := make([]byte, len(ciphertextWithoutTag)) - stream.XORKeyStream(plaintext, ciphertextWithoutTag) - expectedTag, err := c.tag(nonce, plaintext, adata) - if err != nil { - return nil, err - } - - if subtle.ConstantTimeCompare(tag, expectedTag) != 1 { - return nil, errOpen - } - return append(dst, plaintext...), nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go deleted file mode 100644 index 460fb143..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/cbc.go +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( //nolint:gci - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/rand" - "encoding/binary" - "hash" - - "github.com/pion/dtls/v2/internal/util" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// block ciphers using cipher block chaining. -type cbcMode interface { - cipher.BlockMode - SetIV([]byte) -} - -// CBC Provides an API to Encrypt/Decrypt DTLS 1.2 Packets -type CBC struct { - writeCBC, readCBC cbcMode - writeMac, readMac []byte - h prf.HashFunc -} - -// NewCBC creates a DTLS CBC Cipher -func NewCBC(localKey, localWriteIV, localMac, remoteKey, remoteWriteIV, remoteMac []byte, h prf.HashFunc) (*CBC, error) { - writeBlock, err := aes.NewCipher(localKey) - if err != nil { - return nil, err - } - - readBlock, err := aes.NewCipher(remoteKey) - if err != nil { - return nil, err - } - - writeCBC, ok := cipher.NewCBCEncrypter(writeBlock, localWriteIV).(cbcMode) - if !ok { - return nil, errFailedToCast - } - - readCBC, ok := cipher.NewCBCDecrypter(readBlock, remoteWriteIV).(cbcMode) - if !ok { - return nil, errFailedToCast - } - - return &CBC{ - writeCBC: writeCBC, - writeMac: localMac, - - readCBC: readCBC, - readMac: remoteMac, - h: h, - }, nil -} - -// Encrypt encrypt a DTLS RecordLayer message -func (c *CBC) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - payload := raw[recordlayer.HeaderSize:] - raw = raw[:recordlayer.HeaderSize] - blockSize := c.writeCBC.BlockSize() - - // Generate + Append MAC - h := pkt.Header - - MAC, err := c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, payload, c.writeMac, c.h) - if err != nil { - return nil, err - } - payload = append(payload, MAC...) - - // Generate + Append padding - padding := make([]byte, blockSize-len(payload)%blockSize) - paddingLen := len(padding) - for i := 0; i < paddingLen; i++ { - padding[i] = byte(paddingLen - 1) - } - payload = append(payload, padding...) - - // Generate IV - iv := make([]byte, blockSize) - if _, err := rand.Read(iv); err != nil { - return nil, err - } - - // Set IV + Encrypt + Prepend IV - c.writeCBC.SetIV(iv) - c.writeCBC.CryptBlocks(payload, payload) - payload = append(iv, payload...) - - // Prepend unencrypte header with encrypted payload - raw = append(raw, payload...) - - // Update recordLayer size to include IV+MAC+Padding - binary.BigEndian.PutUint16(raw[recordlayer.HeaderSize-2:], uint16(len(raw)-recordlayer.HeaderSize)) - - return raw, nil -} - -// Decrypt decrypts a DTLS RecordLayer message -func (c *CBC) Decrypt(in []byte) ([]byte, error) { - body := in[recordlayer.HeaderSize:] - blockSize := c.readCBC.BlockSize() - mac := c.h() - - var h recordlayer.Header - err := h.Unmarshal(in) - switch { - case err != nil: - return nil, err - case h.ContentType == protocol.ContentTypeChangeCipherSpec: - // Nothing to encrypt with ChangeCipherSpec - return in, nil - case len(body)%blockSize != 0 || len(body) < blockSize+util.Max(mac.Size()+1, blockSize): - return nil, errNotEnoughRoomForNonce - } - - // Set + remove per record IV - c.readCBC.SetIV(body[:blockSize]) - body = body[blockSize:] - - // Decrypt - c.readCBC.CryptBlocks(body, body) - - // Padding+MAC needs to be checked in constant time - // Otherwise we reveal information about the level of correctness - paddingLen, paddingGood := examinePadding(body) - if paddingGood != 255 { - return nil, errInvalidMAC - } - - macSize := mac.Size() - if len(body) < macSize { - return nil, errInvalidMAC - } - - dataEnd := len(body) - macSize - paddingLen - - expectedMAC := body[dataEnd : dataEnd+macSize] - actualMAC, err := c.hmac(h.Epoch, h.SequenceNumber, h.ContentType, h.Version, body[:dataEnd], c.readMac, c.h) - - // Compute Local MAC and compare - if err != nil || !hmac.Equal(actualMAC, expectedMAC) { - return nil, errInvalidMAC - } - - return append(in[:recordlayer.HeaderSize], body[:dataEnd]...), nil -} - -func (c *CBC) hmac(epoch uint16, sequenceNumber uint64, contentType protocol.ContentType, protocolVersion protocol.Version, payload []byte, key []byte, hf func() hash.Hash) ([]byte, error) { - h := hmac.New(hf, key) - - msg := make([]byte, 13) - - binary.BigEndian.PutUint16(msg, epoch) - util.PutBigEndianUint48(msg[2:], sequenceNumber) - msg[8] = byte(contentType) - msg[9] = protocolVersion.Major - msg[10] = protocolVersion.Minor - binary.BigEndian.PutUint16(msg[11:], uint16(len(payload))) - - if _, err := h.Write(msg); err != nil { - return nil, err - } else if _, err := h.Write(payload); err != nil { - return nil, err - } - - return h.Sum(nil), nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go deleted file mode 100644 index 24050dc9..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ccm.go +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/aes" - "crypto/rand" - "encoding/binary" - "fmt" - - "github.com/pion/dtls/v2/pkg/crypto/ccm" - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -// CCMTagLen is the length of Authentication Tag -type CCMTagLen int - -// CCM Enums -const ( - CCMTagLength8 CCMTagLen = 8 - CCMTagLength CCMTagLen = 16 - ccmNonceLength = 12 -) - -// CCM Provides an API to Encrypt/Decrypt DTLS 1.2 Packets -type CCM struct { - localCCM, remoteCCM ccm.CCM - localWriteIV, remoteWriteIV []byte - tagLen CCMTagLen -} - -// NewCCM creates a DTLS GCM Cipher -func NewCCM(tagLen CCMTagLen, localKey, localWriteIV, remoteKey, remoteWriteIV []byte) (*CCM, error) { - localBlock, err := aes.NewCipher(localKey) - if err != nil { - return nil, err - } - localCCM, err := ccm.NewCCM(localBlock, int(tagLen), ccmNonceLength) - if err != nil { - return nil, err - } - - remoteBlock, err := aes.NewCipher(remoteKey) - if err != nil { - return nil, err - } - remoteCCM, err := ccm.NewCCM(remoteBlock, int(tagLen), ccmNonceLength) - if err != nil { - return nil, err - } - - return &CCM{ - localCCM: localCCM, - localWriteIV: localWriteIV, - remoteCCM: remoteCCM, - remoteWriteIV: remoteWriteIV, - tagLen: tagLen, - }, nil -} - -// Encrypt encrypt a DTLS RecordLayer message -func (c *CCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - payload := raw[recordlayer.HeaderSize:] - raw = raw[:recordlayer.HeaderSize] - - nonce := append(append([]byte{}, c.localWriteIV[:4]...), make([]byte, 8)...) - if _, err := rand.Read(nonce[4:]); err != nil { - return nil, err - } - - additionalData := generateAEADAdditionalData(&pkt.Header, len(payload)) - encryptedPayload := c.localCCM.Seal(nil, nonce, payload, additionalData) - - encryptedPayload = append(nonce[4:], encryptedPayload...) - raw = append(raw, encryptedPayload...) - - // Update recordLayer size to include explicit nonce - binary.BigEndian.PutUint16(raw[recordlayer.HeaderSize-2:], uint16(len(raw)-recordlayer.HeaderSize)) - return raw, nil -} - -// Decrypt decrypts a DTLS RecordLayer message -func (c *CCM) Decrypt(in []byte) ([]byte, error) { - var h recordlayer.Header - err := h.Unmarshal(in) - switch { - case err != nil: - return nil, err - case h.ContentType == protocol.ContentTypeChangeCipherSpec: - // Nothing to encrypt with ChangeCipherSpec - return in, nil - case len(in) <= (8 + recordlayer.HeaderSize): - return nil, errNotEnoughRoomForNonce - } - - nonce := append(append([]byte{}, c.remoteWriteIV[:4]...), in[recordlayer.HeaderSize:recordlayer.HeaderSize+8]...) - out := in[recordlayer.HeaderSize+8:] - - additionalData := generateAEADAdditionalData(&h, len(out)-int(c.tagLen)) - out, err = c.remoteCCM.Open(out[:0], nonce, out, additionalData) - if err != nil { - return nil, fmt.Errorf("%w: %v", errDecryptPacket, err) //nolint:errorlint - } - return append(in[:recordlayer.HeaderSize], out...), nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go deleted file mode 100644 index 9d9fb741..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/ciphersuite.go +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package ciphersuite provides the crypto operations needed for a DTLS CipherSuite -package ciphersuite - -import ( - "encoding/binary" - "errors" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -var ( - errNotEnoughRoomForNonce = &protocol.InternalError{Err: errors.New("buffer not long enough to contain nonce")} //nolint:goerr113 - errDecryptPacket = &protocol.TemporaryError{Err: errors.New("failed to decrypt packet")} //nolint:goerr113 - errInvalidMAC = &protocol.TemporaryError{Err: errors.New("invalid mac")} //nolint:goerr113 - errFailedToCast = &protocol.FatalError{Err: errors.New("failed to cast")} //nolint:goerr113 -) - -func generateAEADAdditionalData(h *recordlayer.Header, payloadLen int) []byte { - var additionalData [13]byte - // SequenceNumber MUST be set first - // we only want uint48, clobbering an extra 2 (using uint64, Golang doesn't have uint48) - binary.BigEndian.PutUint64(additionalData[:], h.SequenceNumber) - binary.BigEndian.PutUint16(additionalData[:], h.Epoch) - additionalData[8] = byte(h.ContentType) - additionalData[9] = h.Version.Major - additionalData[10] = h.Version.Minor - binary.BigEndian.PutUint16(additionalData[len(additionalData)-2:], uint16(payloadLen)) - - return additionalData[:] -} - -// examinePadding returns, in constant time, the length of the padding to remove -// from the end of payload. It also returns a byte which is equal to 255 if the -// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2. -// -// https://github.com/golang/go/blob/039c2081d1178f90a8fa2f4e6958693129f8de33/src/crypto/tls/conn.go#L245 -func examinePadding(payload []byte) (toRemove int, good byte) { - if len(payload) < 1 { - return 0, 0 - } - - paddingLen := payload[len(payload)-1] - t := uint(len(payload)-1) - uint(paddingLen) - // if len(payload) >= (paddingLen - 1) then the MSB of t is zero - good = byte(int32(^t) >> 31) - - // The maximum possible padding length plus the actual length field - toCheck := 256 - // The length of the padded data is public, so we can use an if here - if toCheck > len(payload) { - toCheck = len(payload) - } - - for i := 0; i < toCheck; i++ { - t := uint(paddingLen) - uint(i) - // if i <= paddingLen then the MSB of t is zero - mask := byte(int32(^t) >> 31) - b := payload[len(payload)-1-i] - good &^= mask&paddingLen ^ mask&b - } - - // We AND together the bits of good and replicate the result across - // all the bits. - good &= good << 4 - good &= good << 2 - good &= good << 1 - good = uint8(int8(good) >> 7) - - toRemove = int(paddingLen) + 1 - - return toRemove, good -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go deleted file mode 100644 index c0fd1f76..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/ciphersuite/gcm.go +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ciphersuite - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "encoding/binary" - "fmt" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/recordlayer" -) - -const ( - gcmTagLength = 16 - gcmNonceLength = 12 -) - -// GCM Provides an API to Encrypt/Decrypt DTLS 1.2 Packets -type GCM struct { - localGCM, remoteGCM cipher.AEAD - localWriteIV, remoteWriteIV []byte -} - -// NewGCM creates a DTLS GCM Cipher -func NewGCM(localKey, localWriteIV, remoteKey, remoteWriteIV []byte) (*GCM, error) { - localBlock, err := aes.NewCipher(localKey) - if err != nil { - return nil, err - } - localGCM, err := cipher.NewGCM(localBlock) - if err != nil { - return nil, err - } - - remoteBlock, err := aes.NewCipher(remoteKey) - if err != nil { - return nil, err - } - remoteGCM, err := cipher.NewGCM(remoteBlock) - if err != nil { - return nil, err - } - - return &GCM{ - localGCM: localGCM, - localWriteIV: localWriteIV, - remoteGCM: remoteGCM, - remoteWriteIV: remoteWriteIV, - }, nil -} - -// Encrypt encrypt a DTLS RecordLayer message -func (g *GCM) Encrypt(pkt *recordlayer.RecordLayer, raw []byte) ([]byte, error) { - payload := raw[recordlayer.HeaderSize:] - raw = raw[:recordlayer.HeaderSize] - - nonce := make([]byte, gcmNonceLength) - copy(nonce, g.localWriteIV[:4]) - if _, err := rand.Read(nonce[4:]); err != nil { - return nil, err - } - - additionalData := generateAEADAdditionalData(&pkt.Header, len(payload)) - encryptedPayload := g.localGCM.Seal(nil, nonce, payload, additionalData) - r := make([]byte, len(raw)+len(nonce[4:])+len(encryptedPayload)) - copy(r, raw) - copy(r[len(raw):], nonce[4:]) - copy(r[len(raw)+len(nonce[4:]):], encryptedPayload) - - // Update recordLayer size to include explicit nonce - binary.BigEndian.PutUint16(r[recordlayer.HeaderSize-2:], uint16(len(r)-recordlayer.HeaderSize)) - return r, nil -} - -// Decrypt decrypts a DTLS RecordLayer message -func (g *GCM) Decrypt(in []byte) ([]byte, error) { - var h recordlayer.Header - err := h.Unmarshal(in) - switch { - case err != nil: - return nil, err - case h.ContentType == protocol.ContentTypeChangeCipherSpec: - // Nothing to encrypt with ChangeCipherSpec - return in, nil - case len(in) <= (8 + recordlayer.HeaderSize): - return nil, errNotEnoughRoomForNonce - } - - nonce := make([]byte, 0, gcmNonceLength) - nonce = append(append(nonce, g.remoteWriteIV[:4]...), in[recordlayer.HeaderSize:recordlayer.HeaderSize+8]...) - out := in[recordlayer.HeaderSize+8:] - - additionalData := generateAEADAdditionalData(&h, len(out)-gcmTagLength) - out, err = g.remoteGCM.Open(out[:0], nonce, out, additionalData) - if err != nil { - return nil, fmt.Errorf("%w: %v", errDecryptPacket, err) //nolint:errorlint - } - return append(in[:recordlayer.HeaderSize], out...), nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go deleted file mode 100644 index ddfa39eb..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/clientcertificate/client_certificate.go +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package clientcertificate provides all the support Client Certificate types -package clientcertificate - -// Type is used to communicate what -// type of certificate is being transported -// -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-2 -type Type byte - -// ClientCertificateType enums -const ( - RSASign Type = 1 - ECDSASign Type = 64 -) - -// Types returns all valid ClientCertificate Types -func Types() map[Type]bool { - return map[Type]bool{ - RSASign: true, - ECDSASign: true, - } -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go deleted file mode 100644 index 12652387..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/elliptic/elliptic.go +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package elliptic provides elliptic curve cryptography for DTLS -package elliptic - -import ( - "crypto/elliptic" - "crypto/rand" - "errors" - "fmt" - - "golang.org/x/crypto/curve25519" -) - -var errInvalidNamedCurve = errors.New("invalid named curve") - -// CurvePointFormat is used to represent the IANA registered curve points -// -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 -type CurvePointFormat byte - -// CurvePointFormat enums -const ( - CurvePointFormatUncompressed CurvePointFormat = 0 -) - -// Keypair is a Curve with a Private/Public Keypair -type Keypair struct { - Curve Curve - PublicKey []byte - PrivateKey []byte -} - -// CurveType is used to represent the IANA registered curve types for TLS -// -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-10 -type CurveType byte - -// CurveType enums -const ( - CurveTypeNamedCurve CurveType = 0x03 -) - -// CurveTypes returns all known curves -func CurveTypes() map[CurveType]struct{} { - return map[CurveType]struct{}{ - CurveTypeNamedCurve: {}, - } -} - -// Curve is used to represent the IANA registered curves for TLS -// -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 -type Curve uint16 - -// Curve enums -const ( - P256 Curve = 0x0017 - P384 Curve = 0x0018 - X25519 Curve = 0x001d -) - -func (c Curve) String() string { - switch c { - case P256: - return "P-256" - case P384: - return "P-384" - case X25519: - return "X25519" - } - return fmt.Sprintf("%#x", uint16(c)) -} - -// Curves returns all curves we implement -func Curves() map[Curve]bool { - return map[Curve]bool{ - X25519: true, - P256: true, - P384: true, - } -} - -// GenerateKeypair generates a keypair for the given Curve -func GenerateKeypair(c Curve) (*Keypair, error) { - switch c { //nolint:revive - case X25519: - tmp := make([]byte, 32) - if _, err := rand.Read(tmp); err != nil { - return nil, err - } - - var public, private [32]byte - copy(private[:], tmp) - - curve25519.ScalarBaseMult(&public, &private) - return &Keypair{X25519, public[:], private[:]}, nil - case P256: - return ellipticCurveKeypair(P256, elliptic.P256(), elliptic.P256()) - case P384: - return ellipticCurveKeypair(P384, elliptic.P384(), elliptic.P384()) - default: - return nil, errInvalidNamedCurve - } -} - -func ellipticCurveKeypair(nc Curve, c1, c2 elliptic.Curve) (*Keypair, error) { - privateKey, x, y, err := elliptic.GenerateKey(c1, rand.Reader) - if err != nil { - return nil, err - } - - return &Keypair{nc, elliptic.Marshal(c2, x, y), privateKey}, nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/fingerprint.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/fingerprint.go deleted file mode 100644 index 7c66265c..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/fingerprint.go +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package fingerprint provides a helper to create fingerprint string from certificate -package fingerprint - -import ( - "crypto" - "crypto/x509" - "errors" - "fmt" -) - -var ( - errHashUnavailable = errors.New("fingerprint: hash algorithm is not linked into the binary") - errInvalidFingerprintLength = errors.New("fingerprint: invalid fingerprint length") -) - -// Fingerprint creates a fingerprint for a certificate using the specified hash algorithm -func Fingerprint(cert *x509.Certificate, algo crypto.Hash) (string, error) { - if !algo.Available() { - return "", errHashUnavailable - } - h := algo.New() - for i := 0; i < len(cert.Raw); { - n, _ := h.Write(cert.Raw[i:]) - // Hash.Writer is specified to be never returning an error. - // https://golang.org/pkg/hash/#Hash - i += n - } - digest := []byte(fmt.Sprintf("%x", h.Sum(nil))) - - digestlen := len(digest) - if digestlen == 0 { - return "", nil - } - if digestlen%2 != 0 { - return "", errInvalidFingerprintLength - } - res := make([]byte, digestlen>>1+digestlen-1) - - pos := 0 - for i, c := range digest { - res[pos] = c - pos++ - if (i)%2 != 0 && i < digestlen-1 { - res[pos] = byte(':') - pos++ - } - } - - return string(res), nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/hash.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/hash.go deleted file mode 100644 index 3f988ffb..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/fingerprint/hash.go +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package fingerprint - -import ( - "crypto" - "errors" - "strings" -) - -var errInvalidHashAlgorithm = errors.New("fingerprint: invalid hash algorithm") - -func nameToHash() map[string]crypto.Hash { - return map[string]crypto.Hash{ - "md5": crypto.MD5, // [RFC3279] - "sha-1": crypto.SHA1, // [RFC3279] - "sha-224": crypto.SHA224, // [RFC4055] - "sha-256": crypto.SHA256, // [RFC4055] - "sha-384": crypto.SHA384, // [RFC4055] - "sha-512": crypto.SHA512, // [RFC4055] - } -} - -// HashFromString allows looking up a hash algorithm by it's string representation -func HashFromString(s string) (crypto.Hash, error) { - if h, ok := nameToHash()[strings.ToLower(s)]; ok { - return h, nil - } - return 0, errInvalidHashAlgorithm -} - -// StringFromHash allows looking up a string representation of the crypto.Hash. -func StringFromHash(hash crypto.Hash) (string, error) { - for s, h := range nameToHash() { - if h == hash { - return s, nil - } - } - return "", errInvalidHashAlgorithm -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go deleted file mode 100644 index 9966626e..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/hash/hash.go +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package hash provides TLS HashAlgorithm as defined in TLS 1.2 -package hash - -import ( //nolint:gci - "crypto" - "crypto/md5" //nolint:gosec - "crypto/sha1" //nolint:gosec - "crypto/sha256" - "crypto/sha512" -) - -// Algorithm is used to indicate the hash algorithm used -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18 -type Algorithm uint16 - -// Supported hash algorithms -const ( - None Algorithm = 0 // Blacklisted - MD5 Algorithm = 1 // Blacklisted - SHA1 Algorithm = 2 // Blacklisted - SHA224 Algorithm = 3 - SHA256 Algorithm = 4 - SHA384 Algorithm = 5 - SHA512 Algorithm = 6 - Ed25519 Algorithm = 8 -) - -// String makes hashAlgorithm printable -func (a Algorithm) String() string { - switch a { - case None: - return "none" - case MD5: - return "md5" // [RFC3279] - case SHA1: - return "sha-1" // [RFC3279] - case SHA224: - return "sha-224" // [RFC4055] - case SHA256: - return "sha-256" // [RFC4055] - case SHA384: - return "sha-384" // [RFC4055] - case SHA512: - return "sha-512" // [RFC4055] - case Ed25519: - return "null" - default: - return "unknown or unsupported hash algorithm" - } -} - -// Digest performs a digest on the passed value -func (a Algorithm) Digest(b []byte) []byte { - switch a { - case None: - return nil - case MD5: - hash := md5.Sum(b) // #nosec - return hash[:] - case SHA1: - hash := sha1.Sum(b) // #nosec - return hash[:] - case SHA224: - hash := sha256.Sum224(b) - return hash[:] - case SHA256: - hash := sha256.Sum256(b) - return hash[:] - case SHA384: - hash := sha512.Sum384(b) - return hash[:] - case SHA512: - hash := sha512.Sum512(b) - return hash[:] - default: - return nil - } -} - -// Insecure returns if the given HashAlgorithm is considered secure in DTLS 1.2 -func (a Algorithm) Insecure() bool { - switch a { - case None, MD5, SHA1: - return true - default: - return false - } -} - -// CryptoHash returns the crypto.Hash implementation for the given HashAlgorithm -func (a Algorithm) CryptoHash() crypto.Hash { - switch a { - case None: - return crypto.Hash(0) - case MD5: - return crypto.MD5 - case SHA1: - return crypto.SHA1 - case SHA224: - return crypto.SHA224 - case SHA256: - return crypto.SHA256 - case SHA384: - return crypto.SHA384 - case SHA512: - return crypto.SHA512 - case Ed25519: - return crypto.Hash(0) - default: - return crypto.Hash(0) - } -} - -// Algorithms returns all the supported Hash Algorithms -func Algorithms() map[Algorithm]struct{} { - return map[Algorithm]struct{}{ - None: {}, - MD5: {}, - SHA1: {}, - SHA224: {}, - SHA256: {}, - SHA384: {}, - SHA512: {}, - Ed25519: {}, - } -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go deleted file mode 100644 index 6e7b3ecb..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/prf/prf.go +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package prf implements TLS 1.2 Pseudorandom functions -package prf - -import ( //nolint:gci - ellipticStdlib "crypto/elliptic" - "crypto/hmac" - "encoding/binary" - "errors" - "fmt" - "hash" - "math" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/protocol" - "golang.org/x/crypto/curve25519" -) - -const ( - masterSecretLabel = "master secret" - extendedMasterSecretLabel = "extended master secret" - keyExpansionLabel = "key expansion" - verifyDataClientLabel = "client finished" - verifyDataServerLabel = "server finished" -) - -// HashFunc allows callers to decide what hash is used in PRF -type HashFunc func() hash.Hash - -// EncryptionKeys is all the state needed for a TLS CipherSuite -type EncryptionKeys struct { - MasterSecret []byte - ClientMACKey []byte - ServerMACKey []byte - ClientWriteKey []byte - ServerWriteKey []byte - ClientWriteIV []byte - ServerWriteIV []byte -} - -var errInvalidNamedCurve = &protocol.FatalError{Err: errors.New("invalid named curve")} //nolint:goerr113 - -func (e *EncryptionKeys) String() string { - return fmt.Sprintf(`encryptionKeys: -- masterSecret: %#v -- clientMACKey: %#v -- serverMACKey: %#v -- clientWriteKey: %#v -- serverWriteKey: %#v -- clientWriteIV: %#v -- serverWriteIV: %#v -`, - e.MasterSecret, - e.ClientMACKey, - e.ServerMACKey, - e.ClientWriteKey, - e.ServerWriteKey, - e.ClientWriteIV, - e.ServerWriteIV) -} - -// PSKPreMasterSecret generates the PSK Premaster Secret -// The premaster secret is formed as follows: if the PSK is N octets -// long, concatenate a uint16 with the value N, N zero octets, a second -// uint16 with the value N, and the PSK itself. -// -// https://tools.ietf.org/html/rfc4279#section-2 -func PSKPreMasterSecret(psk []byte) []byte { - pskLen := uint16(len(psk)) - - out := append(make([]byte, 2+pskLen+2), psk...) - binary.BigEndian.PutUint16(out, pskLen) - binary.BigEndian.PutUint16(out[2+pskLen:], pskLen) - - return out -} - -// EcdhePSKPreMasterSecret implements TLS 1.2 Premaster Secret generation given a psk, a keypair and a curve -// -// https://datatracker.ietf.org/doc/html/rfc5489#section-2 -func EcdhePSKPreMasterSecret(psk, publicKey, privateKey []byte, curve elliptic.Curve) ([]byte, error) { - preMasterSecret, err := PreMasterSecret(publicKey, privateKey, curve) - if err != nil { - return nil, err - } - out := make([]byte, 2+len(preMasterSecret)+2+len(psk)) - - // write preMasterSecret length - offset := 0 - binary.BigEndian.PutUint16(out[offset:], uint16(len(preMasterSecret))) - offset += 2 - - // write preMasterSecret - copy(out[offset:], preMasterSecret) - offset += len(preMasterSecret) - - // write psk length - binary.BigEndian.PutUint16(out[offset:], uint16(len(psk))) - offset += 2 - - // write psk - copy(out[offset:], psk) - return out, nil -} - -// PreMasterSecret implements TLS 1.2 Premaster Secret generation given a keypair and a curve -func PreMasterSecret(publicKey, privateKey []byte, curve elliptic.Curve) ([]byte, error) { - switch curve { - case elliptic.X25519: - return curve25519.X25519(privateKey, publicKey) - case elliptic.P256: - return ellipticCurvePreMasterSecret(publicKey, privateKey, ellipticStdlib.P256(), ellipticStdlib.P256()) - case elliptic.P384: - return ellipticCurvePreMasterSecret(publicKey, privateKey, ellipticStdlib.P384(), ellipticStdlib.P384()) - default: - return nil, errInvalidNamedCurve - } -} - -func ellipticCurvePreMasterSecret(publicKey, privateKey []byte, c1, c2 ellipticStdlib.Curve) ([]byte, error) { - x, y := ellipticStdlib.Unmarshal(c1, publicKey) - if x == nil || y == nil { - return nil, errInvalidNamedCurve - } - - result, _ := c2.ScalarMult(x, y, privateKey) - preMasterSecret := make([]byte, (c2.Params().BitSize+7)>>3) - resultBytes := result.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(resultBytes):], resultBytes) - return preMasterSecret, nil -} - -// PHash is PRF is the SHA-256 hash function is used for all cipher suites -// defined in this TLS 1.2 document and in TLS documents published prior to this -// document when TLS 1.2 is negotiated. New cipher suites MUST explicitly -// specify a PRF and, in general, SHOULD use the TLS PRF with SHA-256 or a -// stronger standard hash function. -// -// P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + -// HMAC_hash(secret, A(2) + seed) + -// HMAC_hash(secret, A(3) + seed) + ... -// -// A() is defined as: -// -// A(0) = seed -// A(i) = HMAC_hash(secret, A(i-1)) -// -// P_hash can be iterated as many times as necessary to produce the -// required quantity of data. For example, if P_SHA256 is being used to -// create 80 bytes of data, it will have to be iterated three times -// (through A(3)), creating 96 bytes of output data; the last 16 bytes -// of the final iteration will then be discarded, leaving 80 bytes of -// output data. -// -// https://tools.ietf.org/html/rfc4346w -func PHash(secret, seed []byte, requestedLength int, h HashFunc) ([]byte, error) { - hmacSHA256 := func(key, data []byte) ([]byte, error) { - mac := hmac.New(h, key) - if _, err := mac.Write(data); err != nil { - return nil, err - } - return mac.Sum(nil), nil - } - - var err error - lastRound := seed - out := []byte{} - - iterations := int(math.Ceil(float64(requestedLength) / float64(h().Size()))) - for i := 0; i < iterations; i++ { - lastRound, err = hmacSHA256(secret, lastRound) - if err != nil { - return nil, err - } - withSecret, err := hmacSHA256(secret, append(lastRound, seed...)) - if err != nil { - return nil, err - } - out = append(out, withSecret...) - } - - return out[:requestedLength], nil -} - -// ExtendedMasterSecret generates a Extended MasterSecret as defined in -// https://tools.ietf.org/html/rfc7627 -func ExtendedMasterSecret(preMasterSecret, sessionHash []byte, h HashFunc) ([]byte, error) { - seed := append([]byte(extendedMasterSecretLabel), sessionHash...) - return PHash(preMasterSecret, seed, 48, h) -} - -// MasterSecret generates a TLS 1.2 MasterSecret -func MasterSecret(preMasterSecret, clientRandom, serverRandom []byte, h HashFunc) ([]byte, error) { - seed := append(append([]byte(masterSecretLabel), clientRandom...), serverRandom...) - return PHash(preMasterSecret, seed, 48, h) -} - -// GenerateEncryptionKeys is the final step TLS 1.2 PRF. Given all state generated so far generates -// the final keys need for encryption -func GenerateEncryptionKeys(masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int, h HashFunc) (*EncryptionKeys, error) { - seed := append(append([]byte(keyExpansionLabel), serverRandom...), clientRandom...) - keyMaterial, err := PHash(masterSecret, seed, (2*macLen)+(2*keyLen)+(2*ivLen), h) - if err != nil { - return nil, err - } - - clientMACKey := keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - - serverMACKey := keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - - clientWriteKey := keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - - serverWriteKey := keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - - clientWriteIV := keyMaterial[:ivLen] - keyMaterial = keyMaterial[ivLen:] - - serverWriteIV := keyMaterial[:ivLen] - - return &EncryptionKeys{ - MasterSecret: masterSecret, - ClientMACKey: clientMACKey, - ServerMACKey: serverMACKey, - ClientWriteKey: clientWriteKey, - ServerWriteKey: serverWriteKey, - ClientWriteIV: clientWriteIV, - ServerWriteIV: serverWriteIV, - }, nil -} - -func prfVerifyData(masterSecret, handshakeBodies []byte, label string, hashFunc HashFunc) ([]byte, error) { - h := hashFunc() - if _, err := h.Write(handshakeBodies); err != nil { - return nil, err - } - - seed := append([]byte(label), h.Sum(nil)...) - return PHash(masterSecret, seed, 12, hashFunc) -} - -// VerifyDataClient is caled on the Client Side to either verify or generate the VerifyData message -func VerifyDataClient(masterSecret, handshakeBodies []byte, h HashFunc) ([]byte, error) { - return prfVerifyData(masterSecret, handshakeBodies, verifyDataClientLabel, h) -} - -// VerifyDataServer is caled on the Server Side to either verify or generate the VerifyData message -func VerifyDataServer(masterSecret, handshakeBodies []byte, h HashFunc) ([]byte, error) { - return prfVerifyData(masterSecret, handshakeBodies, verifyDataServerLabel, h) -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go deleted file mode 100644 index fec7fba3..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/signature/signature.go +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package signature provides our implemented Signature Algorithms -package signature - -// Algorithm as defined in TLS 1.2 -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-16 -type Algorithm uint16 - -// SignatureAlgorithm enums -const ( - Anonymous Algorithm = 0 - RSA Algorithm = 1 - ECDSA Algorithm = 3 - Ed25519 Algorithm = 7 -) - -// Algorithms returns all implemented Signature Algorithms -func Algorithms() map[Algorithm]struct{} { - return map[Algorithm]struct{}{ - Anonymous: {}, - RSA: {}, - ECDSA: {}, - Ed25519: {}, - } -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go deleted file mode 100644 index 4aeb3e40..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/errors.go +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package signaturehash - -import "errors" - -var ( - errNoAvailableSignatureSchemes = errors.New("connection can not be created, no SignatureScheme satisfy this Config") - errInvalidSignatureAlgorithm = errors.New("invalid signature algorithm") - errInvalidHashAlgorithm = errors.New("invalid hash algorithm") -) diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go deleted file mode 100644 index 2561accd..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package signaturehash provides the SignatureHashAlgorithm as defined in TLS 1.2 -package signaturehash - -import ( - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/tls" - "fmt" - - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" -) - -// Algorithm is a signature/hash algorithm pairs which may be used in -// digital signatures. -// -// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 -type Algorithm struct { - Hash hash.Algorithm - Signature signature.Algorithm -} - -// Algorithms are all the know SignatureHash Algorithms -func Algorithms() []Algorithm { - return []Algorithm{ - {hash.SHA256, signature.ECDSA}, - {hash.SHA384, signature.ECDSA}, - {hash.SHA512, signature.ECDSA}, - {hash.SHA256, signature.RSA}, - {hash.SHA384, signature.RSA}, - {hash.SHA512, signature.RSA}, - {hash.Ed25519, signature.Ed25519}, - } -} - -// SelectSignatureScheme returns most preferred and compatible scheme. -func SelectSignatureScheme(sigs []Algorithm, privateKey crypto.PrivateKey) (Algorithm, error) { - for _, ss := range sigs { - if ss.isCompatible(privateKey) { - return ss, nil - } - } - return Algorithm{}, errNoAvailableSignatureSchemes -} - -// isCompatible checks that given private key is compatible with the signature scheme. -func (a *Algorithm) isCompatible(privateKey crypto.PrivateKey) bool { - switch privateKey.(type) { - case ed25519.PrivateKey: - return a.Signature == signature.Ed25519 - case *ecdsa.PrivateKey: - return a.Signature == signature.ECDSA - case *rsa.PrivateKey: - return a.Signature == signature.RSA - default: - return false - } -} - -// ParseSignatureSchemes translates []tls.SignatureScheme to []signatureHashAlgorithm. -// It returns default signature scheme list if no SignatureScheme is passed. -func ParseSignatureSchemes(sigs []tls.SignatureScheme, insecureHashes bool) ([]Algorithm, error) { - if len(sigs) == 0 { - return Algorithms(), nil - } - out := []Algorithm{} - for _, ss := range sigs { - sig := signature.Algorithm(ss & 0xFF) - if _, ok := signature.Algorithms()[sig]; !ok { - return nil, - fmt.Errorf("SignatureScheme %04x: %w", ss, errInvalidSignatureAlgorithm) - } - h := hash.Algorithm(ss >> 8) - if _, ok := hash.Algorithms()[h]; !ok || (ok && h == hash.None) { - return nil, fmt.Errorf("SignatureScheme %04x: %w", ss, errInvalidHashAlgorithm) - } - if h.Insecure() && !insecureHashes { - continue - } - out = append(out, Algorithm{ - Hash: h, - Signature: sig, - }) - } - - if len(out) == 0 { - return nil, errNoAvailableSignatureSchemes - } - - return out, nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go deleted file mode 100644 index 91e9f4d6..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/alert/alert.go +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package alert implements TLS alert protocol https://tools.ietf.org/html/rfc5246#section-7.2 -package alert - -import ( - "errors" - "fmt" - - "github.com/pion/dtls/v2/pkg/protocol" -) - -var errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 - -// Level is the level of the TLS Alert -type Level byte - -// Level enums -const ( - Warning Level = 1 - Fatal Level = 2 -) - -func (l Level) String() string { - switch l { - case Warning: - return "Warning" - case Fatal: - return "Fatal" - default: - return "Invalid alert level" - } -} - -// Description is the extended info of the TLS Alert -type Description byte - -// Description enums -const ( - CloseNotify Description = 0 - UnexpectedMessage Description = 10 - BadRecordMac Description = 20 - DecryptionFailed Description = 21 - RecordOverflow Description = 22 - DecompressionFailure Description = 30 - HandshakeFailure Description = 40 - NoCertificate Description = 41 - BadCertificate Description = 42 - UnsupportedCertificate Description = 43 - CertificateRevoked Description = 44 - CertificateExpired Description = 45 - CertificateUnknown Description = 46 - IllegalParameter Description = 47 - UnknownCA Description = 48 - AccessDenied Description = 49 - DecodeError Description = 50 - DecryptError Description = 51 - ExportRestriction Description = 60 - ProtocolVersion Description = 70 - InsufficientSecurity Description = 71 - InternalError Description = 80 - UserCanceled Description = 90 - NoRenegotiation Description = 100 - UnsupportedExtension Description = 110 - NoApplicationProtocol Description = 120 -) - -func (d Description) String() string { - switch d { - case CloseNotify: - return "CloseNotify" - case UnexpectedMessage: - return "UnexpectedMessage" - case BadRecordMac: - return "BadRecordMac" - case DecryptionFailed: - return "DecryptionFailed" - case RecordOverflow: - return "RecordOverflow" - case DecompressionFailure: - return "DecompressionFailure" - case HandshakeFailure: - return "HandshakeFailure" - case NoCertificate: - return "NoCertificate" - case BadCertificate: - return "BadCertificate" - case UnsupportedCertificate: - return "UnsupportedCertificate" - case CertificateRevoked: - return "CertificateRevoked" - case CertificateExpired: - return "CertificateExpired" - case CertificateUnknown: - return "CertificateUnknown" - case IllegalParameter: - return "IllegalParameter" - case UnknownCA: - return "UnknownCA" - case AccessDenied: - return "AccessDenied" - case DecodeError: - return "DecodeError" - case DecryptError: - return "DecryptError" - case ExportRestriction: - return "ExportRestriction" - case ProtocolVersion: - return "ProtocolVersion" - case InsufficientSecurity: - return "InsufficientSecurity" - case InternalError: - return "InternalError" - case UserCanceled: - return "UserCanceled" - case NoRenegotiation: - return "NoRenegotiation" - case UnsupportedExtension: - return "UnsupportedExtension" - case NoApplicationProtocol: - return "NoApplicationProtocol" - default: - return "Invalid alert description" - } -} - -// Alert is one of the content types supported by the TLS record layer. -// Alert messages convey the severity of the message -// (warning or fatal) and a description of the alert. Alert messages -// with a level of fatal result in the immediate termination of the -// connection. In this case, other connections corresponding to the -// session may continue, but the session identifier MUST be invalidated, -// preventing the failed session from being used to establish new -// connections. Like other messages, alert messages are encrypted and -// compressed, as specified by the current connection state. -// https://tools.ietf.org/html/rfc5246#section-7.2 -type Alert struct { - Level Level - Description Description -} - -// ContentType returns the ContentType of this Content -func (a Alert) ContentType() protocol.ContentType { - return protocol.ContentTypeAlert -} - -// Marshal returns the encoded alert -func (a *Alert) Marshal() ([]byte, error) { - return []byte{byte(a.Level), byte(a.Description)}, nil -} - -// Unmarshal populates the alert from binary data -func (a *Alert) Unmarshal(data []byte) error { - if len(data) != 2 { - return errBufferTooSmall - } - - a.Level = Level(data[0]) - a.Description = Description(data[1]) - return nil -} - -func (a *Alert) String() string { - return fmt.Sprintf("Alert %s: %s", a.Level, a.Description) -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go deleted file mode 100644 index f4221151..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/application_data.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package protocol - -// ApplicationData messages are carried by the record layer and are -// fragmented, compressed, and encrypted based on the current connection -// state. The messages are treated as transparent data to the record -// layer. -// https://tools.ietf.org/html/rfc5246#section-10 -type ApplicationData struct { - Data []byte -} - -// ContentType returns the ContentType of this content -func (a ApplicationData) ContentType() ContentType { - return ContentTypeApplicationData -} - -// Marshal encodes the ApplicationData to binary -func (a *ApplicationData) Marshal() ([]byte, error) { - return append([]byte{}, a.Data...), nil -} - -// Unmarshal populates the ApplicationData from binary -func (a *ApplicationData) Unmarshal(data []byte) error { - a.Data = append([]byte{}, data...) - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go deleted file mode 100644 index 87f28bc3..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/change_cipher_spec.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package protocol - -// ChangeCipherSpec protocol exists to signal transitions in -// ciphering strategies. The protocol consists of a single message, -// which is encrypted and compressed under the current (not the pending) -// connection state. The message consists of a single byte of value 1. -// https://tools.ietf.org/html/rfc5246#section-7.1 -type ChangeCipherSpec struct{} - -// ContentType returns the ContentType of this content -func (c ChangeCipherSpec) ContentType() ContentType { - return ContentTypeChangeCipherSpec -} - -// Marshal encodes the ChangeCipherSpec to binary -func (c *ChangeCipherSpec) Marshal() ([]byte, error) { - return []byte{0x01}, nil -} - -// Unmarshal populates the ChangeCipherSpec from binary -func (c *ChangeCipherSpec) Unmarshal(data []byte) error { - if len(data) == 1 && data[0] == 0x01 { - return nil - } - - return errInvalidCipherSpec -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go deleted file mode 100644 index 3478ee38..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/compression_method.go +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package protocol - -// CompressionMethodID is the ID for a CompressionMethod -type CompressionMethodID byte - -const ( - compressionMethodNull CompressionMethodID = 0 -) - -// CompressionMethod represents a TLS Compression Method -type CompressionMethod struct { - ID CompressionMethodID -} - -// CompressionMethods returns all supported CompressionMethods -func CompressionMethods() map[CompressionMethodID]*CompressionMethod { - return map[CompressionMethodID]*CompressionMethod{ - compressionMethodNull: {ID: compressionMethodNull}, - } -} - -// DecodeCompressionMethods the given compression methods -func DecodeCompressionMethods(buf []byte) ([]*CompressionMethod, error) { - if len(buf) < 1 { - return nil, errBufferTooSmall - } - compressionMethodsCount := int(buf[0]) - c := []*CompressionMethod{} - for i := 0; i < compressionMethodsCount; i++ { - if len(buf) <= i+1 { - return nil, errBufferTooSmall - } - id := CompressionMethodID(buf[i+1]) - if compressionMethod, ok := CompressionMethods()[id]; ok { - c = append(c, compressionMethod) - } - } - return c, nil -} - -// EncodeCompressionMethods the given compression methods -func EncodeCompressionMethods(c []*CompressionMethod) []byte { - out := []byte{byte(len(c))} - for i := len(c); i > 0; i-- { - out = append(out, byte(c[i-1].ID)) - } - return out -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go deleted file mode 100644 index 92c9db2b..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/content.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package protocol - -// ContentType represents the IANA Registered ContentTypes -// -// https://tools.ietf.org/html/rfc4346#section-6.2.1 -type ContentType uint8 - -// ContentType enums -const ( - ContentTypeChangeCipherSpec ContentType = 20 - ContentTypeAlert ContentType = 21 - ContentTypeHandshake ContentType = 22 - ContentTypeApplicationData ContentType = 23 -) - -// Content is the top level distinguisher for a DTLS Datagram -type Content interface { - ContentType() ContentType - Marshal() ([]byte, error) - Unmarshal(data []byte) error -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go deleted file mode 100644 index d87aff7f..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/errors.go +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package protocol - -import ( - "errors" - "fmt" - "net" -) - -var ( - errBufferTooSmall = &TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 - errInvalidCipherSpec = &FatalError{Err: errors.New("cipher spec invalid")} //nolint:goerr113 -) - -// FatalError indicates that the DTLS connection is no longer available. -// It is mainly caused by wrong configuration of server or client. -type FatalError struct { - Err error -} - -// InternalError indicates and internal error caused by the implementation, and the DTLS connection is no longer available. -// It is mainly caused by bugs or tried to use unimplemented features. -type InternalError struct { - Err error -} - -// TemporaryError indicates that the DTLS connection is still available, but the request was failed temporary. -type TemporaryError struct { - Err error -} - -// TimeoutError indicates that the request was timed out. -type TimeoutError struct { - Err error -} - -// HandshakeError indicates that the handshake failed. -type HandshakeError struct { - Err error -} - -// Timeout implements net.Error.Timeout() -func (*FatalError) Timeout() bool { return false } - -// Temporary implements net.Error.Temporary() -func (*FatalError) Temporary() bool { return false } - -// Unwrap implements Go1.13 error unwrapper. -func (e *FatalError) Unwrap() error { return e.Err } - -func (e *FatalError) Error() string { return fmt.Sprintf("dtls fatal: %v", e.Err) } - -// Timeout implements net.Error.Timeout() -func (*InternalError) Timeout() bool { return false } - -// Temporary implements net.Error.Temporary() -func (*InternalError) Temporary() bool { return false } - -// Unwrap implements Go1.13 error unwrapper. -func (e *InternalError) Unwrap() error { return e.Err } - -func (e *InternalError) Error() string { return fmt.Sprintf("dtls internal: %v", e.Err) } - -// Timeout implements net.Error.Timeout() -func (*TemporaryError) Timeout() bool { return false } - -// Temporary implements net.Error.Temporary() -func (*TemporaryError) Temporary() bool { return true } - -// Unwrap implements Go1.13 error unwrapper. -func (e *TemporaryError) Unwrap() error { return e.Err } - -func (e *TemporaryError) Error() string { return fmt.Sprintf("dtls temporary: %v", e.Err) } - -// Timeout implements net.Error.Timeout() -func (*TimeoutError) Timeout() bool { return true } - -// Temporary implements net.Error.Temporary() -func (*TimeoutError) Temporary() bool { return true } - -// Unwrap implements Go1.13 error unwrapper. -func (e *TimeoutError) Unwrap() error { return e.Err } - -func (e *TimeoutError) Error() string { return fmt.Sprintf("dtls timeout: %v", e.Err) } - -// Timeout implements net.Error.Timeout() -func (e *HandshakeError) Timeout() bool { - var netErr net.Error - if errors.As(e.Err, &netErr) { - return netErr.Timeout() - } - return false -} - -// Temporary implements net.Error.Temporary() -func (e *HandshakeError) Temporary() bool { - var netErr net.Error - if errors.As(e.Err, &netErr) { - return netErr.Temporary() //nolint - } - return false -} - -// Unwrap implements Go1.13 error unwrapper. -func (e *HandshakeError) Unwrap() error { return e.Err } - -func (e *HandshakeError) Error() string { return fmt.Sprintf("handshake error: %v", e.Err) } diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go deleted file mode 100644 index e780dc9e..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/alpn.go +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import ( - "golang.org/x/crypto/cryptobyte" -) - -// ALPN is a TLS extension for application-layer protocol negotiation within -// the TLS handshake. -// -// https://tools.ietf.org/html/rfc7301 -type ALPN struct { - ProtocolNameList []string -} - -// TypeValue returns the extension TypeValue -func (a ALPN) TypeValue() TypeValue { - return ALPNTypeValue -} - -// Marshal encodes the extension -func (a *ALPN) Marshal() ([]byte, error) { - var b cryptobyte.Builder - b.AddUint16(uint16(a.TypeValue())) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, proto := range a.ProtocolNameList { - p := proto // Satisfy range scope lint - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(p)) - }) - } - }) - }) - return b.Bytes() -} - -// Unmarshal populates the extension from encoded data -func (a *ALPN) Unmarshal(data []byte) error { - val := cryptobyte.String(data) - - var extension uint16 - val.ReadUint16(&extension) - if TypeValue(extension) != a.TypeValue() { - return errInvalidExtensionType - } - - var extData cryptobyte.String - val.ReadUint16LengthPrefixed(&extData) - - var protoList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { - return ErrALPNInvalidFormat - } - for !protoList.Empty() { - var proto cryptobyte.String - if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() { - return ErrALPNInvalidFormat - } - a.ProtocolNameList = append(a.ProtocolNameList, string(proto)) - } - return nil -} - -// ALPNProtocolSelection negotiates a shared protocol according to #3.2 of rfc7301 -func ALPNProtocolSelection(supportedProtocols, peerSupportedProtocols []string) (string, error) { - if len(supportedProtocols) == 0 || len(peerSupportedProtocols) == 0 { - return "", nil - } - for _, s := range supportedProtocols { - for _, c := range peerSupportedProtocols { - if s == c { - return s, nil - } - } - } - return "", errALPNNoAppProto -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go deleted file mode 100644 index c5e954ce..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/errors.go +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import ( - "errors" - - "github.com/pion/dtls/v2/pkg/protocol" -) - -var ( - // ErrALPNInvalidFormat is raised when the ALPN format is invalid - ErrALPNInvalidFormat = &protocol.FatalError{Err: errors.New("invalid alpn format")} //nolint:goerr113 - errALPNNoAppProto = &protocol.FatalError{Err: errors.New("no application protocol")} //nolint:goerr113 - errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 - errInvalidExtensionType = &protocol.FatalError{Err: errors.New("invalid extension type")} //nolint:goerr113 - errInvalidSNIFormat = &protocol.FatalError{Err: errors.New("invalid server name format")} //nolint:goerr113 - errLengthMismatch = &protocol.InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113 -) diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go deleted file mode 100644 index 5173a586..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/extension.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package extension implements the extension values in the ClientHello/ServerHello -package extension - -import "encoding/binary" - -// TypeValue is the 2 byte value for a TLS Extension as registered in the IANA -// -// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml -type TypeValue uint16 - -// TypeValue constants -const ( - ServerNameTypeValue TypeValue = 0 - SupportedEllipticCurvesTypeValue TypeValue = 10 - SupportedPointFormatsTypeValue TypeValue = 11 - SupportedSignatureAlgorithmsTypeValue TypeValue = 13 - UseSRTPTypeValue TypeValue = 14 - ALPNTypeValue TypeValue = 16 - UseExtendedMasterSecretTypeValue TypeValue = 23 - RenegotiationInfoTypeValue TypeValue = 65281 -) - -// Extension represents a single TLS extension -type Extension interface { - Marshal() ([]byte, error) - Unmarshal(data []byte) error - TypeValue() TypeValue -} - -// Unmarshal many extensions at once -func Unmarshal(buf []byte) ([]Extension, error) { - switch { - case len(buf) == 0: - return []Extension{}, nil - case len(buf) < 2: - return nil, errBufferTooSmall - } - - declaredLen := binary.BigEndian.Uint16(buf) - if len(buf)-2 != int(declaredLen) { - return nil, errLengthMismatch - } - - extensions := []Extension{} - unmarshalAndAppend := func(data []byte, e Extension) error { - err := e.Unmarshal(data) - if err != nil { - return err - } - extensions = append(extensions, e) - return nil - } - - for offset := 2; offset < len(buf); { - if len(buf) < (offset + 2) { - return nil, errBufferTooSmall - } - var err error - switch TypeValue(binary.BigEndian.Uint16(buf[offset:])) { - case ServerNameTypeValue: - err = unmarshalAndAppend(buf[offset:], &ServerName{}) - case SupportedEllipticCurvesTypeValue: - err = unmarshalAndAppend(buf[offset:], &SupportedEllipticCurves{}) - case UseSRTPTypeValue: - err = unmarshalAndAppend(buf[offset:], &UseSRTP{}) - case ALPNTypeValue: - err = unmarshalAndAppend(buf[offset:], &ALPN{}) - case UseExtendedMasterSecretTypeValue: - err = unmarshalAndAppend(buf[offset:], &UseExtendedMasterSecret{}) - case RenegotiationInfoTypeValue: - err = unmarshalAndAppend(buf[offset:], &RenegotiationInfo{}) - default: - } - if err != nil { - return nil, err - } - if len(buf) < (offset + 4) { - return nil, errBufferTooSmall - } - extensionLength := binary.BigEndian.Uint16(buf[offset+2:]) - offset += (4 + int(extensionLength)) - } - return extensions, nil -} - -// Marshal many extensions at once -func Marshal(e []Extension) ([]byte, error) { - extensions := []byte{} - for _, e := range e { - raw, err := e.Marshal() - if err != nil { - return nil, err - } - extensions = append(extensions, raw...) - } - out := []byte{0x00, 0x00} - binary.BigEndian.PutUint16(out, uint16(len(extensions))) - return append(out, extensions...), nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go deleted file mode 100644 index c5092a7d..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/renegotiation_info.go +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import "encoding/binary" - -const ( - renegotiationInfoHeaderSize = 5 -) - -// RenegotiationInfo allows a Client/Server to -// communicate their renegotation support -// -// https://tools.ietf.org/html/rfc5746 -type RenegotiationInfo struct { - RenegotiatedConnection uint8 -} - -// TypeValue returns the extension TypeValue -func (r RenegotiationInfo) TypeValue() TypeValue { - return RenegotiationInfoTypeValue -} - -// Marshal encodes the extension -func (r *RenegotiationInfo) Marshal() ([]byte, error) { - out := make([]byte, renegotiationInfoHeaderSize) - - binary.BigEndian.PutUint16(out, uint16(r.TypeValue())) - binary.BigEndian.PutUint16(out[2:], uint16(1)) // length - out[4] = r.RenegotiatedConnection - return out, nil -} - -// Unmarshal populates the extension from encoded data -func (r *RenegotiationInfo) Unmarshal(data []byte) error { - if len(data) < renegotiationInfoHeaderSize { - return errBufferTooSmall - } else if TypeValue(binary.BigEndian.Uint16(data)) != r.TypeValue() { - return errInvalidExtensionType - } - - r.RenegotiatedConnection = data[4] - - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go deleted file mode 100644 index 183e08e6..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import ( - "strings" - - "golang.org/x/crypto/cryptobyte" -) - -const serverNameTypeDNSHostName = 0 - -// ServerName allows the client to inform the server the specific -// name it wishes to contact. Useful if multiple DNS names resolve -// to one IP -// -// https://tools.ietf.org/html/rfc6066#section-3 -type ServerName struct { - ServerName string -} - -// TypeValue returns the extension TypeValue -func (s ServerName) TypeValue() TypeValue { - return ServerNameTypeValue -} - -// Marshal encodes the extension -func (s *ServerName) Marshal() ([]byte, error) { - var b cryptobyte.Builder - b.AddUint16(uint16(s.TypeValue())) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(serverNameTypeDNSHostName) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(s.ServerName)) - }) - }) - }) - return b.Bytes() -} - -// Unmarshal populates the extension from encoded data -func (s *ServerName) Unmarshal(data []byte) error { - val := cryptobyte.String(data) - var extension uint16 - val.ReadUint16(&extension) - if TypeValue(extension) != s.TypeValue() { - return errInvalidExtensionType - } - - var extData cryptobyte.String - val.ReadUint16LengthPrefixed(&extData) - - var nameList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() { - return errInvalidSNIFormat - } - for !nameList.Empty() { - var nameType uint8 - var serverName cryptobyte.String - if !nameList.ReadUint8(&nameType) || - !nameList.ReadUint16LengthPrefixed(&serverName) || - serverName.Empty() { - return errInvalidSNIFormat - } - if nameType != serverNameTypeDNSHostName { - continue - } - if len(s.ServerName) != 0 { - // Multiple names of the same name_type are prohibited. - return errInvalidSNIFormat - } - s.ServerName = string(serverName) - // An SNI value may not include a trailing dot. - if strings.HasSuffix(s.ServerName, ".") { - return errInvalidSNIFormat - } - } - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go deleted file mode 100644 index 2966966d..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/srtp_protection_profile.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -// SRTPProtectionProfile defines the parameters and options that are in effect for the SRTP processing -// https://tools.ietf.org/html/rfc5764#section-4.1.2 -type SRTPProtectionProfile uint16 - -const ( - SRTP_AES128_CM_HMAC_SHA1_80 SRTPProtectionProfile = 0x0001 // nolint - SRTP_AES128_CM_HMAC_SHA1_32 SRTPProtectionProfile = 0x0002 // nolint - SRTP_AEAD_AES_128_GCM SRTPProtectionProfile = 0x0007 // nolint - SRTP_AEAD_AES_256_GCM SRTPProtectionProfile = 0x0008 // nolint -) - -func srtpProtectionProfiles() map[SRTPProtectionProfile]bool { - return map[SRTPProtectionProfile]bool{ - SRTP_AES128_CM_HMAC_SHA1_80: true, - SRTP_AES128_CM_HMAC_SHA1_32: true, - SRTP_AEAD_AES_128_GCM: true, - SRTP_AEAD_AES_256_GCM: true, - } -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go deleted file mode 100644 index dd9b54f0..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_elliptic_curves.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" -) - -const ( - supportedGroupsHeaderSize = 6 -) - -// SupportedEllipticCurves allows a Client/Server to communicate -// what curves they both support -// -// https://tools.ietf.org/html/rfc8422#section-5.1.1 -type SupportedEllipticCurves struct { - EllipticCurves []elliptic.Curve -} - -// TypeValue returns the extension TypeValue -func (s SupportedEllipticCurves) TypeValue() TypeValue { - return SupportedEllipticCurvesTypeValue -} - -// Marshal encodes the extension -func (s *SupportedEllipticCurves) Marshal() ([]byte, error) { - out := make([]byte, supportedGroupsHeaderSize) - - binary.BigEndian.PutUint16(out, uint16(s.TypeValue())) - binary.BigEndian.PutUint16(out[2:], uint16(2+(len(s.EllipticCurves)*2))) - binary.BigEndian.PutUint16(out[4:], uint16(len(s.EllipticCurves)*2)) - - for _, v := range s.EllipticCurves { - out = append(out, []byte{0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v)) - } - - return out, nil -} - -// Unmarshal populates the extension from encoded data -func (s *SupportedEllipticCurves) Unmarshal(data []byte) error { - if len(data) <= supportedGroupsHeaderSize { - return errBufferTooSmall - } else if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() { - return errInvalidExtensionType - } - - groupCount := int(binary.BigEndian.Uint16(data[4:]) / 2) - if supportedGroupsHeaderSize+(groupCount*2) > len(data) { - return errLengthMismatch - } - - for i := 0; i < groupCount; i++ { - supportedGroupID := elliptic.Curve(binary.BigEndian.Uint16(data[(supportedGroupsHeaderSize + (i * 2)):])) - if _, ok := elliptic.Curves()[supportedGroupID]; ok { - s.EllipticCurves = append(s.EllipticCurves, supportedGroupID) - } - } - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go deleted file mode 100644 index 9c2543e6..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_point_formats.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" -) - -const ( - supportedPointFormatsSize = 5 -) - -// SupportedPointFormats allows a Client/Server to negotiate -// the EllipticCurvePointFormats -// -// https://tools.ietf.org/html/rfc4492#section-5.1.2 -type SupportedPointFormats struct { - PointFormats []elliptic.CurvePointFormat -} - -// TypeValue returns the extension TypeValue -func (s SupportedPointFormats) TypeValue() TypeValue { - return SupportedPointFormatsTypeValue -} - -// Marshal encodes the extension -func (s *SupportedPointFormats) Marshal() ([]byte, error) { - out := make([]byte, supportedPointFormatsSize) - - binary.BigEndian.PutUint16(out, uint16(s.TypeValue())) - binary.BigEndian.PutUint16(out[2:], uint16(1+(len(s.PointFormats)))) - out[4] = byte(len(s.PointFormats)) - - for _, v := range s.PointFormats { - out = append(out, byte(v)) - } - return out, nil -} - -// Unmarshal populates the extension from encoded data -func (s *SupportedPointFormats) Unmarshal(data []byte) error { - if len(data) <= supportedPointFormatsSize { - return errBufferTooSmall - } else if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() { - return errInvalidExtensionType - } - - pointFormatCount := int(binary.BigEndian.Uint16(data[4:])) - if supportedGroupsHeaderSize+(pointFormatCount) > len(data) { - return errLengthMismatch - } - - for i := 0; i < pointFormatCount; i++ { - p := elliptic.CurvePointFormat(data[supportedPointFormatsSize+i]) - switch p { - case elliptic.CurvePointFormatUncompressed: - s.PointFormats = append(s.PointFormats, p) - default: - } - } - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go deleted file mode 100644 index 2ff4b90b..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/supported_signature_algorithms.go +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" -) - -const ( - supportedSignatureAlgorithmsHeaderSize = 6 -) - -// SupportedSignatureAlgorithms allows a Client/Server to -// negotiate what SignatureHash Algorithms they both support -// -// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 -type SupportedSignatureAlgorithms struct { - SignatureHashAlgorithms []signaturehash.Algorithm -} - -// TypeValue returns the extension TypeValue -func (s SupportedSignatureAlgorithms) TypeValue() TypeValue { - return SupportedSignatureAlgorithmsTypeValue -} - -// Marshal encodes the extension -func (s *SupportedSignatureAlgorithms) Marshal() ([]byte, error) { - out := make([]byte, supportedSignatureAlgorithmsHeaderSize) - - binary.BigEndian.PutUint16(out, uint16(s.TypeValue())) - binary.BigEndian.PutUint16(out[2:], uint16(2+(len(s.SignatureHashAlgorithms)*2))) - binary.BigEndian.PutUint16(out[4:], uint16(len(s.SignatureHashAlgorithms)*2)) - for _, v := range s.SignatureHashAlgorithms { - out = append(out, []byte{0x00, 0x00}...) - out[len(out)-2] = byte(v.Hash) - out[len(out)-1] = byte(v.Signature) - } - - return out, nil -} - -// Unmarshal populates the extension from encoded data -func (s *SupportedSignatureAlgorithms) Unmarshal(data []byte) error { - if len(data) <= supportedSignatureAlgorithmsHeaderSize { - return errBufferTooSmall - } else if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() { - return errInvalidExtensionType - } - - algorithmCount := int(binary.BigEndian.Uint16(data[4:]) / 2) - if supportedSignatureAlgorithmsHeaderSize+(algorithmCount*2) > len(data) { - return errLengthMismatch - } - for i := 0; i < algorithmCount; i++ { - supportedHashAlgorithm := hash.Algorithm(data[supportedSignatureAlgorithmsHeaderSize+(i*2)]) - supportedSignatureAlgorithm := signature.Algorithm(data[supportedSignatureAlgorithmsHeaderSize+(i*2)+1]) - if _, ok := hash.Algorithms()[supportedHashAlgorithm]; ok { - if _, ok := signature.Algorithms()[supportedSignatureAlgorithm]; ok { - s.SignatureHashAlgorithms = append(s.SignatureHashAlgorithms, signaturehash.Algorithm{ - Hash: supportedHashAlgorithm, - Signature: supportedSignatureAlgorithm, - }) - } - } - } - - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go deleted file mode 100644 index d0b70caf..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_master_secret.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import "encoding/binary" - -const ( - useExtendedMasterSecretHeaderSize = 4 -) - -// UseExtendedMasterSecret defines a TLS extension that contextually binds the -// master secret to a log of the full handshake that computes it, thus -// preventing MITM attacks. -type UseExtendedMasterSecret struct { - Supported bool -} - -// TypeValue returns the extension TypeValue -func (u UseExtendedMasterSecret) TypeValue() TypeValue { - return UseExtendedMasterSecretTypeValue -} - -// Marshal encodes the extension -func (u *UseExtendedMasterSecret) Marshal() ([]byte, error) { - if !u.Supported { - return []byte{}, nil - } - - out := make([]byte, useExtendedMasterSecretHeaderSize) - - binary.BigEndian.PutUint16(out, uint16(u.TypeValue())) - binary.BigEndian.PutUint16(out[2:], uint16(0)) // length - return out, nil -} - -// Unmarshal populates the extension from encoded data -func (u *UseExtendedMasterSecret) Unmarshal(data []byte) error { - if len(data) < useExtendedMasterSecretHeaderSize { - return errBufferTooSmall - } else if TypeValue(binary.BigEndian.Uint16(data)) != u.TypeValue() { - return errInvalidExtensionType - } - - u.Supported = true - - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go deleted file mode 100644 index ea9f1087..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/use_srtp.go +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package extension - -import "encoding/binary" - -const ( - useSRTPHeaderSize = 6 -) - -// UseSRTP allows a Client/Server to negotiate what SRTPProtectionProfiles -// they both support -// -// https://tools.ietf.org/html/rfc8422 -type UseSRTP struct { - ProtectionProfiles []SRTPProtectionProfile -} - -// TypeValue returns the extension TypeValue -func (u UseSRTP) TypeValue() TypeValue { - return UseSRTPTypeValue -} - -// Marshal encodes the extension -func (u *UseSRTP) Marshal() ([]byte, error) { - out := make([]byte, useSRTPHeaderSize) - - binary.BigEndian.PutUint16(out, uint16(u.TypeValue())) - binary.BigEndian.PutUint16(out[2:], uint16(2+(len(u.ProtectionProfiles)*2)+ /* MKI Length */ 1)) - binary.BigEndian.PutUint16(out[4:], uint16(len(u.ProtectionProfiles)*2)) - - for _, v := range u.ProtectionProfiles { - out = append(out, []byte{0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v)) - } - - out = append(out, 0x00) /* MKI Length */ - return out, nil -} - -// Unmarshal populates the extension from encoded data -func (u *UseSRTP) Unmarshal(data []byte) error { - if len(data) <= useSRTPHeaderSize { - return errBufferTooSmall - } else if TypeValue(binary.BigEndian.Uint16(data)) != u.TypeValue() { - return errInvalidExtensionType - } - - profileCount := int(binary.BigEndian.Uint16(data[4:]) / 2) - if supportedGroupsHeaderSize+(profileCount*2) > len(data) { - return errLengthMismatch - } - - for i := 0; i < profileCount; i++ { - supportedProfile := SRTPProtectionProfile(binary.BigEndian.Uint16(data[(useSRTPHeaderSize + (i * 2)):])) - if _, ok := srtpProtectionProfiles()[supportedProfile]; ok { - u.ProtectionProfiles = append(u.ProtectionProfiles, supportedProfile) - } - } - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go deleted file mode 100644 index b2962971..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/cipher_suite.go +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import "encoding/binary" - -func decodeCipherSuiteIDs(buf []byte) ([]uint16, error) { - if len(buf) < 2 { - return nil, errBufferTooSmall - } - cipherSuitesCount := int(binary.BigEndian.Uint16(buf[0:])) / 2 - rtrn := make([]uint16, cipherSuitesCount) - for i := 0; i < cipherSuitesCount; i++ { - if len(buf) < (i*2 + 4) { - return nil, errBufferTooSmall - } - - rtrn[i] = binary.BigEndian.Uint16(buf[(i*2)+2:]) - } - return rtrn, nil -} - -func encodeCipherSuiteIDs(cipherSuiteIDs []uint16) []byte { - out := []byte{0x00, 0x00} - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(cipherSuiteIDs)*2)) - for _, id := range cipherSuiteIDs { - out = append(out, []byte{0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], id) - } - return out -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go deleted file mode 100644 index 1354300c..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/errors.go +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "errors" - - "github.com/pion/dtls/v2/pkg/protocol" -) - -// Typed errors -var ( - errUnableToMarshalFragmented = &protocol.InternalError{Err: errors.New("unable to marshal fragmented handshakes")} //nolint:goerr113 - errHandshakeMessageUnset = &protocol.InternalError{Err: errors.New("handshake message unset, unable to marshal")} //nolint:goerr113 - errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 - errLengthMismatch = &protocol.InternalError{Err: errors.New("data length and declared length do not match")} //nolint:goerr113 - errInvalidClientKeyExchange = &protocol.FatalError{Err: errors.New("unable to determine if ClientKeyExchange is a public key or PSK Identity")} //nolint:goerr113 - errInvalidHashAlgorithm = &protocol.FatalError{Err: errors.New("invalid hash algorithm")} //nolint:goerr113 - errInvalidSignatureAlgorithm = &protocol.FatalError{Err: errors.New("invalid signature algorithm")} //nolint:goerr113 - errCookieTooLong = &protocol.FatalError{Err: errors.New("cookie must not be longer then 255 bytes")} //nolint:goerr113 - errInvalidEllipticCurveType = &protocol.FatalError{Err: errors.New("invalid or unknown elliptic curve type")} //nolint:goerr113 - errInvalidNamedCurve = &protocol.FatalError{Err: errors.New("invalid named curve")} //nolint:goerr113 - errCipherSuiteUnset = &protocol.FatalError{Err: errors.New("server hello can not be created without a cipher suite")} //nolint:goerr113 - errCompressionMethodUnset = &protocol.FatalError{Err: errors.New("server hello can not be created without a compression method")} //nolint:goerr113 - errInvalidCompressionMethod = &protocol.FatalError{Err: errors.New("invalid or unknown compression method")} //nolint:goerr113 - errNotImplemented = &protocol.InternalError{Err: errors.New("feature has not been implemented yet")} //nolint:goerr113 -) diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go deleted file mode 100644 index b1f682bf..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package handshake provides the DTLS wire protocol for handshakes -package handshake - -import ( - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/internal/util" - "github.com/pion/dtls/v2/pkg/protocol" -) - -// Type is the unique identifier for each handshake message -// https://tools.ietf.org/html/rfc5246#section-7.4 -type Type uint8 - -// Types of DTLS Handshake messages we know about -const ( - TypeHelloRequest Type = 0 - TypeClientHello Type = 1 - TypeServerHello Type = 2 - TypeHelloVerifyRequest Type = 3 - TypeCertificate Type = 11 - TypeServerKeyExchange Type = 12 - TypeCertificateRequest Type = 13 - TypeServerHelloDone Type = 14 - TypeCertificateVerify Type = 15 - TypeClientKeyExchange Type = 16 - TypeFinished Type = 20 -) - -// String returns the string representation of this type -func (t Type) String() string { - switch t { - case TypeHelloRequest: - return "HelloRequest" - case TypeClientHello: - return "ClientHello" - case TypeServerHello: - return "ServerHello" - case TypeHelloVerifyRequest: - return "HelloVerifyRequest" - case TypeCertificate: - return "TypeCertificate" - case TypeServerKeyExchange: - return "ServerKeyExchange" - case TypeCertificateRequest: - return "CertificateRequest" - case TypeServerHelloDone: - return "ServerHelloDone" - case TypeCertificateVerify: - return "CertificateVerify" - case TypeClientKeyExchange: - return "ClientKeyExchange" - case TypeFinished: - return "Finished" - } - return "" -} - -// Message is the body of a Handshake datagram -type Message interface { - Marshal() ([]byte, error) - Unmarshal(data []byte) error - Type() Type -} - -// Handshake protocol is responsible for selecting a cipher spec and -// generating a master secret, which together comprise the primary -// cryptographic parameters associated with a secure session. The -// handshake protocol can also optionally authenticate parties who have -// certificates signed by a trusted certificate authority. -// https://tools.ietf.org/html/rfc5246#section-7.3 -type Handshake struct { - Header Header - Message Message - - KeyExchangeAlgorithm types.KeyExchangeAlgorithm -} - -// ContentType returns what kind of content this message is carying -func (h Handshake) ContentType() protocol.ContentType { - return protocol.ContentTypeHandshake -} - -// Marshal encodes a handshake into a binary message -func (h *Handshake) Marshal() ([]byte, error) { - if h.Message == nil { - return nil, errHandshakeMessageUnset - } else if h.Header.FragmentOffset != 0 { - return nil, errUnableToMarshalFragmented - } - - msg, err := h.Message.Marshal() - if err != nil { - return nil, err - } - - h.Header.Length = uint32(len(msg)) - h.Header.FragmentLength = h.Header.Length - h.Header.Type = h.Message.Type() - header, err := h.Header.Marshal() - if err != nil { - return nil, err - } - - return append(header, msg...), nil -} - -// Unmarshal decodes a handshake from a binary message -func (h *Handshake) Unmarshal(data []byte) error { - if err := h.Header.Unmarshal(data); err != nil { - return err - } - - reportedLen := util.BigEndianUint24(data[1:]) - if uint32(len(data)-HeaderLength) != reportedLen { - return errLengthMismatch - } else if reportedLen != h.Header.FragmentLength { - return errLengthMismatch - } - - switch Type(data[0]) { - case TypeHelloRequest: - return errNotImplemented - case TypeClientHello: - h.Message = &MessageClientHello{} - case TypeHelloVerifyRequest: - h.Message = &MessageHelloVerifyRequest{} - case TypeServerHello: - h.Message = &MessageServerHello{} - case TypeCertificate: - h.Message = &MessageCertificate{} - case TypeServerKeyExchange: - h.Message = &MessageServerKeyExchange{KeyExchangeAlgorithm: h.KeyExchangeAlgorithm} - case TypeCertificateRequest: - h.Message = &MessageCertificateRequest{} - case TypeServerHelloDone: - h.Message = &MessageServerHelloDone{} - case TypeClientKeyExchange: - h.Message = &MessageClientKeyExchange{KeyExchangeAlgorithm: h.KeyExchangeAlgorithm} - case TypeFinished: - h.Message = &MessageFinished{} - case TypeCertificateVerify: - h.Message = &MessageCertificateVerify{} - default: - return errNotImplemented - } - return h.Message.Unmarshal(data[HeaderLength:]) -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go deleted file mode 100644 index 4f9a9628..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/header.go +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/internal/util" -) - -// HeaderLength msg_len for Handshake messages assumes an extra -// 12 bytes for sequence, fragment and version information vs TLS -const HeaderLength = 12 - -// Header is the static first 12 bytes of each RecordLayer -// of type Handshake. These fields allow us to support message loss, reordering, and -// message fragmentation, -// -// https://tools.ietf.org/html/rfc6347#section-4.2.2 -type Header struct { - Type Type - Length uint32 // uint24 in spec - MessageSequence uint16 - FragmentOffset uint32 // uint24 in spec - FragmentLength uint32 // uint24 in spec -} - -// Marshal encodes the Header -func (h *Header) Marshal() ([]byte, error) { - out := make([]byte, HeaderLength) - - out[0] = byte(h.Type) - util.PutBigEndianUint24(out[1:], h.Length) - binary.BigEndian.PutUint16(out[4:], h.MessageSequence) - util.PutBigEndianUint24(out[6:], h.FragmentOffset) - util.PutBigEndianUint24(out[9:], h.FragmentLength) - return out, nil -} - -// Unmarshal populates the header from encoded data -func (h *Header) Unmarshal(data []byte) error { - if len(data) < HeaderLength { - return errBufferTooSmall - } - - h.Type = Type(data[0]) - h.Length = util.BigEndianUint24(data[1:]) - h.MessageSequence = binary.BigEndian.Uint16(data[4:]) - h.FragmentOffset = util.BigEndianUint24(data[6:]) - h.FragmentLength = util.BigEndianUint24(data[9:]) - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go deleted file mode 100644 index d5c861d9..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate.go +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "github.com/pion/dtls/v2/internal/util" -) - -// MessageCertificate is a DTLS Handshake Message -// it can contain either a Client or Server Certificate -// -// https://tools.ietf.org/html/rfc5246#section-7.4.2 -type MessageCertificate struct { - Certificate [][]byte -} - -// Type returns the Handshake Type -func (m MessageCertificate) Type() Type { - return TypeCertificate -} - -const ( - handshakeMessageCertificateLengthFieldSize = 3 -) - -// Marshal encodes the Handshake -func (m *MessageCertificate) Marshal() ([]byte, error) { - out := make([]byte, handshakeMessageCertificateLengthFieldSize) - - for _, r := range m.Certificate { - // Certificate Length - out = append(out, make([]byte, handshakeMessageCertificateLengthFieldSize)...) - util.PutBigEndianUint24(out[len(out)-handshakeMessageCertificateLengthFieldSize:], uint32(len(r))) - - // Certificate body - out = append(out, append([]byte{}, r...)...) - } - - // Total Payload Size - util.PutBigEndianUint24(out[0:], uint32(len(out[handshakeMessageCertificateLengthFieldSize:]))) - return out, nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageCertificate) Unmarshal(data []byte) error { - if len(data) < handshakeMessageCertificateLengthFieldSize { - return errBufferTooSmall - } - - if certificateBodyLen := int(util.BigEndianUint24(data)); certificateBodyLen+handshakeMessageCertificateLengthFieldSize != len(data) { - return errLengthMismatch - } - - offset := handshakeMessageCertificateLengthFieldSize - for offset < len(data) { - certificateLen := int(util.BigEndianUint24(data[offset:])) - offset += handshakeMessageCertificateLengthFieldSize - - if offset+certificateLen > len(data) { - return errLengthMismatch - } - - m.Certificate = append(m.Certificate, append([]byte{}, data[offset:offset+certificateLen]...)) - offset += certificateLen - } - - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go deleted file mode 100644 index 11a44d44..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_request.go +++ /dev/null @@ -1,144 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/crypto/clientcertificate" - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" - "github.com/pion/dtls/v2/pkg/crypto/signaturehash" -) - -/* -MessageCertificateRequest is so a non-anonymous server can optionally -request a certificate from the client, if appropriate for the selected cipher -suite. This message, if sent, will immediately follow the ServerKeyExchange -message (if it is sent; otherwise, this message follows the -server's Certificate message). - -https://tools.ietf.org/html/rfc5246#section-7.4.4 -*/ -type MessageCertificateRequest struct { - CertificateTypes []clientcertificate.Type - SignatureHashAlgorithms []signaturehash.Algorithm - CertificateAuthoritiesNames [][]byte -} - -const ( - messageCertificateRequestMinLength = 5 -) - -// Type returns the Handshake Type -func (m MessageCertificateRequest) Type() Type { - return TypeCertificateRequest -} - -// Marshal encodes the Handshake -func (m *MessageCertificateRequest) Marshal() ([]byte, error) { - out := []byte{byte(len(m.CertificateTypes))} - for _, v := range m.CertificateTypes { - out = append(out, byte(v)) - } - - out = append(out, []byte{0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(m.SignatureHashAlgorithms)*2)) - for _, v := range m.SignatureHashAlgorithms { - out = append(out, byte(v.Hash)) - out = append(out, byte(v.Signature)) - } - - // Distinguished Names - casLength := 0 - for _, ca := range m.CertificateAuthoritiesNames { - casLength += len(ca) + 2 - } - out = append(out, []byte{0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(casLength)) - if casLength > 0 { - for _, ca := range m.CertificateAuthoritiesNames { - out = append(out, []byte{0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(ca))) - out = append(out, ca...) - } - } - return out, nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageCertificateRequest) Unmarshal(data []byte) error { - if len(data) < messageCertificateRequestMinLength { - return errBufferTooSmall - } - - offset := 0 - certificateTypesLength := int(data[0]) - offset++ - - if (offset + certificateTypesLength) > len(data) { - return errBufferTooSmall - } - - for i := 0; i < certificateTypesLength; i++ { - certType := clientcertificate.Type(data[offset+i]) - if _, ok := clientcertificate.Types()[certType]; ok { - m.CertificateTypes = append(m.CertificateTypes, certType) - } - } - offset += certificateTypesLength - if len(data) < offset+2 { - return errBufferTooSmall - } - signatureHashAlgorithmsLength := int(binary.BigEndian.Uint16(data[offset:])) - offset += 2 - - if (offset + signatureHashAlgorithmsLength) > len(data) { - return errBufferTooSmall - } - - for i := 0; i < signatureHashAlgorithmsLength; i += 2 { - if len(data) < (offset + i + 2) { - return errBufferTooSmall - } - h := hash.Algorithm(data[offset+i]) - s := signature.Algorithm(data[offset+i+1]) - - if _, ok := hash.Algorithms()[h]; !ok { - continue - } else if _, ok := signature.Algorithms()[s]; !ok { - continue - } - m.SignatureHashAlgorithms = append(m.SignatureHashAlgorithms, signaturehash.Algorithm{Signature: s, Hash: h}) - } - - offset += signatureHashAlgorithmsLength - if len(data) < offset+2 { - return errBufferTooSmall - } - casLength := int(binary.BigEndian.Uint16(data[offset:])) - offset += 2 - if (offset + casLength) > len(data) { - return errBufferTooSmall - } - cas := make([]byte, casLength) - copy(cas, data[offset:offset+casLength]) - m.CertificateAuthoritiesNames = nil - for len(cas) > 0 { - if len(cas) < 2 { - return errBufferTooSmall - } - caLen := binary.BigEndian.Uint16(cas) - cas = cas[2:] - - if len(cas) < int(caLen) { - return errBufferTooSmall - } - - m.CertificateAuthoritiesNames = append(m.CertificateAuthoritiesNames, cas[:caLen]) - cas = cas[caLen:] - } - - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go deleted file mode 100644 index 9e02a9c1..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_certificate_verify.go +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" -) - -// MessageCertificateVerify provide explicit verification of a -// client certificate. -// -// https://tools.ietf.org/html/rfc5246#section-7.4.8 -type MessageCertificateVerify struct { - HashAlgorithm hash.Algorithm - SignatureAlgorithm signature.Algorithm - Signature []byte -} - -const handshakeMessageCertificateVerifyMinLength = 4 - -// Type returns the Handshake Type -func (m MessageCertificateVerify) Type() Type { - return TypeCertificateVerify -} - -// Marshal encodes the Handshake -func (m *MessageCertificateVerify) Marshal() ([]byte, error) { - out := make([]byte, 1+1+2+len(m.Signature)) - - out[0] = byte(m.HashAlgorithm) - out[1] = byte(m.SignatureAlgorithm) - binary.BigEndian.PutUint16(out[2:], uint16(len(m.Signature))) - copy(out[4:], m.Signature) - return out, nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageCertificateVerify) Unmarshal(data []byte) error { - if len(data) < handshakeMessageCertificateVerifyMinLength { - return errBufferTooSmall - } - - m.HashAlgorithm = hash.Algorithm(data[0]) - if _, ok := hash.Algorithms()[m.HashAlgorithm]; !ok { - return errInvalidHashAlgorithm - } - - m.SignatureAlgorithm = signature.Algorithm(data[1]) - if _, ok := signature.Algorithms()[m.SignatureAlgorithm]; !ok { - return errInvalidSignatureAlgorithm - } - - signatureLength := int(binary.BigEndian.Uint16(data[2:])) - if (signatureLength + 4) != len(data) { - return errBufferTooSmall - } - - m.Signature = append([]byte{}, data[4:]...) - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go deleted file mode 100644 index bea6dd96..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_hello.go +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/extension" -) - -/* -MessageClientHello is for when a client first connects to a server it is -required to send the client hello as its first message. The client can also send a -client hello in response to a hello request or on its own -initiative in order to renegotiate the security parameters in an -existing connection. -*/ -type MessageClientHello struct { - Version protocol.Version - Random Random - Cookie []byte - - SessionID []byte - - CipherSuiteIDs []uint16 - CompressionMethods []*protocol.CompressionMethod - Extensions []extension.Extension -} - -const handshakeMessageClientHelloVariableWidthStart = 34 - -// Type returns the Handshake Type -func (m MessageClientHello) Type() Type { - return TypeClientHello -} - -// Marshal encodes the Handshake -func (m *MessageClientHello) Marshal() ([]byte, error) { - if len(m.Cookie) > 255 { - return nil, errCookieTooLong - } - - out := make([]byte, handshakeMessageClientHelloVariableWidthStart) - out[0] = m.Version.Major - out[1] = m.Version.Minor - - rand := m.Random.MarshalFixed() - copy(out[2:], rand[:]) - - out = append(out, byte(len(m.SessionID))) - out = append(out, m.SessionID...) - - out = append(out, byte(len(m.Cookie))) - out = append(out, m.Cookie...) - out = append(out, encodeCipherSuiteIDs(m.CipherSuiteIDs)...) - out = append(out, protocol.EncodeCompressionMethods(m.CompressionMethods)...) - - extensions, err := extension.Marshal(m.Extensions) - if err != nil { - return nil, err - } - - return append(out, extensions...), nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageClientHello) Unmarshal(data []byte) error { - if len(data) < 2+RandomLength { - return errBufferTooSmall - } - - m.Version.Major = data[0] - m.Version.Minor = data[1] - - var random [RandomLength]byte - copy(random[:], data[2:]) - m.Random.UnmarshalFixed(random) - - // rest of packet has variable width sections - currOffset := handshakeMessageClientHelloVariableWidthStart - - currOffset++ - if len(data) <= currOffset { - return errBufferTooSmall - } - n := int(data[currOffset-1]) - if len(data) <= currOffset+n { - return errBufferTooSmall - } - m.SessionID = append([]byte{}, data[currOffset:currOffset+n]...) - currOffset += len(m.SessionID) - - currOffset++ - if len(data) <= currOffset { - return errBufferTooSmall - } - n = int(data[currOffset-1]) - if len(data) <= currOffset+n { - return errBufferTooSmall - } - m.Cookie = append([]byte{}, data[currOffset:currOffset+n]...) - currOffset += len(m.Cookie) - - // Cipher Suites - if len(data) < currOffset { - return errBufferTooSmall - } - cipherSuiteIDs, err := decodeCipherSuiteIDs(data[currOffset:]) - if err != nil { - return err - } - m.CipherSuiteIDs = cipherSuiteIDs - if len(data) < currOffset+2 { - return errBufferTooSmall - } - currOffset += int(binary.BigEndian.Uint16(data[currOffset:])) + 2 - - // Compression Methods - if len(data) < currOffset { - return errBufferTooSmall - } - compressionMethods, err := protocol.DecodeCompressionMethods(data[currOffset:]) - if err != nil { - return err - } - m.CompressionMethods = compressionMethods - if len(data) < currOffset { - return errBufferTooSmall - } - currOffset += int(data[currOffset]) + 1 - - // Extensions - extensions, err := extension.Unmarshal(data[currOffset:]) - if err != nil { - return err - } - m.Extensions = extensions - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go deleted file mode 100644 index 2abcd5bf..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_client_key_exchange.go +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/internal/ciphersuite/types" -) - -// MessageClientKeyExchange is a DTLS Handshake Message -// With this message, the premaster secret is set, either by direct -// transmission of the RSA-encrypted secret or by the transmission of -// Diffie-Hellman parameters that will allow each side to agree upon -// the same premaster secret. -// -// https://tools.ietf.org/html/rfc5246#section-7.4.7 -type MessageClientKeyExchange struct { - IdentityHint []byte - PublicKey []byte - - // for unmarshaling - KeyExchangeAlgorithm types.KeyExchangeAlgorithm -} - -// Type returns the Handshake Type -func (m MessageClientKeyExchange) Type() Type { - return TypeClientKeyExchange -} - -// Marshal encodes the Handshake -func (m *MessageClientKeyExchange) Marshal() (out []byte, err error) { - if m.IdentityHint == nil && m.PublicKey == nil { - return nil, errInvalidClientKeyExchange - } - - if m.IdentityHint != nil { - out = append([]byte{0x00, 0x00}, m.IdentityHint...) - binary.BigEndian.PutUint16(out, uint16(len(out)-2)) - } - - if m.PublicKey != nil { - out = append(out, byte(len(m.PublicKey))) - out = append(out, m.PublicKey...) - } - - return out, nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageClientKeyExchange) Unmarshal(data []byte) error { - switch { - case len(data) < 2: - return errBufferTooSmall - case m.KeyExchangeAlgorithm == types.KeyExchangeAlgorithmNone: - return errCipherSuiteUnset - } - - offset := 0 - if m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmPsk) { - pskLength := int(binary.BigEndian.Uint16(data)) - if pskLength > len(data)-2 { - return errBufferTooSmall - } - - m.IdentityHint = append([]byte{}, data[2:pskLength+2]...) - offset += pskLength + 2 - } - - if m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmEcdhe) { - publicKeyLength := int(data[offset]) - if publicKeyLength > len(data)-1-offset { - return errBufferTooSmall - } - - m.PublicKey = append([]byte{}, data[offset+1:]...) - } - - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go deleted file mode 100644 index 255aedd7..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_finished.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -// MessageFinished is a DTLS Handshake Message -// this message is the first one protected with the just -// negotiated algorithms, keys, and secrets. Recipients of Finished -// messages MUST verify that the contents are correct. -// -// https://tools.ietf.org/html/rfc5246#section-7.4.9 -type MessageFinished struct { - VerifyData []byte -} - -// Type returns the Handshake Type -func (m MessageFinished) Type() Type { - return TypeFinished -} - -// Marshal encodes the Handshake -func (m *MessageFinished) Marshal() ([]byte, error) { - return append([]byte{}, m.VerifyData...), nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageFinished) Unmarshal(data []byte) error { - m.VerifyData = append([]byte{}, data...) - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go deleted file mode 100644 index 398e59cc..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_hello_verify_request.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "github.com/pion/dtls/v2/pkg/protocol" -) - -// MessageHelloVerifyRequest is as follows: -// -// struct { -// ProtocolVersion server_version; -// opaque cookie<0..2^8-1>; -// } HelloVerifyRequest; -// -// The HelloVerifyRequest message type is hello_verify_request(3). -// -// When the client sends its ClientHello message to the server, the server -// MAY respond with a HelloVerifyRequest message. This message contains -// a stateless cookie generated using the technique of [PHOTURIS]. The -// client MUST retransmit the ClientHello with the cookie added. -// -// https://tools.ietf.org/html/rfc6347#section-4.2.1 -type MessageHelloVerifyRequest struct { - Version protocol.Version - Cookie []byte -} - -// Type returns the Handshake Type -func (m MessageHelloVerifyRequest) Type() Type { - return TypeHelloVerifyRequest -} - -// Marshal encodes the Handshake -func (m *MessageHelloVerifyRequest) Marshal() ([]byte, error) { - if len(m.Cookie) > 255 { - return nil, errCookieTooLong - } - - out := make([]byte, 3+len(m.Cookie)) - out[0] = m.Version.Major - out[1] = m.Version.Minor - out[2] = byte(len(m.Cookie)) - copy(out[3:], m.Cookie) - - return out, nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageHelloVerifyRequest) Unmarshal(data []byte) error { - if len(data) < 3 { - return errBufferTooSmall - } - m.Version.Major = data[0] - m.Version.Minor = data[1] - cookieLength := int(data[2]) - if len(data) < cookieLength+3 { - return errBufferTooSmall - } - m.Cookie = make([]byte, cookieLength) - - copy(m.Cookie, data[3:3+cookieLength]) - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go deleted file mode 100644 index caf186da..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello.go +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/extension" -) - -// MessageServerHello is sent in response to a ClientHello -// message when it was able to find an acceptable set of algorithms. -// If it cannot find such a match, it will respond with a handshake -// failure alert. -// -// https://tools.ietf.org/html/rfc5246#section-7.4.1.3 -type MessageServerHello struct { - Version protocol.Version - Random Random - - SessionID []byte - - CipherSuiteID *uint16 - CompressionMethod *protocol.CompressionMethod - Extensions []extension.Extension -} - -const messageServerHelloVariableWidthStart = 2 + RandomLength - -// Type returns the Handshake Type -func (m MessageServerHello) Type() Type { - return TypeServerHello -} - -// Marshal encodes the Handshake -func (m *MessageServerHello) Marshal() ([]byte, error) { - if m.CipherSuiteID == nil { - return nil, errCipherSuiteUnset - } else if m.CompressionMethod == nil { - return nil, errCompressionMethodUnset - } - - out := make([]byte, messageServerHelloVariableWidthStart) - out[0] = m.Version.Major - out[1] = m.Version.Minor - - rand := m.Random.MarshalFixed() - copy(out[2:], rand[:]) - - out = append(out, byte(len(m.SessionID))) - out = append(out, m.SessionID...) - - out = append(out, []byte{0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], *m.CipherSuiteID) - - out = append(out, byte(m.CompressionMethod.ID)) - - extensions, err := extension.Marshal(m.Extensions) - if err != nil { - return nil, err - } - - return append(out, extensions...), nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageServerHello) Unmarshal(data []byte) error { - if len(data) < 2+RandomLength { - return errBufferTooSmall - } - - m.Version.Major = data[0] - m.Version.Minor = data[1] - - var random [RandomLength]byte - copy(random[:], data[2:]) - m.Random.UnmarshalFixed(random) - - currOffset := messageServerHelloVariableWidthStart - currOffset++ - if len(data) <= currOffset { - return errBufferTooSmall - } - - n := int(data[currOffset-1]) - if len(data) <= currOffset+n { - return errBufferTooSmall - } - m.SessionID = append([]byte{}, data[currOffset:currOffset+n]...) - currOffset += len(m.SessionID) - - if len(data) < currOffset+2 { - return errBufferTooSmall - } - m.CipherSuiteID = new(uint16) - *m.CipherSuiteID = binary.BigEndian.Uint16(data[currOffset:]) - currOffset += 2 - - if len(data) <= currOffset { - return errBufferTooSmall - } - if compressionMethod, ok := protocol.CompressionMethods()[protocol.CompressionMethodID(data[currOffset])]; ok { - m.CompressionMethod = compressionMethod - currOffset++ - } else { - return errInvalidCompressionMethod - } - - if len(data) <= currOffset { - m.Extensions = []extension.Extension{} - return nil - } - - extensions, err := extension.Unmarshal(data[currOffset:]) - if err != nil { - return err - } - m.Extensions = extensions - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go deleted file mode 100644 index b187dd41..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_hello_done.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -// MessageServerHelloDone is final non-encrypted message from server -// this communicates server has sent all its handshake messages and next -// should be MessageFinished -type MessageServerHelloDone struct{} - -// Type returns the Handshake Type -func (m MessageServerHelloDone) Type() Type { - return TypeServerHelloDone -} - -// Marshal encodes the Handshake -func (m *MessageServerHelloDone) Marshal() ([]byte, error) { - return []byte{}, nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageServerHelloDone) Unmarshal([]byte) error { - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go deleted file mode 100644 index 82abbe0d..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/message_server_key_exchange.go +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/internal/ciphersuite/types" - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/hash" - "github.com/pion/dtls/v2/pkg/crypto/signature" -) - -// MessageServerKeyExchange supports ECDH and PSK -type MessageServerKeyExchange struct { - IdentityHint []byte - - EllipticCurveType elliptic.CurveType - NamedCurve elliptic.Curve - PublicKey []byte - HashAlgorithm hash.Algorithm - SignatureAlgorithm signature.Algorithm - Signature []byte - - // for unmarshaling - KeyExchangeAlgorithm types.KeyExchangeAlgorithm -} - -// Type returns the Handshake Type -func (m MessageServerKeyExchange) Type() Type { - return TypeServerKeyExchange -} - -// Marshal encodes the Handshake -func (m *MessageServerKeyExchange) Marshal() ([]byte, error) { - var out []byte - if m.IdentityHint != nil { - out = append([]byte{0x00, 0x00}, m.IdentityHint...) - binary.BigEndian.PutUint16(out, uint16(len(out)-2)) - } - - if m.EllipticCurveType == 0 || len(m.PublicKey) == 0 { - return out, nil - } - out = append(out, byte(m.EllipticCurveType), 0x00, 0x00) - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(m.NamedCurve)) - - out = append(out, byte(len(m.PublicKey))) - out = append(out, m.PublicKey...) - switch { - case m.HashAlgorithm != hash.None && len(m.Signature) == 0: - return nil, errInvalidHashAlgorithm - case m.HashAlgorithm == hash.None && len(m.Signature) > 0: - return nil, errInvalidHashAlgorithm - case m.SignatureAlgorithm == signature.Anonymous && (m.HashAlgorithm != hash.None || len(m.Signature) > 0): - return nil, errInvalidSignatureAlgorithm - case m.SignatureAlgorithm == signature.Anonymous: - return out, nil - } - - out = append(out, []byte{byte(m.HashAlgorithm), byte(m.SignatureAlgorithm), 0x00, 0x00}...) - binary.BigEndian.PutUint16(out[len(out)-2:], uint16(len(m.Signature))) - out = append(out, m.Signature...) - - return out, nil -} - -// Unmarshal populates the message from encoded data -func (m *MessageServerKeyExchange) Unmarshal(data []byte) error { - switch { - case len(data) < 2: - return errBufferTooSmall - case m.KeyExchangeAlgorithm == types.KeyExchangeAlgorithmNone: - return errCipherSuiteUnset - } - - hintLength := binary.BigEndian.Uint16(data) - if int(hintLength) <= len(data)-2 && m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmPsk) { - m.IdentityHint = append([]byte{}, data[2:2+hintLength]...) - data = data[2+hintLength:] - } - if m.KeyExchangeAlgorithm == types.KeyExchangeAlgorithmPsk { - if len(data) == 0 { - return nil - } - return errLengthMismatch - } - - if !m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmEcdhe) { - return errLengthMismatch - } - - if _, ok := elliptic.CurveTypes()[elliptic.CurveType(data[0])]; ok { - m.EllipticCurveType = elliptic.CurveType(data[0]) - } else { - return errInvalidEllipticCurveType - } - - if len(data[1:]) < 2 { - return errBufferTooSmall - } - m.NamedCurve = elliptic.Curve(binary.BigEndian.Uint16(data[1:3])) - if _, ok := elliptic.Curves()[m.NamedCurve]; !ok { - return errInvalidNamedCurve - } - if len(data) < 4 { - return errBufferTooSmall - } - - publicKeyLength := int(data[3]) - offset := 4 + publicKeyLength - if len(data) < offset { - return errBufferTooSmall - } - m.PublicKey = append([]byte{}, data[4:offset]...) - - // Anon connection doesn't contains hashAlgorithm, signatureAlgorithm, signature - if len(data) == offset { - return nil - } else if len(data) <= offset { - return errBufferTooSmall - } - - m.HashAlgorithm = hash.Algorithm(data[offset]) - if _, ok := hash.Algorithms()[m.HashAlgorithm]; !ok { - return errInvalidHashAlgorithm - } - offset++ - if len(data) <= offset { - return errBufferTooSmall - } - m.SignatureAlgorithm = signature.Algorithm(data[offset]) - if _, ok := signature.Algorithms()[m.SignatureAlgorithm]; !ok { - return errInvalidSignatureAlgorithm - } - offset++ - if len(data) < offset+2 { - return errBufferTooSmall - } - signatureLength := int(binary.BigEndian.Uint16(data[offset:])) - offset += 2 - if len(data) < offset+signatureLength { - return errBufferTooSmall - } - m.Signature = append([]byte{}, data[offset:offset+signatureLength]...) - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go deleted file mode 100644 index 56f37569..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/random.go +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package handshake - -import ( - "crypto/rand" - "encoding/binary" - "time" -) - -// Consts for Random in Handshake -const ( - RandomBytesLength = 28 - RandomLength = RandomBytesLength + 4 -) - -// Random value that is used in ClientHello and ServerHello -// -// https://tools.ietf.org/html/rfc4346#section-7.4.1.2 -type Random struct { - GMTUnixTime time.Time - RandomBytes [RandomBytesLength]byte -} - -// MarshalFixed encodes the Handshake -func (r *Random) MarshalFixed() [RandomLength]byte { - var out [RandomLength]byte - - binary.BigEndian.PutUint32(out[0:], uint32(r.GMTUnixTime.Unix())) - copy(out[4:], r.RandomBytes[:]) - - return out -} - -// UnmarshalFixed populates the message from encoded data -func (r *Random) UnmarshalFixed(data [RandomLength]byte) { - r.GMTUnixTime = time.Unix(int64(binary.BigEndian.Uint32(data[0:])), 0) - copy(r.RandomBytes[:], data[4:]) -} - -// Populate fills the handshakeRandom with random values -// may be called multiple times -func (r *Random) Populate() error { - r.GMTUnixTime = time.Now() - - tmp := make([]byte, RandomBytesLength) - _, err := rand.Read(tmp) - copy(r.RandomBytes[:], tmp) - - return err -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go deleted file mode 100644 index cd4cb60a..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/errors.go +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package recordlayer implements the TLS Record Layer https://tools.ietf.org/html/rfc5246#section-6 -package recordlayer - -import ( - "errors" - - "github.com/pion/dtls/v2/pkg/protocol" -) - -var ( - errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113 - errInvalidPacketLength = &protocol.TemporaryError{Err: errors.New("packet length and declared length do not match")} //nolint:goerr113 - errSequenceNumberOverflow = &protocol.InternalError{Err: errors.New("sequence number overflow")} //nolint:goerr113 - errUnsupportedProtocolVersion = &protocol.FatalError{Err: errors.New("unsupported protocol version")} //nolint:goerr113 - errInvalidContentType = &protocol.TemporaryError{Err: errors.New("invalid content type")} //nolint:goerr113 -) diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go deleted file mode 100644 index 92252502..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/header.go +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package recordlayer - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/internal/util" - "github.com/pion/dtls/v2/pkg/protocol" -) - -// Header implements a TLS RecordLayer header -type Header struct { - ContentType protocol.ContentType - ContentLen uint16 - Version protocol.Version - Epoch uint16 - SequenceNumber uint64 // uint48 in spec -} - -// RecordLayer enums -const ( - HeaderSize = 13 - MaxSequenceNumber = 0x0000FFFFFFFFFFFF -) - -// Marshal encodes a TLS RecordLayer Header to binary -func (h *Header) Marshal() ([]byte, error) { - if h.SequenceNumber > MaxSequenceNumber { - return nil, errSequenceNumberOverflow - } - - out := make([]byte, HeaderSize) - out[0] = byte(h.ContentType) - out[1] = h.Version.Major - out[2] = h.Version.Minor - binary.BigEndian.PutUint16(out[3:], h.Epoch) - util.PutBigEndianUint48(out[5:], h.SequenceNumber) - binary.BigEndian.PutUint16(out[HeaderSize-2:], h.ContentLen) - return out, nil -} - -// Unmarshal populates a TLS RecordLayer Header from binary -func (h *Header) Unmarshal(data []byte) error { - if len(data) < HeaderSize { - return errBufferTooSmall - } - h.ContentType = protocol.ContentType(data[0]) - h.Version.Major = data[1] - h.Version.Minor = data[2] - h.Epoch = binary.BigEndian.Uint16(data[3:]) - - // SequenceNumber is stored as uint48, make into uint64 - seqCopy := make([]byte, 8) - copy(seqCopy[2:], data[5:11]) - h.SequenceNumber = binary.BigEndian.Uint64(seqCopy) - - if !h.Version.Equal(protocol.Version1_0) && !h.Version.Equal(protocol.Version1_2) { - return errUnsupportedProtocolVersion - } - - return nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go deleted file mode 100644 index 02325fd2..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/recordlayer/recordlayer.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package recordlayer - -import ( - "encoding/binary" - - "github.com/pion/dtls/v2/pkg/protocol" - "github.com/pion/dtls/v2/pkg/protocol/alert" - "github.com/pion/dtls/v2/pkg/protocol/handshake" -) - -// RecordLayer which handles all data transport. -// The record layer is assumed to sit directly on top of some -// reliable transport such as TCP. The record layer can carry four types of content: -// -// 1. Handshake messages—used for algorithm negotiation and key establishment. -// 2. ChangeCipherSpec messages—really part of the handshake but technically a separate kind of message. -// 3. Alert messages—used to signal that errors have occurred -// 4. Application layer data -// -// The DTLS record layer is extremely similar to that of TLS 1.1. The -// only change is the inclusion of an explicit sequence number in the -// record. This sequence number allows the recipient to correctly -// verify the TLS MAC. -// -// https://tools.ietf.org/html/rfc4347#section-4.1 -type RecordLayer struct { - Header Header - Content protocol.Content -} - -// Marshal encodes the RecordLayer to binary -func (r *RecordLayer) Marshal() ([]byte, error) { - contentRaw, err := r.Content.Marshal() - if err != nil { - return nil, err - } - - r.Header.ContentLen = uint16(len(contentRaw)) - r.Header.ContentType = r.Content.ContentType() - - headerRaw, err := r.Header.Marshal() - if err != nil { - return nil, err - } - - return append(headerRaw, contentRaw...), nil -} - -// Unmarshal populates the RecordLayer from binary -func (r *RecordLayer) Unmarshal(data []byte) error { - if len(data) < HeaderSize { - return errBufferTooSmall - } - if err := r.Header.Unmarshal(data); err != nil { - return err - } - - switch protocol.ContentType(data[0]) { - case protocol.ContentTypeChangeCipherSpec: - r.Content = &protocol.ChangeCipherSpec{} - case protocol.ContentTypeAlert: - r.Content = &alert.Alert{} - case protocol.ContentTypeHandshake: - r.Content = &handshake.Handshake{} - case protocol.ContentTypeApplicationData: - r.Content = &protocol.ApplicationData{} - default: - return errInvalidContentType - } - - return r.Content.Unmarshal(data[HeaderSize:]) -} - -// UnpackDatagram extracts all RecordLayer messages from a single datagram. -// Note that as with TLS, multiple handshake messages may be placed in -// the same DTLS record, provided that there is room and that they are -// part of the same flight. Thus, there are two acceptable ways to pack -// two DTLS messages into the same datagram: in the same record or in -// separate records. -// https://tools.ietf.org/html/rfc6347#section-4.2.3 -func UnpackDatagram(buf []byte) ([][]byte, error) { - out := [][]byte{} - - for offset := 0; len(buf) != offset; { - if len(buf)-offset <= HeaderSize { - return nil, errInvalidPacketLength - } - - pktLen := (HeaderSize + int(binary.BigEndian.Uint16(buf[offset+11:]))) - if offset+pktLen > len(buf) { - return nil, errInvalidPacketLength - } - - out = append(out, buf[offset:offset+pktLen]) - offset += pktLen - } - - return out, nil -} diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/version.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/version.go deleted file mode 100644 index c4d94ac3..00000000 --- a/vendor/github.com/pion/dtls/v2/pkg/protocol/version.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package protocol provides the DTLS wire format -package protocol - -// Version enums -var ( - Version1_0 = Version{Major: 0xfe, Minor: 0xff} //nolint:gochecknoglobals - Version1_2 = Version{Major: 0xfe, Minor: 0xfd} //nolint:gochecknoglobals -) - -// Version is the minor/major value in the RecordLayer -// and ClientHello/ServerHello -// -// https://tools.ietf.org/html/rfc4346#section-6.2.1 -type Version struct { - Major, Minor uint8 -} - -// Equal determines if two protocol versions are equal -func (v Version) Equal(x Version) bool { - return v.Major == x.Major && v.Minor == x.Minor -} diff --git a/vendor/github.com/pion/dtls/v2/renovate.json b/vendor/github.com/pion/dtls/v2/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/dtls/v2/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/dtls/v2/resume.go b/vendor/github.com/pion/dtls/v2/resume.go deleted file mode 100644 index c470d856..00000000 --- a/vendor/github.com/pion/dtls/v2/resume.go +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "context" - "net" -) - -// Resume imports an already established dtls connection using a specific dtls state -func Resume(state *State, conn net.Conn, config *Config) (*Conn, error) { - if err := state.initCipherSuite(); err != nil { - return nil, err - } - c, err := createConn(context.Background(), conn, config, state.isClient, state) - if err != nil { - return nil, err - } - - return c, nil -} diff --git a/vendor/github.com/pion/dtls/v2/session.go b/vendor/github.com/pion/dtls/v2/session.go deleted file mode 100644 index 99bf5a49..00000000 --- a/vendor/github.com/pion/dtls/v2/session.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -// Session store data needed in resumption -type Session struct { - // ID store session id - ID []byte - // Secret store session master secret - Secret []byte -} - -// SessionStore defines methods needed for session resumption. -type SessionStore interface { - // Set save a session. - // For client, use server name as key. - // For server, use session id. - Set(key []byte, s Session) error - // Get fetch a session. - Get(key []byte) (Session, error) - // Del clean saved session. - Del(key []byte) error -} diff --git a/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go b/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go deleted file mode 100644 index e306e9e6..00000000 --- a/vendor/github.com/pion/dtls/v2/srtp_protection_profile.go +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import "github.com/pion/dtls/v2/pkg/protocol/extension" - -// SRTPProtectionProfile defines the parameters and options that are in effect for the SRTP processing -// https://tools.ietf.org/html/rfc5764#section-4.1.2 -type SRTPProtectionProfile = extension.SRTPProtectionProfile - -const ( - SRTP_AES128_CM_HMAC_SHA1_80 SRTPProtectionProfile = extension.SRTP_AES128_CM_HMAC_SHA1_80 // nolint:revive,stylecheck - SRTP_AES128_CM_HMAC_SHA1_32 SRTPProtectionProfile = extension.SRTP_AES128_CM_HMAC_SHA1_32 // nolint:revive,stylecheck - SRTP_AEAD_AES_128_GCM SRTPProtectionProfile = extension.SRTP_AEAD_AES_128_GCM // nolint:revive,stylecheck - SRTP_AEAD_AES_256_GCM SRTPProtectionProfile = extension.SRTP_AEAD_AES_256_GCM // nolint:revive,stylecheck -) diff --git a/vendor/github.com/pion/dtls/v2/state.go b/vendor/github.com/pion/dtls/v2/state.go deleted file mode 100644 index e9f86a80..00000000 --- a/vendor/github.com/pion/dtls/v2/state.go +++ /dev/null @@ -1,216 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -import ( - "bytes" - "encoding/gob" - "sync/atomic" - - "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/dtls/v2/pkg/crypto/prf" - "github.com/pion/dtls/v2/pkg/protocol/handshake" - "github.com/pion/transport/v2/replaydetector" -) - -// State holds the dtls connection state and implements both encoding.BinaryMarshaler and encoding.BinaryUnmarshaler -type State struct { - localEpoch, remoteEpoch atomic.Value - localSequenceNumber []uint64 // uint48 - localRandom, remoteRandom handshake.Random - masterSecret []byte - cipherSuite CipherSuite // nil if a cipherSuite hasn't been chosen - - srtpProtectionProfile SRTPProtectionProfile // Negotiated SRTPProtectionProfile - PeerCertificates [][]byte - IdentityHint []byte - SessionID []byte - - isClient bool - - preMasterSecret []byte - extendedMasterSecret bool - - namedCurve elliptic.Curve - localKeypair *elliptic.Keypair - cookie []byte - handshakeSendSequence int - handshakeRecvSequence int - serverName string - remoteRequestedCertificate bool // Did we get a CertificateRequest - localCertificatesVerify []byte // cache CertificateVerify - localVerifyData []byte // cached VerifyData - localKeySignature []byte // cached keySignature - peerCertificatesVerified bool - - replayDetector []replaydetector.ReplayDetector - - peerSupportedProtocols []string - NegotiatedProtocol string -} - -type serializedState struct { - LocalEpoch uint16 - RemoteEpoch uint16 - LocalRandom [handshake.RandomLength]byte - RemoteRandom [handshake.RandomLength]byte - CipherSuiteID uint16 - MasterSecret []byte - SequenceNumber uint64 - SRTPProtectionProfile uint16 - PeerCertificates [][]byte - IdentityHint []byte - SessionID []byte - IsClient bool -} - -func (s *State) clone() *State { - serialized := s.serialize() - state := &State{} - state.deserialize(*serialized) - - return state -} - -func (s *State) serialize() *serializedState { - // Marshal random values - localRnd := s.localRandom.MarshalFixed() - remoteRnd := s.remoteRandom.MarshalFixed() - - epoch := s.getLocalEpoch() - return &serializedState{ - LocalEpoch: s.getLocalEpoch(), - RemoteEpoch: s.getRemoteEpoch(), - CipherSuiteID: uint16(s.cipherSuite.ID()), - MasterSecret: s.masterSecret, - SequenceNumber: atomic.LoadUint64(&s.localSequenceNumber[epoch]), - LocalRandom: localRnd, - RemoteRandom: remoteRnd, - SRTPProtectionProfile: uint16(s.srtpProtectionProfile), - PeerCertificates: s.PeerCertificates, - IdentityHint: s.IdentityHint, - SessionID: s.SessionID, - IsClient: s.isClient, - } -} - -func (s *State) deserialize(serialized serializedState) { - // Set epoch values - epoch := serialized.LocalEpoch - s.localEpoch.Store(serialized.LocalEpoch) - s.remoteEpoch.Store(serialized.RemoteEpoch) - - for len(s.localSequenceNumber) <= int(epoch) { - s.localSequenceNumber = append(s.localSequenceNumber, uint64(0)) - } - - // Set random values - localRandom := &handshake.Random{} - localRandom.UnmarshalFixed(serialized.LocalRandom) - s.localRandom = *localRandom - - remoteRandom := &handshake.Random{} - remoteRandom.UnmarshalFixed(serialized.RemoteRandom) - s.remoteRandom = *remoteRandom - - s.isClient = serialized.IsClient - - // Set master secret - s.masterSecret = serialized.MasterSecret - - // Set cipher suite - s.cipherSuite = cipherSuiteForID(CipherSuiteID(serialized.CipherSuiteID), nil) - - atomic.StoreUint64(&s.localSequenceNumber[epoch], serialized.SequenceNumber) - s.srtpProtectionProfile = SRTPProtectionProfile(serialized.SRTPProtectionProfile) - - // Set remote certificate - s.PeerCertificates = serialized.PeerCertificates - s.IdentityHint = serialized.IdentityHint - s.SessionID = serialized.SessionID -} - -func (s *State) initCipherSuite() error { - if s.cipherSuite.IsInitialized() { - return nil - } - - localRandom := s.localRandom.MarshalFixed() - remoteRandom := s.remoteRandom.MarshalFixed() - - var err error - if s.isClient { - err = s.cipherSuite.Init(s.masterSecret, localRandom[:], remoteRandom[:], true) - } else { - err = s.cipherSuite.Init(s.masterSecret, remoteRandom[:], localRandom[:], false) - } - if err != nil { - return err - } - return nil -} - -// MarshalBinary is a binary.BinaryMarshaler.MarshalBinary implementation -func (s *State) MarshalBinary() ([]byte, error) { - serialized := s.serialize() - - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - if err := enc.Encode(*serialized); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// UnmarshalBinary is a binary.BinaryUnmarshaler.UnmarshalBinary implementation -func (s *State) UnmarshalBinary(data []byte) error { - enc := gob.NewDecoder(bytes.NewBuffer(data)) - var serialized serializedState - if err := enc.Decode(&serialized); err != nil { - return err - } - - s.deserialize(serialized) - - return s.initCipherSuite() -} - -// ExportKeyingMaterial returns length bytes of exported key material in a new -// slice as defined in RFC 5705. -// This allows protocols to use DTLS for key establishment, but -// then use some of the keying material for their own purposes -func (s *State) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) { - if s.getLocalEpoch() == 0 { - return nil, errHandshakeInProgress - } else if len(context) != 0 { - return nil, errContextUnsupported - } else if _, ok := invalidKeyingLabels()[label]; ok { - return nil, errReservedExportKeyingMaterial - } - - localRandom := s.localRandom.MarshalFixed() - remoteRandom := s.remoteRandom.MarshalFixed() - - seed := []byte(label) - if s.isClient { - seed = append(append(seed, localRandom[:]...), remoteRandom[:]...) - } else { - seed = append(append(seed, remoteRandom[:]...), localRandom[:]...) - } - return prf.PHash(s.masterSecret, seed, length, s.cipherSuite.HashFunc()) -} - -func (s *State) getRemoteEpoch() uint16 { - if remoteEpoch, ok := s.remoteEpoch.Load().(uint16); ok { - return remoteEpoch - } - return 0 -} - -func (s *State) getLocalEpoch() uint16 { - if localEpoch, ok := s.localEpoch.Load().(uint16); ok { - return localEpoch - } - return 0 -} diff --git a/vendor/github.com/pion/dtls/v2/util.go b/vendor/github.com/pion/dtls/v2/util.go deleted file mode 100644 index 663c4437..00000000 --- a/vendor/github.com/pion/dtls/v2/util.go +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package dtls - -func findMatchingSRTPProfile(a, b []SRTPProtectionProfile) (SRTPProtectionProfile, bool) { - for _, aProfile := range a { - for _, bProfile := range b { - if aProfile == bProfile { - return aProfile, true - } - } - } - return 0, false -} - -func findMatchingCipherSuite(a, b []CipherSuite) (CipherSuite, bool) { - for _, aSuite := range a { - for _, bSuite := range b { - if aSuite.ID() == bSuite.ID() { - return aSuite, true - } - } - } - return nil, false -} - -func splitBytes(bytes []byte, splitLen int) [][]byte { - splitBytes := make([][]byte, 0) - numBytes := len(bytes) - for i := 0; i < numBytes; i += splitLen { - j := i + splitLen - if j > numBytes { - j = numBytes - } - - splitBytes = append(splitBytes, bytes[i:j]) - } - - return splitBytes -} diff --git a/vendor/github.com/pion/ice/v2/.gitignore b/vendor/github.com/pion/ice/v2/.gitignore deleted file mode 100644 index 6e2f206a..00000000 --- a/vendor/github.com/pion/ice/v2/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/ice/v2/.golangci.yml b/vendor/github.com/pion/ice/v2/.golangci.yml deleted file mode 100644 index 4e3eddf4..00000000 --- a/vendor/github.com/pion/ice/v2/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/ice/v2/.goreleaser.yml b/vendor/github.com/pion/ice/v2/.goreleaser.yml deleted file mode 100644 index 30093e9d..00000000 --- a/vendor/github.com/pion/ice/v2/.goreleaser.yml +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -builds: -- skip: true diff --git a/vendor/github.com/pion/ice/v2/AUTHORS.txt b/vendor/github.com/pion/ice/v2/AUTHORS.txt deleted file mode 100644 index 57eb6937..00000000 --- a/vendor/github.com/pion/ice/v2/AUTHORS.txt +++ /dev/null @@ -1,65 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aaron France -Adam Kiss -adwpc -Aleksandr Razumov -aler9 <46489434+aler9@users.noreply.github.com> -Antoine Baché -Artur Shellunts -Assad Obaid -Atsushi Watanabe -backkem -buptczq -cgojin -Chao Yuan -cnderrauber -David Hamilton -David Zhao -David Zhao -Eric Daniels -Genteure -Henry -hexiang -hn8 <10730886+hn8@users.noreply.github.com> -Hugo Arregui -Hugo Arregui -Jason Maldonis -Jerko Steiner -JooYoung -Juliusz Chroboczek -Kacper Bąk <56700396+53jk1@users.noreply.github.com> -Kevin Caffrey -Konstantin Itskov -korymiller1489 -Kyle Carberry -Lander Noterman -Luke Curley -Meelap Shah -Michael MacDonald -Michael MacDonald -Mikhail Bragin -Miroslav Šedivý -Nevio Vesic -Ori Bernstein -Rasmus Hanning -Robert Eperjesi -Sam Lancia -Sam Lancia -San9H0 -Sean DuBois -Sean DuBois -Sebastian Waisbrot -Sidney San Martín -Steffen Vogel -Will Forcey -Woodrow Douglass -Yutaka Takeda -ZHENK -Zizheng Tai - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/ice/v2/LICENSE b/vendor/github.com/pion/ice/v2/LICENSE deleted file mode 100644 index 491caf6b..00000000 --- a/vendor/github.com/pion/ice/v2/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2023 The Pion community - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/pion/ice/v2/README.md b/vendor/github.com/pion/ice/v2/README.md deleted file mode 100644 index 111ca705..00000000 --- a/vendor/github.com/pion/ice/v2/README.md +++ /dev/null @@ -1,34 +0,0 @@ -

-
- Pion ICE -
-

-

A Go implementation of ICE

-

- Pion ICE - Slack Widget -
- GitHub Workflow Status - Go Reference - Coverage Status - Go Report Card - License: MIT -

-
- -### Roadmap -The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones. - -### Community -Pion has an active community on the [Slack](https://pion.ly/slack). - -Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news. - -We are always looking to support **your projects**. Please reach out if you have something to build! -If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) - -### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) - -### License -MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/ice/v2/addr.go b/vendor/github.com/pion/ice/v2/addr.go deleted file mode 100644 index 1d70025b..00000000 --- a/vendor/github.com/pion/ice/v2/addr.go +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" -) - -func parseMulticastAnswerAddr(in net.Addr) (net.IP, bool) { - switch addr := in.(type) { - case *net.IPAddr: - return addr.IP, true - case *net.UDPAddr: - return addr.IP, true - case *net.TCPAddr: - return addr.IP, true - } - return nil, false -} - -func parseAddr(in net.Addr) (net.IP, int, NetworkType, bool) { - switch addr := in.(type) { - case *net.UDPAddr: - return addr.IP, addr.Port, NetworkTypeUDP4, true - case *net.TCPAddr: - return addr.IP, addr.Port, NetworkTypeTCP4, true - } - return nil, 0, 0, false -} - -func createAddr(network NetworkType, ip net.IP, port int) net.Addr { - switch { - case network.IsTCP(): - return &net.TCPAddr{IP: ip, Port: port} - default: - return &net.UDPAddr{IP: ip, Port: port} - } -} - -func addrEqual(a, b net.Addr) bool { - aIP, aPort, aType, aOk := parseAddr(a) - if !aOk { - return false - } - - bIP, bPort, bType, bOk := parseAddr(b) - if !bOk { - return false - } - - return aType == bType && aIP.Equal(bIP) && aPort == bPort -} - -// AddrPort is an IP and a port number. -type AddrPort [18]byte - -func toAddrPort(addr net.Addr) AddrPort { - var ap AddrPort - switch addr := addr.(type) { - case *net.UDPAddr: - copy(ap[:16], addr.IP.To16()) - ap[16] = uint8(addr.Port >> 8) - ap[17] = uint8(addr.Port) - case *net.TCPAddr: - copy(ap[:16], addr.IP.To16()) - ap[16] = uint8(addr.Port >> 8) - ap[17] = uint8(addr.Port) - } - return ap -} diff --git a/vendor/github.com/pion/ice/v2/agent.go b/vendor/github.com/pion/ice/v2/agent.go deleted file mode 100644 index 5350330f..00000000 --- a/vendor/github.com/pion/ice/v2/agent.go +++ /dev/null @@ -1,1206 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package ice implements the Interactive Connectivity Establishment (ICE) -// protocol defined in rfc5245. -package ice - -import ( - "context" - "fmt" - "net" - "strings" - "sync" - "sync/atomic" - "time" - - atomicx "github.com/pion/ice/v2/internal/atomic" - stunx "github.com/pion/ice/v2/internal/stun" - "github.com/pion/logging" - "github.com/pion/mdns" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/packetio" - "github.com/pion/transport/v2/stdnet" - "github.com/pion/transport/v2/vnet" - "golang.org/x/net/proxy" -) - -type bindingRequest struct { - timestamp time.Time - transactionID [stun.TransactionIDSize]byte - destination net.Addr - isUseCandidate bool -} - -// Agent represents the ICE agent -type Agent struct { - chanTask chan task - afterRunFn []func(ctx context.Context) - muAfterRun sync.Mutex - - onConnectionStateChangeHdlr atomic.Value // func(ConnectionState) - onSelectedCandidatePairChangeHdlr atomic.Value // func(Candidate, Candidate) - onCandidateHdlr atomic.Value // func(Candidate) - - // State owned by the taskLoop - onConnected chan struct{} - onConnectedOnce sync.Once - - // Force candidate to be contacted immediately (instead of waiting for task ticker) - forceCandidateContact chan bool - - tieBreaker uint64 - lite bool - - connectionState ConnectionState - gatheringState GatheringState - - mDNSMode MulticastDNSMode - mDNSName string - mDNSConn *mdns.Conn - - muHaveStarted sync.Mutex - startedCh <-chan struct{} - startedFn func() - isControlling bool - - maxBindingRequests uint16 - - hostAcceptanceMinWait time.Duration - srflxAcceptanceMinWait time.Duration - prflxAcceptanceMinWait time.Duration - relayAcceptanceMinWait time.Duration - - portMin uint16 - portMax uint16 - - candidateTypes []CandidateType - - // How long connectivity checks can fail before the ICE Agent - // goes to disconnected - disconnectedTimeout time.Duration - - // How long connectivity checks can fail before the ICE Agent - // goes to failed - failedTimeout time.Duration - - // How often should we send keepalive packets? - // 0 means never - keepaliveInterval time.Duration - - // How often should we run our internal taskLoop to check for state changes when connecting - checkInterval time.Duration - - localUfrag string - localPwd string - localCandidates map[NetworkType][]Candidate - - remoteUfrag string - remotePwd string - remoteCandidates map[NetworkType][]Candidate - - checklist []*CandidatePair - selector pairCandidateSelector - - selectedPair atomic.Value // *CandidatePair - - urls []*stun.URI - networkTypes []NetworkType - - buf *packetio.Buffer - - // LRU of outbound Binding request Transaction IDs - pendingBindingRequests []bindingRequest - - // 1:1 D-NAT IP address mapping - extIPMapper *externalIPMapper - - // State for closing - done chan struct{} - taskLoopDone chan struct{} - err atomicx.Error - - gatherCandidateCancel func() - gatherCandidateDone chan struct{} - - chanCandidate chan Candidate - chanCandidatePair chan *CandidatePair - chanState chan ConnectionState - - loggerFactory logging.LoggerFactory - log logging.LeveledLogger - - net transport.Net - tcpMux TCPMux - udpMux UDPMux - udpMuxSrflx UniversalUDPMux - - interfaceFilter func(string) bool - ipFilter func(net.IP) bool - includeLoopback bool - - insecureSkipVerify bool - - proxyDialer proxy.Dialer -} - -type task struct { - fn func(context.Context, *Agent) - done chan struct{} -} - -// afterRun registers function to be run after the task. -func (a *Agent) afterRun(f func(context.Context)) { - a.muAfterRun.Lock() - a.afterRunFn = append(a.afterRunFn, f) - a.muAfterRun.Unlock() -} - -func (a *Agent) getAfterRunFn() []func(context.Context) { - a.muAfterRun.Lock() - defer a.muAfterRun.Unlock() - fns := a.afterRunFn - a.afterRunFn = nil - return fns -} - -func (a *Agent) ok() error { - select { - case <-a.done: - return a.getErr() - default: - } - return nil -} - -func (a *Agent) getErr() error { - if err := a.err.Load(); err != nil { - return err - } - return ErrClosed -} - -// Run task in serial. Blocking tasks must be cancelable by context. -func (a *Agent) run(ctx context.Context, t func(context.Context, *Agent)) error { - if err := a.ok(); err != nil { - return err - } - done := make(chan struct{}) - select { - case <-ctx.Done(): - return ctx.Err() - case a.chanTask <- task{t, done}: - <-done - return nil - } -} - -// taskLoop handles registered tasks and agent close. -func (a *Agent) taskLoop() { - after := func() { - for { - // Get and run func registered by afterRun(). - fns := a.getAfterRunFn() - if len(fns) == 0 { - break - } - for _, fn := range fns { - fn(a.context()) - } - } - } - defer func() { - a.deleteAllCandidates() - a.startedFn() - - if err := a.buf.Close(); err != nil { - a.log.Warnf("Failed to close buffer: %v", err) - } - - a.closeMulticastConn() - a.updateConnectionState(ConnectionStateClosed) - - after() - - close(a.chanState) - close(a.chanCandidate) - close(a.chanCandidatePair) - close(a.taskLoopDone) - }() - - for { - select { - case <-a.done: - return - case t := <-a.chanTask: - t.fn(a.context(), a) - close(t.done) - after() - } - } -} - -// NewAgent creates a new Agent -func NewAgent(config *AgentConfig) (*Agent, error) { //nolint:gocognit - var err error - if config.PortMax < config.PortMin { - return nil, ErrPort - } - - mDNSName := config.MulticastDNSHostName - if mDNSName == "" { - if mDNSName, err = generateMulticastDNSName(); err != nil { - return nil, err - } - } - - if !strings.HasSuffix(mDNSName, ".local") || len(strings.Split(mDNSName, ".")) != 2 { - return nil, ErrInvalidMulticastDNSHostName - } - - mDNSMode := config.MulticastDNSMode - if mDNSMode == 0 { - mDNSMode = MulticastDNSModeQueryOnly - } - - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - log := loggerFactory.NewLogger("ice") - - startedCtx, startedFn := context.WithCancel(context.Background()) - - a := &Agent{ - chanTask: make(chan task), - chanState: make(chan ConnectionState), - chanCandidate: make(chan Candidate), - chanCandidatePair: make(chan *CandidatePair), - tieBreaker: globalMathRandomGenerator.Uint64(), - lite: config.Lite, - gatheringState: GatheringStateNew, - connectionState: ConnectionStateNew, - localCandidates: make(map[NetworkType][]Candidate), - remoteCandidates: make(map[NetworkType][]Candidate), - urls: config.Urls, - networkTypes: config.NetworkTypes, - onConnected: make(chan struct{}), - buf: packetio.NewBuffer(), - done: make(chan struct{}), - taskLoopDone: make(chan struct{}), - startedCh: startedCtx.Done(), - startedFn: startedFn, - portMin: config.PortMin, - portMax: config.PortMax, - loggerFactory: loggerFactory, - log: log, - net: config.Net, - proxyDialer: config.ProxyDialer, - tcpMux: config.TCPMux, - udpMux: config.UDPMux, - udpMuxSrflx: config.UDPMuxSrflx, - - mDNSMode: mDNSMode, - mDNSName: mDNSName, - - gatherCandidateCancel: func() {}, - - forceCandidateContact: make(chan bool, 1), - - interfaceFilter: config.InterfaceFilter, - - ipFilter: config.IPFilter, - - insecureSkipVerify: config.InsecureSkipVerify, - - includeLoopback: config.IncludeLoopback, - } - - if a.net == nil { - a.net, err = stdnet.NewNet() - if err != nil { - return nil, fmt.Errorf("failed to create network: %w", err) - } - } else if _, isVirtual := a.net.(*vnet.Net); isVirtual { - a.log.Warn("Virtual network is enabled") - if a.mDNSMode != MulticastDNSModeDisabled { - a.log.Warn("Virtual network does not support mDNS yet") - } - } - - // Opportunistic mDNS: If we can't open the connection, that's ok: we - // can continue without it. - if a.mDNSConn, a.mDNSMode, err = createMulticastDNS(a.net, mDNSMode, mDNSName, log); err != nil { - log.Warnf("Failed to initialize mDNS %s: %v", mDNSName, err) - } - - config.initWithDefaults(a) - - // Make sure the buffer doesn't grow indefinitely. - // NOTE: We actually won't get anywhere close to this limit. - // SRTP will constantly read from the endpoint and drop packets if it's full. - a.buf.SetLimitSize(maxBufferSize) - - if a.lite && (len(a.candidateTypes) != 1 || a.candidateTypes[0] != CandidateTypeHost) { - a.closeMulticastConn() - return nil, ErrLiteUsingNonHostCandidates - } - - if config.Urls != nil && len(config.Urls) > 0 && !containsCandidateType(CandidateTypeServerReflexive, a.candidateTypes) && !containsCandidateType(CandidateTypeRelay, a.candidateTypes) { - a.closeMulticastConn() - return nil, ErrUselessUrlsProvided - } - - if err = config.initExtIPMapping(a); err != nil { - a.closeMulticastConn() - return nil, err - } - - go a.taskLoop() - - // CandidatePair and ConnectionState are usually changed at once. - // Blocking one by the other one causes deadlock. - // Hence, we call handlers from independent Goroutines. - go a.candidatePairRoutine() - go a.connectionStateRoutine() - go a.candidateRoutine() - - // Restart is also used to initialize the agent for the first time - if err := a.Restart(config.LocalUfrag, config.LocalPwd); err != nil { - a.closeMulticastConn() - _ = a.Close() - return nil, err - } - - return a, nil -} - -func (a *Agent) startConnectivityChecks(isControlling bool, remoteUfrag, remotePwd string) error { - a.muHaveStarted.Lock() - defer a.muHaveStarted.Unlock() - select { - case <-a.startedCh: - return ErrMultipleStart - default: - } - if err := a.SetRemoteCredentials(remoteUfrag, remotePwd); err != nil { //nolint:contextcheck - return err - } - - a.log.Debugf("Started agent: isControlling? %t, remoteUfrag: %q, remotePwd: %q", isControlling, remoteUfrag, remotePwd) - - return a.run(a.context(), func(ctx context.Context, agent *Agent) { - agent.isControlling = isControlling - agent.remoteUfrag = remoteUfrag - agent.remotePwd = remotePwd - - if isControlling { - a.selector = &controllingSelector{agent: a, log: a.log} - } else { - a.selector = &controlledSelector{agent: a, log: a.log} - } - - if a.lite { - a.selector = &liteSelector{pairCandidateSelector: a.selector} - } - - a.selector.Start() - a.startedFn() - - agent.updateConnectionState(ConnectionStateChecking) - - a.requestConnectivityCheck() - go a.connectivityChecks() //nolint:contextcheck - }) -} - -func (a *Agent) connectivityChecks() { - lastConnectionState := ConnectionState(0) - checkingDuration := time.Time{} - - contact := func() { - if err := a.run(a.context(), func(ctx context.Context, a *Agent) { - defer func() { - lastConnectionState = a.connectionState - }() - - switch a.connectionState { - case ConnectionStateFailed: - // The connection is currently failed so don't send any checks - // In the future it may be restarted though - return - case ConnectionStateChecking: - // We have just entered checking for the first time so update our checking timer - if lastConnectionState != a.connectionState { - checkingDuration = time.Now() - } - - // We have been in checking longer then Disconnect+Failed timeout, set the connection to Failed - if time.Since(checkingDuration) > a.disconnectedTimeout+a.failedTimeout { - a.updateConnectionState(ConnectionStateFailed) - return - } - default: - } - - a.selector.ContactCandidates() - }); err != nil { - a.log.Warnf("Failed to start connectivity checks: %v", err) - } - } - - for { - interval := defaultKeepaliveInterval - - updateInterval := func(x time.Duration) { - if x != 0 && (interval == 0 || interval > x) { - interval = x - } - } - - switch lastConnectionState { - case ConnectionStateNew, ConnectionStateChecking: // While connecting, check candidates more frequently - updateInterval(a.checkInterval) - case ConnectionStateConnected, ConnectionStateDisconnected: - updateInterval(a.keepaliveInterval) - default: - } - // Ensure we run our task loop as quickly as the minimum of our various configured timeouts - updateInterval(a.disconnectedTimeout) - updateInterval(a.failedTimeout) - - t := time.NewTimer(interval) - select { - case <-a.forceCandidateContact: - t.Stop() - contact() - case <-t.C: - contact() - case <-a.done: - t.Stop() - return - } - } -} - -func (a *Agent) updateConnectionState(newState ConnectionState) { - if a.connectionState != newState { - // Connection has gone to failed, release all gathered candidates - if newState == ConnectionStateFailed { - a.deleteAllCandidates() - } - - a.log.Infof("Setting new connection state: %s", newState) - a.connectionState = newState - - // Call handler after finishing current task since we may be holding the agent lock - // and the handler may also require it - a.afterRun(func(ctx context.Context) { - a.chanState <- newState - }) - } -} - -func (a *Agent) setSelectedPair(p *CandidatePair) { - if p == nil { - var nilPair *CandidatePair - a.selectedPair.Store(nilPair) - a.log.Tracef("Unset selected candidate pair") - return - } - - p.nominated = true - a.selectedPair.Store(p) - a.log.Tracef("Set selected candidate pair: %s", p) - - a.updateConnectionState(ConnectionStateConnected) - - // Notify when the selected pair changes - a.afterRun(func(ctx context.Context) { - select { - case a.chanCandidatePair <- p: - case <-ctx.Done(): - } - }) - - // Signal connected - a.onConnectedOnce.Do(func() { close(a.onConnected) }) -} - -func (a *Agent) pingAllCandidates() { - a.log.Trace("pinging all candidates") - - if len(a.checklist) == 0 { - a.log.Warn("Failed to ping without candidate pairs. Connection is not possible yet.") - } - - for _, p := range a.checklist { - if p.state == CandidatePairStateWaiting { - p.state = CandidatePairStateInProgress - } else if p.state != CandidatePairStateInProgress { - continue - } - - if p.bindingRequestCount > a.maxBindingRequests { - a.log.Tracef("max requests reached for pair %s, marking it as failed", p) - p.state = CandidatePairStateFailed - } else { - a.selector.PingCandidate(p.Local, p.Remote) - p.bindingRequestCount++ - } - } -} - -func (a *Agent) getBestAvailableCandidatePair() *CandidatePair { - var best *CandidatePair - for _, p := range a.checklist { - if p.state == CandidatePairStateFailed { - continue - } - - if best == nil { - best = p - } else if best.priority() < p.priority() { - best = p - } - } - return best -} - -func (a *Agent) getBestValidCandidatePair() *CandidatePair { - var best *CandidatePair - for _, p := range a.checklist { - if p.state != CandidatePairStateSucceeded { - continue - } - - if best == nil { - best = p - } else if best.priority() < p.priority() { - best = p - } - } - return best -} - -func (a *Agent) addPair(local, remote Candidate) *CandidatePair { - p := newCandidatePair(local, remote, a.isControlling) - a.checklist = append(a.checklist, p) - return p -} - -func (a *Agent) findPair(local, remote Candidate) *CandidatePair { - for _, p := range a.checklist { - if p.Local.Equal(local) && p.Remote.Equal(remote) { - return p - } - } - return nil -} - -// validateSelectedPair checks if the selected pair is (still) valid -// Note: the caller should hold the agent lock. -func (a *Agent) validateSelectedPair() bool { - selectedPair := a.getSelectedPair() - if selectedPair == nil { - return false - } - - disconnectedTime := time.Since(selectedPair.Remote.LastReceived()) - - // Only allow transitions to failed if a.failedTimeout is non-zero - totalTimeToFailure := a.failedTimeout - if totalTimeToFailure != 0 { - totalTimeToFailure += a.disconnectedTimeout - } - - switch { - case totalTimeToFailure != 0 && disconnectedTime > totalTimeToFailure: - a.updateConnectionState(ConnectionStateFailed) - case a.disconnectedTimeout != 0 && disconnectedTime > a.disconnectedTimeout: - a.updateConnectionState(ConnectionStateDisconnected) - default: - a.updateConnectionState(ConnectionStateConnected) - } - - return true -} - -// checkKeepalive sends STUN Binding Indications to the selected pair -// if no packet has been sent on that pair in the last keepaliveInterval -// Note: the caller should hold the agent lock. -func (a *Agent) checkKeepalive() { - selectedPair := a.getSelectedPair() - if selectedPair == nil { - return - } - - if (a.keepaliveInterval != 0) && - ((time.Since(selectedPair.Local.LastSent()) > a.keepaliveInterval) || - (time.Since(selectedPair.Remote.LastReceived()) > a.keepaliveInterval)) { - // We use binding request instead of indication to support refresh consent schemas - // see https://tools.ietf.org/html/rfc7675 - a.selector.PingCandidate(selectedPair.Local, selectedPair.Remote) - } -} - -// AddRemoteCandidate adds a new remote candidate -func (a *Agent) AddRemoteCandidate(c Candidate) error { - if c == nil { - return nil - } - - // Cannot check for network yet because it might not be applied - // when mDNS hostname is used. - if c.TCPType() == TCPTypeActive { - // TCP Candidates with TCP type active will probe server passive ones, so - // no need to do anything with them. - a.log.Infof("Ignoring remote candidate with tcpType active: %s", c) - return nil - } - - // If we have a mDNS Candidate lets fully resolve it before adding it locally - if c.Type() == CandidateTypeHost && strings.HasSuffix(c.Address(), ".local") { - if a.mDNSMode == MulticastDNSModeDisabled { - a.log.Warnf("Remote mDNS candidate added, but mDNS is disabled: (%s)", c.Address()) - return nil - } - - hostCandidate, ok := c.(*CandidateHost) - if !ok { - return ErrAddressParseFailed - } - - go a.resolveAndAddMulticastCandidate(hostCandidate) - return nil - } - - go func() { - if err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - agent.addRemoteCandidate(c) - }); err != nil { - a.log.Warnf("Failed to add remote candidate %s: %v", c.Address(), err) - return - } - }() - return nil -} - -func (a *Agent) resolveAndAddMulticastCandidate(c *CandidateHost) { - if a.mDNSConn == nil { - return - } - _, src, err := a.mDNSConn.Query(c.context(), c.Address()) - if err != nil { - a.log.Warnf("Failed to discover mDNS candidate %s: %v", c.Address(), err) - return - } - - ip, ipOk := parseMulticastAnswerAddr(src) - if !ipOk { - a.log.Warnf("Failed to discover mDNS candidate %s: failed to parse IP", c.Address()) - return - } - - if err = c.setIP(ip); err != nil { - a.log.Warnf("Failed to discover mDNS candidate %s: %v", c.Address(), err) - return - } - - if err = a.run(a.context(), func(ctx context.Context, agent *Agent) { - agent.addRemoteCandidate(c) - }); err != nil { - a.log.Warnf("Failed to add mDNS candidate %s: %v", c.Address(), err) - return - } -} - -func (a *Agent) requestConnectivityCheck() { - select { - case a.forceCandidateContact <- true: - default: - } -} - -// addRemoteCandidate assumes you are holding the lock (must be execute using a.run) -func (a *Agent) addRemoteCandidate(c Candidate) { - set := a.remoteCandidates[c.NetworkType()] - - for _, candidate := range set { - if candidate.Equal(c) { - return - } - } - - set = append(set, c) - a.remoteCandidates[c.NetworkType()] = set - - if localCandidates, ok := a.localCandidates[c.NetworkType()]; ok { - for _, localCandidate := range localCandidates { - a.addPair(localCandidate, c) - } - } - - a.requestConnectivityCheck() -} - -func (a *Agent) addCandidate(ctx context.Context, c Candidate, candidateConn net.PacketConn) error { - return a.run(ctx, func(ctx context.Context, agent *Agent) { - set := a.localCandidates[c.NetworkType()] - for _, candidate := range set { - if candidate.Equal(c) { - a.log.Debugf("Ignore duplicate candidate: %s", c.String()) - if err := c.close(); err != nil { - a.log.Warnf("Failed to close duplicate candidate: %v", err) - } - if err := candidateConn.Close(); err != nil { - a.log.Warnf("Failed to close duplicate candidate connection: %v", err) - } - return - } - } - - c.start(a, candidateConn, a.startedCh) - - set = append(set, c) - a.localCandidates[c.NetworkType()] = set - - if remoteCandidates, ok := a.remoteCandidates[c.NetworkType()]; ok { - for _, remoteCandidate := range remoteCandidates { - a.addPair(c, remoteCandidate) - } - } - - a.requestConnectivityCheck() - - a.chanCandidate <- c - }) -} - -// GetLocalCandidates returns the local candidates -func (a *Agent) GetLocalCandidates() ([]Candidate, error) { - var res []Candidate - - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - var candidates []Candidate - for _, set := range agent.localCandidates { - candidates = append(candidates, set...) - } - res = candidates - }) - if err != nil { - return nil, err - } - - return res, nil -} - -// GetLocalUserCredentials returns the local user credentials -func (a *Agent) GetLocalUserCredentials() (frag string, pwd string, err error) { - valSet := make(chan struct{}) - err = a.run(a.context(), func(ctx context.Context, agent *Agent) { - frag = agent.localUfrag - pwd = agent.localPwd - close(valSet) - }) - - if err == nil { - <-valSet - } - return -} - -// GetRemoteUserCredentials returns the remote user credentials -func (a *Agent) GetRemoteUserCredentials() (frag string, pwd string, err error) { - valSet := make(chan struct{}) - err = a.run(a.context(), func(ctx context.Context, agent *Agent) { - frag = agent.remoteUfrag - pwd = agent.remotePwd - close(valSet) - }) - - if err == nil { - <-valSet - } - return -} - -func (a *Agent) removeUfragFromMux() { - if a.tcpMux != nil { - a.tcpMux.RemoveConnByUfrag(a.localUfrag) - } - if a.udpMux != nil { - a.udpMux.RemoveConnByUfrag(a.localUfrag) - } - if a.udpMuxSrflx != nil { - a.udpMuxSrflx.RemoveConnByUfrag(a.localUfrag) - } -} - -// Close cleans up the Agent -func (a *Agent) Close() error { - if err := a.ok(); err != nil { - return err - } - - a.afterRun(func(context.Context) { - a.gatherCandidateCancel() - if a.gatherCandidateDone != nil { - <-a.gatherCandidateDone - } - }) - a.err.Store(ErrClosed) - - a.removeUfragFromMux() - - close(a.done) - <-a.taskLoopDone - return nil -} - -// Remove all candidates. This closes any listening sockets -// and removes both the local and remote candidate lists. -// -// This is used for restarts, failures and on close -func (a *Agent) deleteAllCandidates() { - for net, cs := range a.localCandidates { - for _, c := range cs { - if err := c.close(); err != nil { - a.log.Warnf("Failed to close candidate %s: %v", c, err) - } - } - delete(a.localCandidates, net) - } - for net, cs := range a.remoteCandidates { - for _, c := range cs { - if err := c.close(); err != nil { - a.log.Warnf("Failed to close candidate %s: %v", c, err) - } - } - delete(a.remoteCandidates, net) - } -} - -func (a *Agent) findRemoteCandidate(networkType NetworkType, addr net.Addr) Candidate { - ip, port, _, ok := parseAddr(addr) - if !ok { - a.log.Warnf("Failed to parse address: %s", addr) - return nil - } - - set := a.remoteCandidates[networkType] - for _, c := range set { - if c.Address() == ip.String() && c.Port() == port { - return c - } - } - return nil -} - -func (a *Agent) sendBindingRequest(m *stun.Message, local, remote Candidate) { - a.log.Tracef("ping STUN from %s to %s", local.String(), remote.String()) - - a.invalidatePendingBindingRequests(time.Now()) - a.pendingBindingRequests = append(a.pendingBindingRequests, bindingRequest{ - timestamp: time.Now(), - transactionID: m.TransactionID, - destination: remote.addr(), - isUseCandidate: m.Contains(stun.AttrUseCandidate), - }) - - a.sendSTUN(m, local, remote) -} - -func (a *Agent) sendBindingSuccess(m *stun.Message, local, remote Candidate) { - base := remote - - ip, port, _, ok := parseAddr(base.addr()) - if !ok { - a.log.Warnf("Failed to parse address: %s", base.addr()) - return - } - - if out, err := stun.Build(m, stun.BindingSuccess, - &stun.XORMappedAddress{ - IP: ip, - Port: port, - }, - stun.NewShortTermIntegrity(a.localPwd), - stun.Fingerprint, - ); err != nil { - a.log.Warnf("Failed to handle inbound ICE from: %s to: %s error: %s", local, remote, err) - } else { - a.sendSTUN(out, local, remote) - } -} - -// Removes pending binding requests that are over maxBindingRequestTimeout old -// -// Let HTO be the transaction timeout, which SHOULD be 2*RTT if -// RTT is known or 500 ms otherwise. -// https://tools.ietf.org/html/rfc8445#appendix-B.1 -func (a *Agent) invalidatePendingBindingRequests(filterTime time.Time) { - initialSize := len(a.pendingBindingRequests) - - temp := a.pendingBindingRequests[:0] - for _, bindingRequest := range a.pendingBindingRequests { - if filterTime.Sub(bindingRequest.timestamp) < maxBindingRequestTimeout { - temp = append(temp, bindingRequest) - } - } - - a.pendingBindingRequests = temp - if bindRequestsRemoved := initialSize - len(a.pendingBindingRequests); bindRequestsRemoved > 0 { - a.log.Tracef("Discarded %d binding requests because they expired", bindRequestsRemoved) - } -} - -// Assert that the passed TransactionID is in our pendingBindingRequests and returns the destination -// If the bindingRequest was valid remove it from our pending cache -func (a *Agent) handleInboundBindingSuccess(id [stun.TransactionIDSize]byte) (bool, *bindingRequest) { - a.invalidatePendingBindingRequests(time.Now()) - for i := range a.pendingBindingRequests { - if a.pendingBindingRequests[i].transactionID == id { - validBindingRequest := a.pendingBindingRequests[i] - a.pendingBindingRequests = append(a.pendingBindingRequests[:i], a.pendingBindingRequests[i+1:]...) - return true, &validBindingRequest - } - } - return false, nil -} - -// handleInbound processes STUN traffic from a remote candidate -func (a *Agent) handleInbound(m *stun.Message, local Candidate, remote net.Addr) { //nolint:gocognit - var err error - if m == nil || local == nil { - return - } - - if m.Type.Method != stun.MethodBinding || - !(m.Type.Class == stun.ClassSuccessResponse || - m.Type.Class == stun.ClassRequest || - m.Type.Class == stun.ClassIndication) { - a.log.Tracef("unhandled STUN from %s to %s class(%s) method(%s)", remote, local, m.Type.Class, m.Type.Method) - return - } - - if a.isControlling { - if m.Contains(stun.AttrICEControlling) { - a.log.Debug("Inbound STUN message: isControlling && a.isControlling == true") - return - } else if m.Contains(stun.AttrUseCandidate) { - a.log.Debug("Inbound STUN message: useCandidate && a.isControlling == true") - return - } - } else { - if m.Contains(stun.AttrICEControlled) { - a.log.Debug("Inbound STUN message: isControlled && a.isControlling == false") - return - } - } - - remoteCandidate := a.findRemoteCandidate(local.NetworkType(), remote) - if m.Type.Class == stun.ClassSuccessResponse { - if err = stun.MessageIntegrity([]byte(a.remotePwd)).Check(m); err != nil { - a.log.Warnf("Discard message from (%s), %v", remote, err) - return - } - - if remoteCandidate == nil { - a.log.Warnf("Discard success message from (%s), no such remote", remote) - return - } - - a.selector.HandleSuccessResponse(m, local, remoteCandidate, remote) - } else if m.Type.Class == stun.ClassRequest { - if err = stunx.AssertUsername(m, a.localUfrag+":"+a.remoteUfrag); err != nil { - a.log.Warnf("Discard message from (%s), %v", remote, err) - return - } else if err = stun.MessageIntegrity([]byte(a.localPwd)).Check(m); err != nil { - a.log.Warnf("Discard message from (%s), %v", remote, err) - return - } - - if remoteCandidate == nil { - ip, port, networkType, ok := parseAddr(remote) - if !ok { - a.log.Errorf("Failed to create parse remote net.Addr when creating remote prflx candidate") - return - } - - prflxCandidateConfig := CandidatePeerReflexiveConfig{ - Network: networkType.String(), - Address: ip.String(), - Port: port, - Component: local.Component(), - RelAddr: "", - RelPort: 0, - } - - prflxCandidate, err := NewCandidatePeerReflexive(&prflxCandidateConfig) - if err != nil { - a.log.Errorf("Failed to create new remote prflx candidate (%s)", err) - return - } - remoteCandidate = prflxCandidate - - a.log.Debugf("Adding a new peer-reflexive candidate: %s ", remote) - a.addRemoteCandidate(remoteCandidate) - } - - a.log.Tracef("inbound STUN (Request) from %s to %s", remote.String(), local.String()) - - a.selector.HandleBindingRequest(m, local, remoteCandidate) - } - - if remoteCandidate != nil { - remoteCandidate.seen(false) - } -} - -// validateNonSTUNTraffic processes non STUN traffic from a remote candidate, -// and returns true if it is an actual remote candidate -func (a *Agent) validateNonSTUNTraffic(local Candidate, remote net.Addr) (Candidate, bool) { - var remoteCandidate Candidate - if err := a.run(local.context(), func(ctx context.Context, agent *Agent) { - remoteCandidate = a.findRemoteCandidate(local.NetworkType(), remote) - if remoteCandidate != nil { - remoteCandidate.seen(false) - } - }); err != nil { - a.log.Warnf("Failed to validate remote candidate: %v", err) - } - - return remoteCandidate, remoteCandidate != nil -} - -// GetSelectedCandidatePair returns the selected pair or nil if there is none -func (a *Agent) GetSelectedCandidatePair() (*CandidatePair, error) { - selectedPair := a.getSelectedPair() - if selectedPair == nil { - return nil, nil //nolint:nilnil - } - - local, err := selectedPair.Local.copy() - if err != nil { - return nil, err - } - - remote, err := selectedPair.Remote.copy() - if err != nil { - return nil, err - } - - return &CandidatePair{Local: local, Remote: remote}, nil -} - -func (a *Agent) getSelectedPair() *CandidatePair { - if selectedPair, ok := a.selectedPair.Load().(*CandidatePair); ok { - return selectedPair - } - - return nil -} - -func (a *Agent) closeMulticastConn() { - if a.mDNSConn != nil { - if err := a.mDNSConn.Close(); err != nil { - a.log.Warnf("Failed to close mDNS Conn: %v", err) - } - } -} - -// SetRemoteCredentials sets the credentials of the remote agent -func (a *Agent) SetRemoteCredentials(remoteUfrag, remotePwd string) error { - switch { - case remoteUfrag == "": - return ErrRemoteUfragEmpty - case remotePwd == "": - return ErrRemotePwdEmpty - } - - return a.run(a.context(), func(ctx context.Context, agent *Agent) { - agent.remoteUfrag = remoteUfrag - agent.remotePwd = remotePwd - }) -} - -// Restart restarts the ICE Agent with the provided ufrag/pwd -// If no ufrag/pwd is provided the Agent will generate one itself -// -// If there is a gatherer routine currently running, Restart will -// cancel it. -// After a Restart, the user must then call GatherCandidates explicitly -// to start generating new ones. -func (a *Agent) Restart(ufrag, pwd string) error { - if ufrag == "" { - var err error - ufrag, err = generateUFrag() - if err != nil { - return err - } - } - if pwd == "" { - var err error - pwd, err = generatePwd() - if err != nil { - return err - } - } - - if len([]rune(ufrag))*8 < 24 { - return ErrLocalUfragInsufficientBits - } - if len([]rune(pwd))*8 < 128 { - return ErrLocalPwdInsufficientBits - } - - var err error - if runErr := a.run(a.context(), func(ctx context.Context, agent *Agent) { - if agent.gatheringState == GatheringStateGathering { - agent.gatherCandidateCancel() - } - - // Clear all agent needed to take back to fresh state - a.removeUfragFromMux() - agent.localUfrag = ufrag - agent.localPwd = pwd - agent.remoteUfrag = "" - agent.remotePwd = "" - a.gatheringState = GatheringStateNew - a.checklist = make([]*CandidatePair, 0) - a.pendingBindingRequests = make([]bindingRequest, 0) - a.setSelectedPair(nil) - a.deleteAllCandidates() - if a.selector != nil { - a.selector.Start() - } - - // Restart is used by NewAgent. Accept/Connect should be used to move to checking - // for new Agents - if a.connectionState != ConnectionStateNew { - a.updateConnectionState(ConnectionStateChecking) - } - }); runErr != nil { - return runErr - } - return err -} - -func (a *Agent) setGatheringState(newState GatheringState) error { - done := make(chan struct{}) - if err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - if a.gatheringState != newState && newState == GatheringStateComplete { - a.chanCandidate <- nil - } - - a.gatheringState = newState - close(done) - }); err != nil { - return err - } - - <-done - return nil -} diff --git a/vendor/github.com/pion/ice/v2/agent_config.go b/vendor/github.com/pion/ice/v2/agent_config.go deleted file mode 100644 index f5897cd4..00000000 --- a/vendor/github.com/pion/ice/v2/agent_config.go +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" - "time" - - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "golang.org/x/net/proxy" -) - -const ( - // defaultCheckInterval is the interval at which the agent performs candidate checks in the connecting phase - defaultCheckInterval = 200 * time.Millisecond - - // keepaliveInterval used to keep candidates alive - defaultKeepaliveInterval = 2 * time.Second - - // defaultDisconnectedTimeout is the default time till an Agent transitions disconnected - defaultDisconnectedTimeout = 5 * time.Second - - // defaultFailedTimeout is the default time till an Agent transitions to failed after disconnected - defaultFailedTimeout = 25 * time.Second - - // defaultHostAcceptanceMinWait is the wait time before nominating a host candidate - defaultHostAcceptanceMinWait = 0 - - // defaultSrflxAcceptanceMinWait is the wait time before nominating a srflx candidate - defaultSrflxAcceptanceMinWait = 500 * time.Millisecond - - // defaultPrflxAcceptanceMinWait is the wait time before nominating a prflx candidate - defaultPrflxAcceptanceMinWait = 1000 * time.Millisecond - - // defaultRelayAcceptanceMinWait is the wait time before nominating a relay candidate - defaultRelayAcceptanceMinWait = 2000 * time.Millisecond - - // defaultMaxBindingRequests is the maximum number of binding requests before considering a pair failed - defaultMaxBindingRequests = 7 - - // maxBufferSize is the number of bytes that can be buffered before we start to error - maxBufferSize = 1000 * 1000 // 1MB - - // maxBindingRequestTimeout is the wait time before binding requests can be deleted - maxBindingRequestTimeout = 4000 * time.Millisecond -) - -func defaultCandidateTypes() []CandidateType { - return []CandidateType{CandidateTypeHost, CandidateTypeServerReflexive, CandidateTypeRelay} -} - -// AgentConfig collects the arguments to ice.Agent construction into -// a single structure, for future-proofness of the interface -type AgentConfig struct { - Urls []*stun.URI - - // PortMin and PortMax are optional. Leave them 0 for the default UDP port allocation strategy. - PortMin uint16 - PortMax uint16 - - // LocalUfrag and LocalPwd values used to perform connectivity - // checks. The values MUST be unguessable, with at least 128 bits of - // random number generator output used to generate the password, and - // at least 24 bits of output to generate the username fragment. - LocalUfrag string - LocalPwd string - - // MulticastDNSMode controls mDNS behavior for the ICE agent - MulticastDNSMode MulticastDNSMode - - // MulticastDNSHostName controls the hostname for this agent. If none is specified a random one will be generated - MulticastDNSHostName string - - // DisconnectedTimeout defaults to 5 seconds when this property is nil. - // If the duration is 0, the ICE Agent will never go to disconnected - DisconnectedTimeout *time.Duration - - // FailedTimeout defaults to 25 seconds when this property is nil. - // If the duration is 0, we will never go to failed. - FailedTimeout *time.Duration - - // KeepaliveInterval determines how often should we send ICE - // keepalives (should be less then connectiontimeout above) - // when this is nil, it defaults to 10 seconds. - // A keepalive interval of 0 means we never send keepalive packets - KeepaliveInterval *time.Duration - - // CheckInterval controls how often our task loop runs when in the - // connecting state. - CheckInterval *time.Duration - - // NetworkTypes is an optional configuration for disabling or enabling - // support for specific network types. - NetworkTypes []NetworkType - - // CandidateTypes is an optional configuration for disabling or enabling - // support for specific candidate types. - CandidateTypes []CandidateType - - LoggerFactory logging.LoggerFactory - - // MaxBindingRequests is the max amount of binding requests the agent will send - // over a candidate pair for validation or nomination, if after MaxBindingRequests - // the candidate is yet to answer a binding request or a nomination we set the pair as failed - MaxBindingRequests *uint16 - - // Lite agents do not perform connectivity check and only provide host candidates. - Lite bool - - // NAT1To1IPCandidateType is used along with NAT1To1IPs to specify which candidate type - // the 1:1 NAT IP addresses should be mapped to. - // If unspecified or CandidateTypeHost, NAT1To1IPs are used to replace host candidate IPs. - // If CandidateTypeServerReflexive, it will insert a srflx candidate (as if it was derived - // from a STUN server) with its port number being the one for the actual host candidate. - // Other values will result in an error. - NAT1To1IPCandidateType CandidateType - - // NAT1To1IPs contains a list of public IP addresses that are to be used as a host - // candidate or srflx candidate. This is used typically for servers that are behind - // 1:1 D-NAT (e.g. AWS EC2 instances) and to eliminate the need of server reflexive - // candidate gathering. - NAT1To1IPs []string - - // HostAcceptanceMinWait specify a minimum wait time before selecting host candidates - HostAcceptanceMinWait *time.Duration - // HostAcceptanceMinWait specify a minimum wait time before selecting srflx candidates - SrflxAcceptanceMinWait *time.Duration - // HostAcceptanceMinWait specify a minimum wait time before selecting prflx candidates - PrflxAcceptanceMinWait *time.Duration - // HostAcceptanceMinWait specify a minimum wait time before selecting relay candidates - RelayAcceptanceMinWait *time.Duration - - // Net is the our abstracted network interface for internal development purpose only - // (see https://github.com/pion/transport) - Net transport.Net - - // InterfaceFilter is a function that you can use in order to whitelist or blacklist - // the interfaces which are used to gather ICE candidates. - InterfaceFilter func(string) bool - - // IPFilter is a function that you can use in order to whitelist or blacklist - // the ips which are used to gather ICE candidates. - IPFilter func(net.IP) bool - - // InsecureSkipVerify controls if self-signed certificates are accepted when connecting - // to TURN servers via TLS or DTLS - InsecureSkipVerify bool - - // TCPMux will be used for multiplexing incoming TCP connections for ICE TCP. - // Currently only passive candidates are supported. This functionality is - // experimental and the API might change in the future. - TCPMux TCPMux - - // UDPMux is used for multiplexing multiple incoming UDP connections on a single port - // when this is set, the agent ignores PortMin and PortMax configurations and will - // defer to UDPMux for incoming connections - UDPMux UDPMux - - // UDPMuxSrflx is used for multiplexing multiple incoming UDP connections of server reflexive candidates - // on a single port when this is set, the agent ignores PortMin and PortMax configurations and will - // defer to UDPMuxSrflx for incoming connections - // It embeds UDPMux to do the actual connection multiplexing - UDPMuxSrflx UniversalUDPMux - - // Proxy Dialer is a dialer that should be implemented by the user based on golang.org/x/net/proxy - // dial interface in order to support corporate proxies - ProxyDialer proxy.Dialer - - // Deprecated: AcceptAggressiveNomination always enabled. - AcceptAggressiveNomination bool - - // Include loopback addresses in the candidate list. - IncludeLoopback bool -} - -// initWithDefaults populates an agent and falls back to defaults if fields are unset -func (config *AgentConfig) initWithDefaults(a *Agent) { - if config.MaxBindingRequests == nil { - a.maxBindingRequests = defaultMaxBindingRequests - } else { - a.maxBindingRequests = *config.MaxBindingRequests - } - - if config.HostAcceptanceMinWait == nil { - a.hostAcceptanceMinWait = defaultHostAcceptanceMinWait - } else { - a.hostAcceptanceMinWait = *config.HostAcceptanceMinWait - } - - if config.SrflxAcceptanceMinWait == nil { - a.srflxAcceptanceMinWait = defaultSrflxAcceptanceMinWait - } else { - a.srflxAcceptanceMinWait = *config.SrflxAcceptanceMinWait - } - - if config.PrflxAcceptanceMinWait == nil { - a.prflxAcceptanceMinWait = defaultPrflxAcceptanceMinWait - } else { - a.prflxAcceptanceMinWait = *config.PrflxAcceptanceMinWait - } - - if config.RelayAcceptanceMinWait == nil { - a.relayAcceptanceMinWait = defaultRelayAcceptanceMinWait - } else { - a.relayAcceptanceMinWait = *config.RelayAcceptanceMinWait - } - - if config.DisconnectedTimeout == nil { - a.disconnectedTimeout = defaultDisconnectedTimeout - } else { - a.disconnectedTimeout = *config.DisconnectedTimeout - } - - if config.FailedTimeout == nil { - a.failedTimeout = defaultFailedTimeout - } else { - a.failedTimeout = *config.FailedTimeout - } - - if config.KeepaliveInterval == nil { - a.keepaliveInterval = defaultKeepaliveInterval - } else { - a.keepaliveInterval = *config.KeepaliveInterval - } - - if config.CheckInterval == nil { - a.checkInterval = defaultCheckInterval - } else { - a.checkInterval = *config.CheckInterval - } - - if config.CandidateTypes == nil || len(config.CandidateTypes) == 0 { - a.candidateTypes = defaultCandidateTypes() - } else { - a.candidateTypes = config.CandidateTypes - } -} - -func (config *AgentConfig) initExtIPMapping(a *Agent) error { - var err error - a.extIPMapper, err = newExternalIPMapper(config.NAT1To1IPCandidateType, config.NAT1To1IPs) - if err != nil { - return err - } - if a.extIPMapper == nil { - return nil // This may happen when config.NAT1To1IPs is an empty array - } - if a.extIPMapper.candidateType == CandidateTypeHost { - if a.mDNSMode == MulticastDNSModeQueryAndGather { - return ErrMulticastDNSWithNAT1To1IPMapping - } - candiHostEnabled := false - for _, candiType := range a.candidateTypes { - if candiType == CandidateTypeHost { - candiHostEnabled = true - break - } - } - if !candiHostEnabled { - return ErrIneffectiveNAT1To1IPMappingHost - } - } else if a.extIPMapper.candidateType == CandidateTypeServerReflexive { - candiSrflxEnabled := false - for _, candiType := range a.candidateTypes { - if candiType == CandidateTypeServerReflexive { - candiSrflxEnabled = true - break - } - } - if !candiSrflxEnabled { - return ErrIneffectiveNAT1To1IPMappingSrflx - } - } - return nil -} diff --git a/vendor/github.com/pion/ice/v2/agent_handlers.go b/vendor/github.com/pion/ice/v2/agent_handlers.go deleted file mode 100644 index c5a5ec03..00000000 --- a/vendor/github.com/pion/ice/v2/agent_handlers.go +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -// OnConnectionStateChange sets a handler that is fired when the connection state changes -func (a *Agent) OnConnectionStateChange(f func(ConnectionState)) error { - a.onConnectionStateChangeHdlr.Store(f) - return nil -} - -// OnSelectedCandidatePairChange sets a handler that is fired when the final candidate -// pair is selected -func (a *Agent) OnSelectedCandidatePairChange(f func(Candidate, Candidate)) error { - a.onSelectedCandidatePairChangeHdlr.Store(f) - return nil -} - -// OnCandidate sets a handler that is fired when new candidates gathered. When -// the gathering process complete the last candidate is nil. -func (a *Agent) OnCandidate(f func(Candidate)) error { - a.onCandidateHdlr.Store(f) - return nil -} - -func (a *Agent) onSelectedCandidatePairChange(p *CandidatePair) { - if h, ok := a.onSelectedCandidatePairChangeHdlr.Load().(func(Candidate, Candidate)); ok { - h(p.Local, p.Remote) - } -} - -func (a *Agent) onCandidate(c Candidate) { - if onCandidateHdlr, ok := a.onCandidateHdlr.Load().(func(Candidate)); ok { - onCandidateHdlr(c) - } -} - -func (a *Agent) onConnectionStateChange(s ConnectionState) { - if hdlr, ok := a.onConnectionStateChangeHdlr.Load().(func(ConnectionState)); ok { - hdlr(s) - } -} - -func (a *Agent) candidatePairRoutine() { - for p := range a.chanCandidatePair { - a.onSelectedCandidatePairChange(p) - } -} - -func (a *Agent) connectionStateRoutine() { - for s := range a.chanState { - go a.onConnectionStateChange(s) - } -} - -func (a *Agent) candidateRoutine() { - for c := range a.chanCandidate { - a.onCandidate(c) - } -} diff --git a/vendor/github.com/pion/ice/v2/agent_stats.go b/vendor/github.com/pion/ice/v2/agent_stats.go deleted file mode 100644 index b9ad7187..00000000 --- a/vendor/github.com/pion/ice/v2/agent_stats.go +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "context" - "time" -) - -// GetCandidatePairsStats returns a list of candidate pair stats -func (a *Agent) GetCandidatePairsStats() []CandidatePairStats { - var res []CandidatePairStats - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - result := make([]CandidatePairStats, 0, len(agent.checklist)) - for _, cp := range agent.checklist { - stat := CandidatePairStats{ - Timestamp: time.Now(), - LocalCandidateID: cp.Local.ID(), - RemoteCandidateID: cp.Remote.ID(), - State: cp.state, - Nominated: cp.nominated, - // PacketsSent uint32 - // PacketsReceived uint32 - // BytesSent uint64 - // BytesReceived uint64 - // LastPacketSentTimestamp time.Time - // LastPacketReceivedTimestamp time.Time - // FirstRequestTimestamp time.Time - // LastRequestTimestamp time.Time - // LastResponseTimestamp time.Time - // TotalRoundTripTime float64 - // CurrentRoundTripTime float64 - // AvailableOutgoingBitrate float64 - // AvailableIncomingBitrate float64 - // CircuitBreakerTriggerCount uint32 - // RequestsReceived uint64 - // RequestsSent uint64 - // ResponsesReceived uint64 - // ResponsesSent uint64 - // RetransmissionsReceived uint64 - // RetransmissionsSent uint64 - // ConsentRequestsSent uint64 - // ConsentExpiredTimestamp time.Time - } - result = append(result, stat) - } - res = result - }) - if err != nil { - a.log.Errorf("Failed to get candidate pairs stats: %v", err) - return []CandidatePairStats{} - } - return res -} - -// GetLocalCandidatesStats returns a list of local candidates stats -func (a *Agent) GetLocalCandidatesStats() []CandidateStats { - var res []CandidateStats - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - result := make([]CandidateStats, 0, len(agent.localCandidates)) - for networkType, localCandidates := range agent.localCandidates { - for _, c := range localCandidates { - relayProtocol := "" - if c.Type() == CandidateTypeRelay { - if cRelay, ok := c.(*CandidateRelay); ok { - relayProtocol = cRelay.RelayProtocol() - } - } - stat := CandidateStats{ - Timestamp: time.Now(), - ID: c.ID(), - NetworkType: networkType, - IP: c.Address(), - Port: c.Port(), - CandidateType: c.Type(), - Priority: c.Priority(), - // URL string - RelayProtocol: relayProtocol, - // Deleted bool - } - result = append(result, stat) - } - } - res = result - }) - if err != nil { - a.log.Errorf("Failed to get candidate pair stats: %v", err) - return []CandidateStats{} - } - return res -} - -// GetRemoteCandidatesStats returns a list of remote candidates stats -func (a *Agent) GetRemoteCandidatesStats() []CandidateStats { - var res []CandidateStats - err := a.run(a.context(), func(ctx context.Context, agent *Agent) { - result := make([]CandidateStats, 0, len(agent.remoteCandidates)) - for networkType, remoteCandidates := range agent.remoteCandidates { - for _, c := range remoteCandidates { - stat := CandidateStats{ - Timestamp: time.Now(), - ID: c.ID(), - NetworkType: networkType, - IP: c.Address(), - Port: c.Port(), - CandidateType: c.Type(), - Priority: c.Priority(), - // URL string - RelayProtocol: "", - } - result = append(result, stat) - } - } - res = result - }) - if err != nil { - a.log.Errorf("Failed to get candidate pair stats: %v", err) - return []CandidateStats{} - } - return res -} diff --git a/vendor/github.com/pion/ice/v2/candidate.go b/vendor/github.com/pion/ice/v2/candidate.go deleted file mode 100644 index 92a00768..00000000 --- a/vendor/github.com/pion/ice/v2/candidate.go +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "context" - "net" - "time" -) - -const ( - receiveMTU = 8192 - defaultLocalPreference = 65535 - - // ComponentRTP indicates that the candidate is used for RTP - ComponentRTP uint16 = 1 - // ComponentRTCP indicates that the candidate is used for RTCP - ComponentRTCP -) - -// Candidate represents an ICE candidate -type Candidate interface { - // An arbitrary string used in the freezing algorithm to - // group similar candidates. It is the same for two candidates that - // have the same type, base IP address, protocol (UDP, TCP, etc.), - // and STUN or TURN server. - Foundation() string - - // ID is a unique identifier for just this candidate - // Unlike the foundation this is different for each candidate - ID() string - - // A component is a piece of a data stream. - // An example is one for RTP, and one for RTCP - Component() uint16 - SetComponent(uint16) - - // The last time this candidate received traffic - LastReceived() time.Time - - // The last time this candidate sent traffic - LastSent() time.Time - - NetworkType() NetworkType - Address() string - Port() int - - Priority() uint32 - - // A transport address related to a - // candidate, which is useful for diagnostics and other purposes - RelatedAddress() *CandidateRelatedAddress - - String() string - Type() CandidateType - TCPType() TCPType - - Equal(other Candidate) bool - - Marshal() string - - addr() net.Addr - agent() *Agent - context() context.Context - - close() error - copy() (Candidate, error) - seen(outbound bool) - start(a *Agent, conn net.PacketConn, initializedCh <-chan struct{}) - writeTo(raw []byte, dst Candidate) (int, error) -} diff --git a/vendor/github.com/pion/ice/v2/candidate_base.go b/vendor/github.com/pion/ice/v2/candidate_base.go deleted file mode 100644 index 8e551d8f..00000000 --- a/vendor/github.com/pion/ice/v2/candidate_base.go +++ /dev/null @@ -1,543 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "context" - "errors" - "fmt" - "hash/crc32" - "io" - "net" - "strconv" - "strings" - "sync/atomic" - "time" - - "github.com/pion/stun" -) - -type candidateBase struct { - id string - networkType NetworkType - candidateType CandidateType - - component uint16 - address string - port int - relatedAddress *CandidateRelatedAddress - tcpType TCPType - - resolvedAddr net.Addr - - lastSent atomic.Value - lastReceived atomic.Value - conn net.PacketConn - - currAgent *Agent - closeCh chan struct{} - closedCh chan struct{} - - foundationOverride string - priorityOverride uint32 - - remoteCandidateCaches map[AddrPort]Candidate -} - -// Done implements context.Context -func (c *candidateBase) Done() <-chan struct{} { - return c.closeCh -} - -// Err implements context.Context -func (c *candidateBase) Err() error { - select { - case <-c.closedCh: - return ErrRunCanceled - default: - return nil - } -} - -// Deadline implements context.Context -func (c *candidateBase) Deadline() (deadline time.Time, ok bool) { - return time.Time{}, false -} - -// Value implements context.Context -func (c *candidateBase) Value(interface{}) interface{} { - return nil -} - -// ID returns Candidate ID -func (c *candidateBase) ID() string { - return c.id -} - -func (c *candidateBase) Foundation() string { - if c.foundationOverride != "" { - return c.foundationOverride - } - - return fmt.Sprintf("%d", crc32.ChecksumIEEE([]byte(c.Type().String()+c.address+c.networkType.String()))) -} - -// Address returns Candidate Address -func (c *candidateBase) Address() string { - return c.address -} - -// Port returns Candidate Port -func (c *candidateBase) Port() int { - return c.port -} - -// Type returns candidate type -func (c *candidateBase) Type() CandidateType { - return c.candidateType -} - -// NetworkType returns candidate NetworkType -func (c *candidateBase) NetworkType() NetworkType { - return c.networkType -} - -// Component returns candidate component -func (c *candidateBase) Component() uint16 { - return c.component -} - -func (c *candidateBase) SetComponent(component uint16) { - c.component = component -} - -// LocalPreference returns the local preference for this candidate -func (c *candidateBase) LocalPreference() uint16 { - if c.NetworkType().IsTCP() { - // RFC 6544, section 4.2 - // - // In Section 4.1.2.1 of [RFC5245], a recommended formula for UDP ICE - // candidate prioritization is defined. For TCP candidates, the same - // formula and candidate type preferences SHOULD be used, and the - // RECOMMENDED type preferences for the new candidate types defined in - // this document (see Section 5) are 105 for NAT-assisted candidates and - // 75 for UDP-tunneled candidates. - // - // (...) - // - // With TCP candidates, the local preference part of the recommended - // priority formula is updated to also include the directionality - // (active, passive, or simultaneous-open) of the TCP connection. The - // RECOMMENDED local preference is then defined as: - // - // local preference = (2^13) * direction-pref + other-pref - // - // The direction-pref MUST be between 0 and 7 (both inclusive), with 7 - // being the most preferred. The other-pref MUST be between 0 and 8191 - // (both inclusive), with 8191 being the most preferred. It is - // RECOMMENDED that the host, UDP-tunneled, and relayed TCP candidates - // have the direction-pref assigned as follows: 6 for active, 4 for - // passive, and 2 for S-O. For the NAT-assisted and server reflexive - // candidates, the RECOMMENDED values are: 6 for S-O, 4 for active, and - // 2 for passive. - // - // (...) - // - // If any two candidates have the same type-preference and direction- - // pref, they MUST have a unique other-pref. With this specification, - // this usually only happens with multi-homed hosts, in which case - // other-pref is the preference for the particular IP address from which - // the candidate was obtained. When there is only a single IP address, - // this value SHOULD be set to the maximum allowed value (8191). - var otherPref uint16 = 8191 - - directionPref := func() uint16 { - switch c.Type() { - case CandidateTypeHost, CandidateTypeRelay: - switch c.tcpType { - case TCPTypeActive: - return 6 - case TCPTypePassive: - return 4 - case TCPTypeSimultaneousOpen: - return 2 - case TCPTypeUnspecified: - return 0 - } - case CandidateTypePeerReflexive, CandidateTypeServerReflexive: - switch c.tcpType { - case TCPTypeSimultaneousOpen: - return 6 - case TCPTypeActive: - return 4 - case TCPTypePassive: - return 2 - case TCPTypeUnspecified: - return 0 - } - case CandidateTypeUnspecified: - return 0 - } - return 0 - }() - - return (1<<13)*directionPref + otherPref - } - - return defaultLocalPreference -} - -// RelatedAddress returns *CandidateRelatedAddress -func (c *candidateBase) RelatedAddress() *CandidateRelatedAddress { - return c.relatedAddress -} - -func (c *candidateBase) TCPType() TCPType { - return c.tcpType -} - -// start runs the candidate using the provided connection -func (c *candidateBase) start(a *Agent, conn net.PacketConn, initializedCh <-chan struct{}) { - if c.conn != nil { - c.agent().log.Warn("Can't start already started candidateBase") - return - } - c.currAgent = a - c.conn = conn - c.closeCh = make(chan struct{}) - c.closedCh = make(chan struct{}) - - go c.recvLoop(initializedCh) -} - -func (c *candidateBase) recvLoop(initializedCh <-chan struct{}) { - a := c.agent() - - defer close(c.closedCh) - - select { - case <-initializedCh: - case <-c.closeCh: - return - } - - buf := make([]byte, receiveMTU) - for { - n, srcAddr, err := c.conn.ReadFrom(buf) - if err != nil { - if !(errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed)) { - a.log.Warnf("Failed to read from candidate %s: %v", c, err) - } - return - } - - c.handleInboundPacket(buf[:n], srcAddr) - } -} - -func (c *candidateBase) validateSTUNTrafficCache(addr net.Addr) bool { - if candidate, ok := c.remoteCandidateCaches[toAddrPort(addr)]; ok { - candidate.seen(false) - return true - } - return false -} - -func (c *candidateBase) addRemoteCandidateCache(candidate Candidate, srcAddr net.Addr) { - if c.validateSTUNTrafficCache(srcAddr) { - return - } - c.remoteCandidateCaches[toAddrPort(srcAddr)] = candidate -} - -func (c *candidateBase) handleInboundPacket(buf []byte, srcAddr net.Addr) { - a := c.agent() - - if stun.IsMessage(buf) { - m := &stun.Message{ - Raw: make([]byte, len(buf)), - } - - // Explicitly copy raw buffer so Message can own the memory. - copy(m.Raw, buf) - - if err := m.Decode(); err != nil { - a.log.Warnf("Failed to handle decode ICE from %s to %s: %v", c.addr(), srcAddr, err) - return - } - - if err := a.run(c, func(ctx context.Context, a *Agent) { - a.handleInbound(m, c, srcAddr) - }); err != nil { - a.log.Warnf("Failed to handle message: %v", err) - } - - return - } - - if !c.validateSTUNTrafficCache(srcAddr) { - remoteCandidate, valid := a.validateNonSTUNTraffic(c, srcAddr) //nolint:contextcheck - if !valid { - a.log.Warnf("Discarded message from %s, not a valid remote candidate", c.addr()) - return - } - c.addRemoteCandidateCache(remoteCandidate, srcAddr) - } - - // Note: This will return packetio.ErrFull if the buffer ever manages to fill up. - if _, err := a.buf.Write(buf); err != nil { - a.log.Warnf("Failed to write packet: %s", err) - return - } -} - -// close stops the recvLoop -func (c *candidateBase) close() error { - // If conn has never been started will be nil - if c.Done() == nil { - return nil - } - - // Assert that conn has not already been closed - select { - case <-c.Done(): - return nil - default: - } - - var firstErr error - - // Unblock recvLoop - close(c.closeCh) - if err := c.conn.SetDeadline(time.Now()); err != nil { - firstErr = err - } - - // Close the conn - if err := c.conn.Close(); err != nil && firstErr == nil { - firstErr = err - } - - if firstErr != nil { - return firstErr - } - - // Wait until the recvLoop is closed - <-c.closedCh - - return nil -} - -func (c *candidateBase) writeTo(raw []byte, dst Candidate) (int, error) { - n, err := c.conn.WriteTo(raw, dst.addr()) - if err != nil { - // If the connection is closed, we should return the error - if errors.Is(err, io.ErrClosedPipe) { - return n, err - } - c.agent().log.Infof("%s: %v", errSendPacket, err) - return n, nil - } - c.seen(true) - return n, nil -} - -// Priority computes the priority for this ICE Candidate -func (c *candidateBase) Priority() uint32 { - if c.priorityOverride != 0 { - return c.priorityOverride - } - - // The local preference MUST be an integer from 0 (lowest preference) to - // 65535 (highest preference) inclusive. When there is only a single IP - // address, this value SHOULD be set to 65535. If there are multiple - // candidates for a particular component for a particular data stream - // that have the same type, the local preference MUST be unique for each - // one. - return (1<<24)*uint32(c.Type().Preference()) + - (1<<8)*uint32(c.LocalPreference()) + - uint32(256-c.Component()) -} - -// Equal is used to compare two candidateBases -func (c *candidateBase) Equal(other Candidate) bool { - return c.NetworkType() == other.NetworkType() && - c.Type() == other.Type() && - c.Address() == other.Address() && - c.Port() == other.Port() && - c.TCPType() == other.TCPType() && - c.RelatedAddress().Equal(other.RelatedAddress()) -} - -// String makes the candidateBase printable -func (c *candidateBase) String() string { - return fmt.Sprintf("%s %s %s%s", c.NetworkType(), c.Type(), net.JoinHostPort(c.Address(), strconv.Itoa(c.Port())), c.relatedAddress) -} - -// LastReceived returns a time.Time indicating the last time -// this candidate was received -func (c *candidateBase) LastReceived() time.Time { - if lastReceived, ok := c.lastReceived.Load().(time.Time); ok { - return lastReceived - } - return time.Time{} -} - -func (c *candidateBase) setLastReceived(t time.Time) { - c.lastReceived.Store(t) -} - -// LastSent returns a time.Time indicating the last time -// this candidate was sent -func (c *candidateBase) LastSent() time.Time { - if lastSent, ok := c.lastSent.Load().(time.Time); ok { - return lastSent - } - return time.Time{} -} - -func (c *candidateBase) setLastSent(t time.Time) { - c.lastSent.Store(t) -} - -func (c *candidateBase) seen(outbound bool) { - if outbound { - c.setLastSent(time.Now()) - } else { - c.setLastReceived(time.Now()) - } -} - -func (c *candidateBase) addr() net.Addr { - return c.resolvedAddr -} - -func (c *candidateBase) agent() *Agent { - return c.currAgent -} - -func (c *candidateBase) context() context.Context { - return c -} - -func (c *candidateBase) copy() (Candidate, error) { - return UnmarshalCandidate(c.Marshal()) -} - -// Marshal returns the string representation of the ICECandidate -func (c *candidateBase) Marshal() string { - val := c.Foundation() - if val == " " { - val = "" - } - - val = fmt.Sprintf("%s %d %s %d %s %d typ %s", - val, - c.Component(), - c.NetworkType().NetworkShort(), - c.Priority(), - c.Address(), - c.Port(), - c.Type()) - - if c.tcpType != TCPTypeUnspecified { - val += fmt.Sprintf(" tcptype %s", c.tcpType.String()) - } - - if r := c.RelatedAddress(); r != nil && r.Address != "" && r.Port != 0 { - val = fmt.Sprintf("%s raddr %s rport %d", - val, - r.Address, - r.Port) - } - - return val -} - -// UnmarshalCandidate creates a Candidate from its string representation -func UnmarshalCandidate(raw string) (Candidate, error) { - split := strings.Fields(raw) - // Foundation not specified: not RFC 8445 compliant but seen in the wild - if len(raw) != 0 && raw[0] == ' ' { - split = append([]string{" "}, split...) - } - if len(split) < 8 { - return nil, fmt.Errorf("%w (%d)", errAttributeTooShortICECandidate, len(split)) - } - - // Foundation - foundation := split[0] - - // Component - rawComponent, err := strconv.ParseUint(split[1], 10, 16) - if err != nil { - return nil, fmt.Errorf("%w: %v", errParseComponent, err) //nolint:errorlint - } - component := uint16(rawComponent) - - // Protocol - protocol := split[2] - - // Priority - priorityRaw, err := strconv.ParseUint(split[3], 10, 32) - if err != nil { - return nil, fmt.Errorf("%w: %v", errParsePriority, err) //nolint:errorlint - } - priority := uint32(priorityRaw) - - // Address - address := split[4] - - // Port - rawPort, err := strconv.ParseUint(split[5], 10, 16) - if err != nil { - return nil, fmt.Errorf("%w: %v", errParsePort, err) //nolint:errorlint - } - port := int(rawPort) - typ := split[7] - - relatedAddress := "" - relatedPort := 0 - tcpType := TCPTypeUnspecified - - if len(split) > 8 { - split = split[8:] - - if split[0] == "raddr" { - if len(split) < 4 { - return nil, fmt.Errorf("%w: incorrect length", errParseRelatedAddr) - } - - // RelatedAddress - relatedAddress = split[1] - - // RelatedPort - rawRelatedPort, parseErr := strconv.ParseUint(split[3], 10, 16) - if parseErr != nil { - return nil, fmt.Errorf("%w: %v", errParsePort, parseErr) //nolint:errorlint - } - relatedPort = int(rawRelatedPort) - } else if split[0] == "tcptype" { - if len(split) < 2 { - return nil, fmt.Errorf("%w: incorrect length", errParseTCPType) - } - - tcpType = NewTCPType(split[1]) - } - } - - switch typ { - case "host": - return NewCandidateHost(&CandidateHostConfig{"", protocol, address, port, component, priority, foundation, tcpType}) - case "srflx": - return NewCandidateServerReflexive(&CandidateServerReflexiveConfig{"", protocol, address, port, component, priority, foundation, relatedAddress, relatedPort}) - case "prflx": - return NewCandidatePeerReflexive(&CandidatePeerReflexiveConfig{"", protocol, address, port, component, priority, foundation, relatedAddress, relatedPort}) - case "relay": - return NewCandidateRelay(&CandidateRelayConfig{"", protocol, address, port, component, priority, foundation, relatedAddress, relatedPort, "", nil}) - default: - } - - return nil, fmt.Errorf("%w (%s)", ErrUnknownCandidateTyp, typ) -} diff --git a/vendor/github.com/pion/ice/v2/candidate_host.go b/vendor/github.com/pion/ice/v2/candidate_host.go deleted file mode 100644 index 5d207dd9..00000000 --- a/vendor/github.com/pion/ice/v2/candidate_host.go +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" - "strings" -) - -// CandidateHost is a candidate of type host -type CandidateHost struct { - candidateBase - - network string -} - -// CandidateHostConfig is the config required to create a new CandidateHost -type CandidateHostConfig struct { - CandidateID string - Network string - Address string - Port int - Component uint16 - Priority uint32 - Foundation string - TCPType TCPType -} - -// NewCandidateHost creates a new host candidate -func NewCandidateHost(config *CandidateHostConfig) (*CandidateHost, error) { - candidateID := config.CandidateID - - if candidateID == "" { - candidateID = globalCandidateIDGenerator.Generate() - } - - c := &CandidateHost{ - candidateBase: candidateBase{ - id: candidateID, - address: config.Address, - candidateType: CandidateTypeHost, - component: config.Component, - port: config.Port, - tcpType: config.TCPType, - foundationOverride: config.Foundation, - priorityOverride: config.Priority, - remoteCandidateCaches: map[AddrPort]Candidate{}, - }, - network: config.Network, - } - - if !strings.HasSuffix(config.Address, ".local") { - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed - } - - if err := c.setIP(ip); err != nil { - return nil, err - } - } else { - // Until mDNS candidate is resolved assume it is UDPv4 - c.candidateBase.networkType = NetworkTypeUDP4 - } - - return c, nil -} - -func (c *CandidateHost) setIP(ip net.IP) error { - networkType, err := determineNetworkType(c.network, ip) - if err != nil { - return err - } - - c.candidateBase.networkType = networkType - c.candidateBase.resolvedAddr = createAddr(networkType, ip, c.port) - - return nil -} diff --git a/vendor/github.com/pion/ice/v2/candidate_peer_reflexive.go b/vendor/github.com/pion/ice/v2/candidate_peer_reflexive.go deleted file mode 100644 index f019ec69..00000000 --- a/vendor/github.com/pion/ice/v2/candidate_peer_reflexive.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package ice ... -// -//nolint:dupl -package ice - -import "net" - -// CandidatePeerReflexive ... -type CandidatePeerReflexive struct { - candidateBase -} - -// CandidatePeerReflexiveConfig is the config required to create a new CandidatePeerReflexive -type CandidatePeerReflexiveConfig struct { - CandidateID string - Network string - Address string - Port int - Component uint16 - Priority uint32 - Foundation string - RelAddr string - RelPort int -} - -// NewCandidatePeerReflexive creates a new peer reflective candidate -func NewCandidatePeerReflexive(config *CandidatePeerReflexiveConfig) (*CandidatePeerReflexive, error) { - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed - } - - networkType, err := determineNetworkType(config.Network, ip) - if err != nil { - return nil, err - } - - candidateID := config.CandidateID - candidateIDGenerator := newCandidateIDGenerator() - if candidateID == "" { - candidateID = candidateIDGenerator.Generate() - } - - return &CandidatePeerReflexive{ - candidateBase: candidateBase{ - id: candidateID, - networkType: networkType, - candidateType: CandidateTypePeerReflexive, - address: config.Address, - port: config.Port, - resolvedAddr: createAddr(networkType, ip, config.Port), - component: config.Component, - foundationOverride: config.Foundation, - priorityOverride: config.Priority, - relatedAddress: &CandidateRelatedAddress{ - Address: config.RelAddr, - Port: config.RelPort, - }, - remoteCandidateCaches: map[AddrPort]Candidate{}, - }, - }, nil -} diff --git a/vendor/github.com/pion/ice/v2/candidate_relay.go b/vendor/github.com/pion/ice/v2/candidate_relay.go deleted file mode 100644 index 449d077a..00000000 --- a/vendor/github.com/pion/ice/v2/candidate_relay.go +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" -) - -// CandidateRelay ... -type CandidateRelay struct { - candidateBase - - relayProtocol string - onClose func() error -} - -// CandidateRelayConfig is the config required to create a new CandidateRelay -type CandidateRelayConfig struct { - CandidateID string - Network string - Address string - Port int - Component uint16 - Priority uint32 - Foundation string - RelAddr string - RelPort int - RelayProtocol string - OnClose func() error -} - -// NewCandidateRelay creates a new relay candidate -func NewCandidateRelay(config *CandidateRelayConfig) (*CandidateRelay, error) { - candidateID := config.CandidateID - - if candidateID == "" { - candidateID = globalCandidateIDGenerator.Generate() - } - - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed - } - - networkType, err := determineNetworkType(config.Network, ip) - if err != nil { - return nil, err - } - - return &CandidateRelay{ - candidateBase: candidateBase{ - id: candidateID, - networkType: networkType, - candidateType: CandidateTypeRelay, - address: config.Address, - port: config.Port, - resolvedAddr: &net.UDPAddr{IP: ip, Port: config.Port}, - component: config.Component, - foundationOverride: config.Foundation, - priorityOverride: config.Priority, - relatedAddress: &CandidateRelatedAddress{ - Address: config.RelAddr, - Port: config.RelPort, - }, - remoteCandidateCaches: map[AddrPort]Candidate{}, - }, - relayProtocol: config.RelayProtocol, - onClose: config.OnClose, - }, nil -} - -// RelayProtocol returns the protocol used between the endpoint and the relay server. -func (c *CandidateRelay) RelayProtocol() string { - return c.relayProtocol -} - -func (c *CandidateRelay) close() error { - err := c.candidateBase.close() - if c.onClose != nil { - err = c.onClose() - c.onClose = nil - } - return err -} - -func (c *CandidateRelay) copy() (Candidate, error) { - cc, err := c.candidateBase.copy() - if err != nil { - return nil, err - } - - if ccr, ok := cc.(*CandidateRelay); ok { - ccr.relayProtocol = c.relayProtocol - } - - return cc, nil -} diff --git a/vendor/github.com/pion/ice/v2/candidate_server_reflexive.go b/vendor/github.com/pion/ice/v2/candidate_server_reflexive.go deleted file mode 100644 index 3a8ac0ff..00000000 --- a/vendor/github.com/pion/ice/v2/candidate_server_reflexive.go +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "net" - -// CandidateServerReflexive ... -type CandidateServerReflexive struct { - candidateBase -} - -// CandidateServerReflexiveConfig is the config required to create a new CandidateServerReflexive -type CandidateServerReflexiveConfig struct { - CandidateID string - Network string - Address string - Port int - Component uint16 - Priority uint32 - Foundation string - RelAddr string - RelPort int -} - -// NewCandidateServerReflexive creates a new server reflective candidate -func NewCandidateServerReflexive(config *CandidateServerReflexiveConfig) (*CandidateServerReflexive, error) { - ip := net.ParseIP(config.Address) - if ip == nil { - return nil, ErrAddressParseFailed - } - - networkType, err := determineNetworkType(config.Network, ip) - if err != nil { - return nil, err - } - - candidateID := config.CandidateID - if candidateID == "" { - candidateID = globalCandidateIDGenerator.Generate() - } - - return &CandidateServerReflexive{ - candidateBase: candidateBase{ - id: candidateID, - networkType: networkType, - candidateType: CandidateTypeServerReflexive, - address: config.Address, - port: config.Port, - resolvedAddr: &net.UDPAddr{IP: ip, Port: config.Port}, - component: config.Component, - foundationOverride: config.Foundation, - priorityOverride: config.Priority, - relatedAddress: &CandidateRelatedAddress{ - Address: config.RelAddr, - Port: config.RelPort, - }, - remoteCandidateCaches: map[AddrPort]Candidate{}, - }, - }, nil -} diff --git a/vendor/github.com/pion/ice/v2/candidatepair.go b/vendor/github.com/pion/ice/v2/candidatepair.go deleted file mode 100644 index f33be539..00000000 --- a/vendor/github.com/pion/ice/v2/candidatepair.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "fmt" - - "github.com/pion/stun" -) - -func newCandidatePair(local, remote Candidate, controlling bool) *CandidatePair { - return &CandidatePair{ - iceRoleControlling: controlling, - Remote: remote, - Local: local, - state: CandidatePairStateWaiting, - } -} - -// CandidatePair is a combination of a -// local and remote candidate -type CandidatePair struct { - iceRoleControlling bool - Remote Candidate - Local Candidate - bindingRequestCount uint16 - state CandidatePairState - nominated bool - nominateOnBindingSuccess bool -} - -func (p *CandidatePair) String() string { - if p == nil { - return "" - } - - return fmt.Sprintf("prio %d (local, prio %d) %s <-> %s (remote, prio %d)", - p.priority(), p.Local.Priority(), p.Local, p.Remote, p.Remote.Priority()) -} - -func (p *CandidatePair) equal(other *CandidatePair) bool { - if p == nil && other == nil { - return true - } - if p == nil || other == nil { - return false - } - return p.Local.Equal(other.Local) && p.Remote.Equal(other.Remote) -} - -// RFC 5245 - 5.7.2. Computing Pair Priority and Ordering Pairs -// Let G be the priority for the candidate provided by the controlling -// agent. Let D be the priority for the candidate provided by the -// controlled agent. -// pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0) -func (p *CandidatePair) priority() uint64 { - var g, d uint32 - if p.iceRoleControlling { - g = p.Local.Priority() - d = p.Remote.Priority() - } else { - g = p.Remote.Priority() - d = p.Local.Priority() - } - - // Just implement these here rather - // than fooling around with the math package - min := func(x, y uint32) uint64 { - if x < y { - return uint64(x) - } - return uint64(y) - } - max := func(x, y uint32) uint64 { - if x > y { - return uint64(x) - } - return uint64(y) - } - cmp := func(x, y uint32) uint64 { - if x > y { - return uint64(1) - } - return uint64(0) - } - - // 1<<32 overflows uint32; and if both g && d are - // maxUint32, this result would overflow uint64 - return (1<<32-1)*min(g, d) + 2*max(g, d) + cmp(g, d) -} - -func (p *CandidatePair) Write(b []byte) (int, error) { - return p.Local.writeTo(b, p.Remote) -} - -func (a *Agent) sendSTUN(msg *stun.Message, local, remote Candidate) { - _, err := local.writeTo(msg.Raw, remote) - if err != nil { - a.log.Tracef("failed to send STUN message: %s", err) - } -} diff --git a/vendor/github.com/pion/ice/v2/candidatepair_state.go b/vendor/github.com/pion/ice/v2/candidatepair_state.go deleted file mode 100644 index 1a1e827b..00000000 --- a/vendor/github.com/pion/ice/v2/candidatepair_state.go +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -// CandidatePairState represent the ICE candidate pair state -type CandidatePairState int - -const ( - // CandidatePairStateWaiting means a check has not been performed for - // this pair - CandidatePairStateWaiting = iota + 1 - - // CandidatePairStateInProgress means a check has been sent for this pair, - // but the transaction is in progress. - CandidatePairStateInProgress - - // CandidatePairStateFailed means a check for this pair was already done - // and failed, either never producing any response or producing an unrecoverable - // failure response. - CandidatePairStateFailed - - // CandidatePairStateSucceeded means a check for this pair was already - // done and produced a successful result. - CandidatePairStateSucceeded -) - -func (c CandidatePairState) String() string { - switch c { - case CandidatePairStateWaiting: - return "waiting" - case CandidatePairStateInProgress: - return "in-progress" - case CandidatePairStateFailed: - return "failed" - case CandidatePairStateSucceeded: - return "succeeded" - } - return "Unknown candidate pair state" -} diff --git a/vendor/github.com/pion/ice/v2/candidaterelatedaddress.go b/vendor/github.com/pion/ice/v2/candidaterelatedaddress.go deleted file mode 100644 index e87c7051..00000000 --- a/vendor/github.com/pion/ice/v2/candidaterelatedaddress.go +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "fmt" - -// CandidateRelatedAddress convey transport addresses related to the -// candidate, useful for diagnostics and other purposes. -type CandidateRelatedAddress struct { - Address string - Port int -} - -// String makes CandidateRelatedAddress printable -func (c *CandidateRelatedAddress) String() string { - if c == nil { - return "" - } - - return fmt.Sprintf(" related %s:%d", c.Address, c.Port) -} - -// Equal allows comparing two CandidateRelatedAddresses. -// The CandidateRelatedAddress are allowed to be nil. -func (c *CandidateRelatedAddress) Equal(other *CandidateRelatedAddress) bool { - if c == nil && other == nil { - return true - } - return c != nil && other != nil && - c.Address == other.Address && - c.Port == other.Port -} diff --git a/vendor/github.com/pion/ice/v2/candidatetype.go b/vendor/github.com/pion/ice/v2/candidatetype.go deleted file mode 100644 index 3972934c..00000000 --- a/vendor/github.com/pion/ice/v2/candidatetype.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -// CandidateType represents the type of candidate -type CandidateType byte - -// CandidateType enum -const ( - CandidateTypeUnspecified CandidateType = iota - CandidateTypeHost - CandidateTypeServerReflexive - CandidateTypePeerReflexive - CandidateTypeRelay -) - -// String makes CandidateType printable -func (c CandidateType) String() string { - switch c { - case CandidateTypeHost: - return "host" - case CandidateTypeServerReflexive: - return "srflx" - case CandidateTypePeerReflexive: - return "prflx" - case CandidateTypeRelay: - return "relay" - case CandidateTypeUnspecified: - return "Unknown candidate type" - } - return "Unknown candidate type" -} - -// Preference returns the preference weight of a CandidateType -// -// 4.1.2.2. Guidelines for Choosing Type and Local Preferences -// The RECOMMENDED values are 126 for host candidates, 100 -// for server reflexive candidates, 110 for peer reflexive candidates, -// and 0 for relayed candidates. -func (c CandidateType) Preference() uint16 { - switch c { - case CandidateTypeHost: - return 126 - case CandidateTypePeerReflexive: - return 110 - case CandidateTypeServerReflexive: - return 100 - case CandidateTypeRelay, CandidateTypeUnspecified: - return 0 - } - return 0 -} - -func containsCandidateType(candidateType CandidateType, candidateTypeList []CandidateType) bool { - if candidateTypeList == nil { - return false - } - for _, ct := range candidateTypeList { - if ct == candidateType { - return true - } - } - return false -} diff --git a/vendor/github.com/pion/ice/v2/codecov.yml b/vendor/github.com/pion/ice/v2/codecov.yml deleted file mode 100644 index 263e4d45..00000000 --- a/vendor/github.com/pion/ice/v2/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/ice/v2/context.go b/vendor/github.com/pion/ice/v2/context.go deleted file mode 100644 index 36454450..00000000 --- a/vendor/github.com/pion/ice/v2/context.go +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "context" - "time" -) - -func (a *Agent) context() context.Context { - return agentContext(a.done) -} - -type agentContext chan struct{} - -// Done implements context.Context -func (a agentContext) Done() <-chan struct{} { - return (chan struct{})(a) -} - -// Err implements context.Context -func (a agentContext) Err() error { - select { - case <-(chan struct{})(a): - return ErrRunCanceled - default: - return nil - } -} - -// Deadline implements context.Context -func (a agentContext) Deadline() (deadline time.Time, ok bool) { - return time.Time{}, false -} - -// Value implements context.Context -func (a agentContext) Value(interface{}) interface{} { - return nil -} diff --git a/vendor/github.com/pion/ice/v2/errors.go b/vendor/github.com/pion/ice/v2/errors.go deleted file mode 100644 index e05cce89..00000000 --- a/vendor/github.com/pion/ice/v2/errors.go +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "errors" - -var ( - // ErrUnknownType indicates an error with Unknown info. - ErrUnknownType = errors.New("Unknown") - - // ErrSchemeType indicates the scheme type could not be parsed. - ErrSchemeType = errors.New("unknown scheme type") - - // ErrSTUNQuery indicates query arguments are provided in a STUN URL. - ErrSTUNQuery = errors.New("queries not supported in STUN address") - - // ErrInvalidQuery indicates an malformed query is provided. - ErrInvalidQuery = errors.New("invalid query") - - // ErrHost indicates malformed hostname is provided. - ErrHost = errors.New("invalid hostname") - - // ErrPort indicates malformed port is provided. - ErrPort = errors.New("invalid port") - - // ErrLocalUfragInsufficientBits indicates local username fragment insufficient bits are provided. - // Have to be at least 24 bits long - ErrLocalUfragInsufficientBits = errors.New("local username fragment is less than 24 bits long") - - // ErrLocalPwdInsufficientBits indicates local password insufficient bits are provided. - // Have to be at least 128 bits long - ErrLocalPwdInsufficientBits = errors.New("local password is less than 128 bits long") - - // ErrProtoType indicates an unsupported transport type was provided. - ErrProtoType = errors.New("invalid transport protocol type") - - // ErrClosed indicates the agent is closed - ErrClosed = errors.New("the agent is closed") - - // ErrNoCandidatePairs indicates agent does not have a valid candidate pair - ErrNoCandidatePairs = errors.New("no candidate pairs available") - - // ErrCanceledByCaller indicates agent connection was canceled by the caller - ErrCanceledByCaller = errors.New("connecting canceled by caller") - - // ErrMultipleStart indicates agent was started twice - ErrMultipleStart = errors.New("attempted to start agent twice") - - // ErrRemoteUfragEmpty indicates agent was started with an empty remote ufrag - ErrRemoteUfragEmpty = errors.New("remote ufrag is empty") - - // ErrRemotePwdEmpty indicates agent was started with an empty remote pwd - ErrRemotePwdEmpty = errors.New("remote pwd is empty") - - // ErrNoOnCandidateHandler indicates agent was started without OnCandidate - ErrNoOnCandidateHandler = errors.New("no OnCandidate provided") - - // ErrMultipleGatherAttempted indicates GatherCandidates has been called multiple times - ErrMultipleGatherAttempted = errors.New("attempting to gather candidates during gathering state") - - // ErrUsernameEmpty indicates agent was give TURN URL with an empty Username - ErrUsernameEmpty = errors.New("username is empty") - - // ErrPasswordEmpty indicates agent was give TURN URL with an empty Password - ErrPasswordEmpty = errors.New("password is empty") - - // ErrAddressParseFailed indicates we were unable to parse a candidate address - ErrAddressParseFailed = errors.New("failed to parse address") - - // ErrLiteUsingNonHostCandidates indicates non host candidates were selected for a lite agent - ErrLiteUsingNonHostCandidates = errors.New("lite agents must only use host candidates") - - // ErrUselessUrlsProvided indicates that one or more URL was provided to the agent but no host - // candidate required them - ErrUselessUrlsProvided = errors.New("agent does not need URL with selected candidate types") - - // ErrUnsupportedNAT1To1IPCandidateType indicates that the specified NAT1To1IPCandidateType is - // unsupported - ErrUnsupportedNAT1To1IPCandidateType = errors.New("unsupported 1:1 NAT IP candidate type") - - // ErrInvalidNAT1To1IPMapping indicates that the given 1:1 NAT IP mapping is invalid - ErrInvalidNAT1To1IPMapping = errors.New("invalid 1:1 NAT IP mapping") - - // ErrExternalMappedIPNotFound in NAT1To1IPMapping - ErrExternalMappedIPNotFound = errors.New("external mapped IP not found") - - // ErrMulticastDNSWithNAT1To1IPMapping indicates that the mDNS gathering cannot be used along - // with 1:1 NAT IP mapping for host candidate. - ErrMulticastDNSWithNAT1To1IPMapping = errors.New("mDNS gathering cannot be used with 1:1 NAT IP mapping for host candidate") - - // ErrIneffectiveNAT1To1IPMappingHost indicates that 1:1 NAT IP mapping for host candidate is - // requested, but the host candidate type is disabled. - ErrIneffectiveNAT1To1IPMappingHost = errors.New("1:1 NAT IP mapping for host candidate ineffective") - - // ErrIneffectiveNAT1To1IPMappingSrflx indicates that 1:1 NAT IP mapping for srflx candidate is - // requested, but the srflx candidate type is disabled. - ErrIneffectiveNAT1To1IPMappingSrflx = errors.New("1:1 NAT IP mapping for srflx candidate ineffective") - - // ErrInvalidMulticastDNSHostName indicates an invalid MulticastDNSHostName - ErrInvalidMulticastDNSHostName = errors.New("invalid mDNS HostName, must end with .local and can only contain a single '.'") - - // ErrRunCanceled indicates a run operation was canceled by its individual done - ErrRunCanceled = errors.New("run was canceled by done") - - // ErrTCPRemoteAddrAlreadyExists indicates we already have the connection with same remote addr. - ErrTCPRemoteAddrAlreadyExists = errors.New("conn with same remote addr already exists") - - // ErrUnknownCandidateTyp indicates that a candidate had a unknown type value. - ErrUnknownCandidateTyp = errors.New("unknown candidate typ") - - // ErrDetermineNetworkType indicates that the NetworkType was not able to be parsed - ErrDetermineNetworkType = errors.New("unable to determine networkType") - - errSendPacket = errors.New("failed to send packet") - errAttributeTooShortICECandidate = errors.New("attribute not long enough to be ICE candidate") - errParseComponent = errors.New("could not parse component") - errParsePriority = errors.New("could not parse priority") - errParsePort = errors.New("could not parse port") - errParseRelatedAddr = errors.New("could not parse related addresses") - errParseTCPType = errors.New("could not parse TCP type") - errGetXorMappedAddrResponse = errors.New("failed to get XOR-MAPPED-ADDRESS response") - errConnectionAddrAlreadyExist = errors.New("connection with same remote address already exists") - errReadingStreamingPacket = errors.New("error reading streaming packet") - errWriting = errors.New("error writing to") - errClosingConnection = errors.New("error closing connection") - errRead = errors.New("unexpected error trying to read") - errUnknownRole = errors.New("unknown role") - errICEWriteSTUNMessage = errors.New("the ICE conn can't write STUN messages") - errUDPMuxDisabled = errors.New("UDPMux is not enabled") - errNoXorAddrMapping = errors.New("no address mapping") - errSendSTUNPacket = errors.New("failed to send STUN packet") - errXORMappedAddrTimeout = errors.New("timeout while waiting for XORMappedAddr") - errNotImplemented = errors.New("not implemented yet") - errNoUDPMuxAvailable = errors.New("no UDP mux is available") - errNoTCPMuxAvailable = errors.New("no TCP mux is available") - errInvalidAddress = errors.New("invalid address") - - // UDPMuxDefault should not listen on unspecified address, but to keep backward compatibility, don't return error now. - // will be used in the future. - // errListenUnspecified = errors.New("can't listen on unspecified address") -) diff --git a/vendor/github.com/pion/ice/v2/external_ip_mapper.go b/vendor/github.com/pion/ice/v2/external_ip_mapper.go deleted file mode 100644 index 3d542fb1..00000000 --- a/vendor/github.com/pion/ice/v2/external_ip_mapper.go +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" - "strings" -) - -func validateIPString(ipStr string) (net.IP, bool, error) { - ip := net.ParseIP(ipStr) - if ip == nil { - return nil, false, ErrInvalidNAT1To1IPMapping - } - return ip, (ip.To4() != nil), nil -} - -// ipMapping holds the mapping of local and external IP address for a particular IP family -type ipMapping struct { - ipSole net.IP // When non-nil, this is the sole external IP for one local IP assumed - ipMap map[string]net.IP // Local-to-external IP mapping (k: local, v: external) - valid bool // If not set any external IP, valid is false -} - -func (m *ipMapping) setSoleIP(ip net.IP) error { - if m.ipSole != nil || len(m.ipMap) > 0 { - return ErrInvalidNAT1To1IPMapping - } - - m.ipSole = ip - m.valid = true - - return nil -} - -func (m *ipMapping) addIPMapping(locIP, extIP net.IP) error { - if m.ipSole != nil { - return ErrInvalidNAT1To1IPMapping - } - - locIPStr := locIP.String() - - // Check if dup of local IP - if _, ok := m.ipMap[locIPStr]; ok { - return ErrInvalidNAT1To1IPMapping - } - - m.ipMap[locIPStr] = extIP - m.valid = true - - return nil -} - -func (m *ipMapping) findExternalIP(locIP net.IP) (net.IP, error) { - if !m.valid { - return locIP, nil - } - - if m.ipSole != nil { - return m.ipSole, nil - } - - extIP, ok := m.ipMap[locIP.String()] - if !ok { - return nil, ErrExternalMappedIPNotFound - } - - return extIP, nil -} - -type externalIPMapper struct { - ipv4Mapping ipMapping - ipv6Mapping ipMapping - candidateType CandidateType -} - -func newExternalIPMapper(candidateType CandidateType, ips []string) (*externalIPMapper, error) { //nolint:gocognit - if len(ips) == 0 { - return nil, nil //nolint:nilnil - } - if candidateType == CandidateTypeUnspecified { - candidateType = CandidateTypeHost // Defaults to host - } else if candidateType != CandidateTypeHost && candidateType != CandidateTypeServerReflexive { - return nil, ErrUnsupportedNAT1To1IPCandidateType - } - - m := &externalIPMapper{ - ipv4Mapping: ipMapping{ipMap: map[string]net.IP{}}, - ipv6Mapping: ipMapping{ipMap: map[string]net.IP{}}, - candidateType: candidateType, - } - - for _, extIPStr := range ips { - ipPair := strings.Split(extIPStr, "/") - if len(ipPair) == 0 || len(ipPair) > 2 { - return nil, ErrInvalidNAT1To1IPMapping - } - - extIP, isExtIPv4, err := validateIPString(ipPair[0]) - if err != nil { - return nil, err - } - if len(ipPair) == 1 { - if isExtIPv4 { - if err := m.ipv4Mapping.setSoleIP(extIP); err != nil { - return nil, err - } - } else { - if err := m.ipv6Mapping.setSoleIP(extIP); err != nil { - return nil, err - } - } - } else { - locIP, isLocIPv4, err := validateIPString(ipPair[1]) - if err != nil { - return nil, err - } - if isExtIPv4 { - if !isLocIPv4 { - return nil, ErrInvalidNAT1To1IPMapping - } - - if err := m.ipv4Mapping.addIPMapping(locIP, extIP); err != nil { - return nil, err - } - } else { - if isLocIPv4 { - return nil, ErrInvalidNAT1To1IPMapping - } - - if err := m.ipv6Mapping.addIPMapping(locIP, extIP); err != nil { - return nil, err - } - } - } - } - - return m, nil -} - -func (m *externalIPMapper) findExternalIP(localIPStr string) (net.IP, error) { - locIP, isLocIPv4, err := validateIPString(localIPStr) - if err != nil { - return nil, err - } - - if isLocIPv4 { - return m.ipv4Mapping.findExternalIP(locIP) - } - - return m.ipv6Mapping.findExternalIP(locIP) -} diff --git a/vendor/github.com/pion/ice/v2/gather.go b/vendor/github.com/pion/ice/v2/gather.go deleted file mode 100644 index 15e2da14..00000000 --- a/vendor/github.com/pion/ice/v2/gather.go +++ /dev/null @@ -1,720 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "context" - "crypto/tls" - "fmt" - "io" - "net" - "reflect" - "sync" - "time" - - "github.com/pion/dtls/v2" - "github.com/pion/ice/v2/internal/fakenet" - stunx "github.com/pion/ice/v2/internal/stun" - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/turn/v2" -) - -const ( - stunGatherTimeout = time.Second * 5 -) - -// Close a net.Conn and log if we have a failure -func closeConnAndLog(c io.Closer, log logging.LeveledLogger, msg string, args ...interface{}) { - if c == nil || (reflect.ValueOf(c).Kind() == reflect.Ptr && reflect.ValueOf(c).IsNil()) { - log.Warnf("Connection is not allocated: "+msg, args...) - return - } - - log.Warnf(msg) - if err := c.Close(); err != nil { - log.Warnf("Failed to close connection: %v", err) - } -} - -// GatherCandidates initiates the trickle based gathering process. -func (a *Agent) GatherCandidates() error { - var gatherErr error - - if runErr := a.run(a.context(), func(ctx context.Context, agent *Agent) { - if a.gatheringState != GatheringStateNew { - gatherErr = ErrMultipleGatherAttempted - return - } else if a.onCandidateHdlr.Load() == nil { - gatherErr = ErrNoOnCandidateHandler - return - } - - a.gatherCandidateCancel() // Cancel previous gathering routine - ctx, cancel := context.WithCancel(ctx) - a.gatherCandidateCancel = cancel - done := make(chan struct{}) - a.gatherCandidateDone = done - - go a.gatherCandidates(ctx, done) - }); runErr != nil { - return runErr - } - return gatherErr -} - -func (a *Agent) gatherCandidates(ctx context.Context, done chan struct{}) { - defer close(done) - if err := a.setGatheringState(GatheringStateGathering); err != nil { //nolint:contextcheck - a.log.Warnf("Failed to set gatheringState to GatheringStateGathering: %v", err) - return - } - - var wg sync.WaitGroup - for _, t := range a.candidateTypes { - switch t { - case CandidateTypeHost: - wg.Add(1) - go func() { - a.gatherCandidatesLocal(ctx, a.networkTypes) - wg.Done() - }() - case CandidateTypeServerReflexive: - wg.Add(1) - go func() { - if a.udpMuxSrflx != nil { - a.gatherCandidatesSrflxUDPMux(ctx, a.urls, a.networkTypes) - } else { - a.gatherCandidatesSrflx(ctx, a.urls, a.networkTypes) - } - wg.Done() - }() - if a.extIPMapper != nil && a.extIPMapper.candidateType == CandidateTypeServerReflexive { - wg.Add(1) - go func() { - a.gatherCandidatesSrflxMapped(ctx, a.networkTypes) - wg.Done() - }() - } - case CandidateTypeRelay: - wg.Add(1) - go func() { - a.gatherCandidatesRelay(ctx, a.urls) - wg.Done() - }() - case CandidateTypePeerReflexive, CandidateTypeUnspecified: - } - } - - // Block until all STUN and TURN URLs have been gathered (or timed out) - wg.Wait() - - if err := a.setGatheringState(GatheringStateComplete); err != nil { //nolint:contextcheck - a.log.Warnf("Failed to set gatheringState to GatheringStateComplete: %v", err) - } -} - -func (a *Agent) gatherCandidatesLocal(ctx context.Context, networkTypes []NetworkType) { //nolint:gocognit - networks := map[string]struct{}{} - for _, networkType := range networkTypes { - if networkType.IsTCP() { - networks[tcp] = struct{}{} - } else { - networks[udp] = struct{}{} - } - } - - // When UDPMux is enabled, skip other UDP candidates - if a.udpMux != nil { - if err := a.gatherCandidatesLocalUDPMux(ctx); err != nil { - a.log.Warnf("Failed to create host candidate for UDPMux: %s", err) - } - delete(networks, udp) - } - - localIPs, err := localInterfaces(a.net, a.interfaceFilter, a.ipFilter, networkTypes, a.includeLoopback) - if err != nil { - a.log.Warnf("Failed to iterate local interfaces, host candidates will not be gathered %s", err) - return - } - - for _, ip := range localIPs { - mappedIP := ip - if a.mDNSMode != MulticastDNSModeQueryAndGather && a.extIPMapper != nil && a.extIPMapper.candidateType == CandidateTypeHost { - if _mappedIP, innerErr := a.extIPMapper.findExternalIP(ip.String()); innerErr == nil { - mappedIP = _mappedIP - } else { - a.log.Warnf("1:1 NAT mapping is enabled but no external IP is found for %s", ip.String()) - } - } - - address := mappedIP.String() - if a.mDNSMode == MulticastDNSModeQueryAndGather { - address = a.mDNSName - } - - for network := range networks { - type connAndPort struct { - conn net.PacketConn - port int - } - var ( - conns []connAndPort - tcpType TCPType - ) - - switch network { - case tcp: - if a.tcpMux == nil { - continue - } - - // Handle ICE TCP passive mode - var muxConns []net.PacketConn - if multi, ok := a.tcpMux.(AllConnsGetter); ok { - a.log.Debugf("GetAllConns by ufrag: %s", a.localUfrag) - muxConns, err = multi.GetAllConns(a.localUfrag, mappedIP.To4() == nil, ip) - if err != nil { - a.log.Warnf("Failed to get all TCP connections by ufrag: %s %s %s", network, ip, a.localUfrag) - continue - } - } else { - a.log.Debugf("GetConn by ufrag: %s", a.localUfrag) - conn, err := a.tcpMux.GetConnByUfrag(a.localUfrag, mappedIP.To4() == nil, ip) - if err != nil { - a.log.Warnf("Failed to get TCP connections by ufrag: %s %s %s", network, ip, a.localUfrag) - continue - } - muxConns = []net.PacketConn{conn} - } - - // Extract the port for each PacketConn we got. - for _, conn := range muxConns { - if tcpConn, ok := conn.LocalAddr().(*net.TCPAddr); ok { - conns = append(conns, connAndPort{conn, tcpConn.Port}) - } else { - a.log.Warnf("Failed to get port of connection from TCPMux: %s %s %s", network, ip, a.localUfrag) - } - } - if len(conns) == 0 { - // Didn't succeed with any, try the next network. - continue - } - tcpType = TCPTypePassive - // Is there a way to verify that the listen address is even - // accessible from the current interface. - case udp: - conn, err := listenUDPInPortRange(a.net, a.log, int(a.portMax), int(a.portMin), network, &net.UDPAddr{IP: ip, Port: 0}) - if err != nil { - a.log.Warnf("Failed to listen %s %s", network, ip) - continue - } - - if udpConn, ok := conn.LocalAddr().(*net.UDPAddr); ok { - conns = append(conns, connAndPort{conn, udpConn.Port}) - } else { - a.log.Warnf("Failed to get port of UDPAddr from ListenUDPInPortRange: %s %s %s", network, ip, a.localUfrag) - continue - } - } - - for _, connAndPort := range conns { - hostConfig := CandidateHostConfig{ - Network: network, - Address: address, - Port: connAndPort.port, - Component: ComponentRTP, - TCPType: tcpType, - } - - c, err := NewCandidateHost(&hostConfig) - if err != nil { - closeConnAndLog(connAndPort.conn, a.log, "failed to create host candidate: %s %s %d: %v", network, mappedIP, connAndPort.port, err) - continue - } - - if a.mDNSMode == MulticastDNSModeQueryAndGather { - if err = c.setIP(ip); err != nil { - closeConnAndLog(connAndPort.conn, a.log, "failed to create host candidate: %s %s %d: %v", network, mappedIP, connAndPort.port, err) - continue - } - } - - if err := a.addCandidate(ctx, c, connAndPort.conn); err != nil { - if closeErr := c.close(); closeErr != nil { - a.log.Warnf("Failed to close candidate: %v", closeErr) - } - a.log.Warnf("Failed to append to localCandidates and run onCandidateHdlr: %v", err) - } - } - } - } -} - -func (a *Agent) gatherCandidatesLocalUDPMux(ctx context.Context) error { //nolint:gocognit - if a.udpMux == nil { - return errUDPMuxDisabled - } - - localAddresses := a.udpMux.GetListenAddresses() - existingConfigs := make(map[CandidateHostConfig]struct{}) - - for _, addr := range localAddresses { - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - return errInvalidAddress - } - candidateIP := udpAddr.IP - if a.extIPMapper != nil && a.extIPMapper.candidateType == CandidateTypeHost { - mappedIP, err := a.extIPMapper.findExternalIP(candidateIP.String()) - if err != nil { - a.log.Warnf("1:1 NAT mapping is enabled but no external IP is found for %s", candidateIP.String()) - continue - } - - candidateIP = mappedIP - } - - hostConfig := CandidateHostConfig{ - Network: udp, - Address: candidateIP.String(), - Port: udpAddr.Port, - Component: ComponentRTP, - } - - // Detect a duplicate candidate before calling addCandidate(). - // otherwise, addCandidate() detects the duplicate candidate - // and close its connection, invalidating all candidates - // that share the same connection. - if _, ok := existingConfigs[hostConfig]; ok { - continue - } - - conn, err := a.udpMux.GetConn(a.localUfrag, udpAddr) - if err != nil { - return err - } - - c, err := NewCandidateHost(&hostConfig) - if err != nil { - closeConnAndLog(conn, a.log, "failed to create host mux candidate: %s %d: %v", candidateIP, udpAddr.Port, err) - continue - } - - if err := a.addCandidate(ctx, c, conn); err != nil { - if closeErr := c.close(); closeErr != nil { - a.log.Warnf("Failed to close candidate: %v", closeErr) - } - - closeConnAndLog(conn, a.log, "failed to add candidate: %s %d: %v", candidateIP, udpAddr.Port, err) - continue - } - - existingConfigs[hostConfig] = struct{}{} - } - - return nil -} - -func (a *Agent) gatherCandidatesSrflxMapped(ctx context.Context, networkTypes []NetworkType) { - var wg sync.WaitGroup - defer wg.Wait() - - for _, networkType := range networkTypes { - if networkType.IsTCP() { - continue - } - - network := networkType.String() - wg.Add(1) - go func() { - defer wg.Done() - - conn, err := listenUDPInPortRange(a.net, a.log, int(a.portMax), int(a.portMin), network, &net.UDPAddr{IP: nil, Port: 0}) - if err != nil { - a.log.Warnf("Failed to listen %s: %v", network, err) - return - } - - lAddr, ok := conn.LocalAddr().(*net.UDPAddr) - if !ok { - closeConnAndLog(conn, a.log, "1:1 NAT mapping is enabled but LocalAddr is not a UDPAddr") - return - } - - mappedIP, err := a.extIPMapper.findExternalIP(lAddr.IP.String()) - if err != nil { - closeConnAndLog(conn, a.log, "1:1 NAT mapping is enabled but no external IP is found for %s", lAddr.IP.String()) - return - } - - srflxConfig := CandidateServerReflexiveConfig{ - Network: network, - Address: mappedIP.String(), - Port: lAddr.Port, - Component: ComponentRTP, - RelAddr: lAddr.IP.String(), - RelPort: lAddr.Port, - } - c, err := NewCandidateServerReflexive(&srflxConfig) - if err != nil { - closeConnAndLog(conn, a.log, "failed to create server reflexive candidate: %s %s %d: %v", - network, - mappedIP.String(), - lAddr.Port, - err) - return - } - - if err := a.addCandidate(ctx, c, conn); err != nil { - if closeErr := c.close(); closeErr != nil { - a.log.Warnf("Failed to close candidate: %v", closeErr) - } - a.log.Warnf("Failed to append to localCandidates and run onCandidateHdlr: %v", err) - } - }() - } -} - -func (a *Agent) gatherCandidatesSrflxUDPMux(ctx context.Context, urls []*stun.URI, networkTypes []NetworkType) { //nolint:gocognit - var wg sync.WaitGroup - defer wg.Wait() - - for _, networkType := range networkTypes { - if networkType.IsTCP() { - continue - } - - for i := range urls { - for _, listenAddr := range a.udpMuxSrflx.GetListenAddresses() { - udpAddr, ok := listenAddr.(*net.UDPAddr) - if !ok { - a.log.Warn("Failed to cast udpMuxSrflx listen address to UDPAddr") - continue - } - wg.Add(1) - go func(url stun.URI, network string, localAddr *net.UDPAddr) { - defer wg.Done() - - hostPort := fmt.Sprintf("%s:%d", url.Host, url.Port) - serverAddr, err := a.net.ResolveUDPAddr(network, hostPort) - if err != nil { - a.log.Warnf("Failed to resolve STUN host: %s: %v", hostPort, err) - return - } - - xorAddr, err := a.udpMuxSrflx.GetXORMappedAddr(serverAddr, stunGatherTimeout) - if err != nil { - a.log.Warnf("Failed get server reflexive address %s %s: %v", network, url, err) - return - } - - conn, err := a.udpMuxSrflx.GetConnForURL(a.localUfrag, url.String(), localAddr) - if err != nil { - a.log.Warnf("Failed to find connection in UDPMuxSrflx %s %s: %v", network, url, err) - return - } - - ip := xorAddr.IP - port := xorAddr.Port - - srflxConfig := CandidateServerReflexiveConfig{ - Network: network, - Address: ip.String(), - Port: port, - Component: ComponentRTP, - RelAddr: localAddr.IP.String(), - RelPort: localAddr.Port, - } - c, err := NewCandidateServerReflexive(&srflxConfig) - if err != nil { - closeConnAndLog(conn, a.log, "failed to create server reflexive candidate: %s %s %d: %v", network, ip, port, err) - return - } - - if err := a.addCandidate(ctx, c, conn); err != nil { - if closeErr := c.close(); closeErr != nil { - a.log.Warnf("Failed to close candidate: %v", closeErr) - } - a.log.Warnf("Failed to append to localCandidates and run onCandidateHdlr: %v", err) - } - }(*urls[i], networkType.String(), udpAddr) - } - } - } -} - -func (a *Agent) gatherCandidatesSrflx(ctx context.Context, urls []*stun.URI, networkTypes []NetworkType) { //nolint:gocognit - var wg sync.WaitGroup - defer wg.Wait() - - for _, networkType := range networkTypes { - if networkType.IsTCP() { - continue - } - - for i := range urls { - wg.Add(1) - go func(url stun.URI, network string) { - defer wg.Done() - - hostPort := fmt.Sprintf("%s:%d", url.Host, url.Port) - serverAddr, err := a.net.ResolveUDPAddr(network, hostPort) - if err != nil { - a.log.Warnf("Failed to resolve STUN host: %s: %v", hostPort, err) - return - } - - conn, err := listenUDPInPortRange(a.net, a.log, int(a.portMax), int(a.portMin), network, &net.UDPAddr{IP: nil, Port: 0}) - if err != nil { - closeConnAndLog(conn, a.log, "failed to listen for %s: %v", serverAddr.String(), err) - return - } - // If the agent closes midway through the connection - // we end it early to prevent close delay. - cancelCtx, cancelFunc := context.WithCancel(ctx) - defer cancelFunc() - go func() { - select { - case <-cancelCtx.Done(): - return - case <-a.done: - _ = conn.Close() - } - }() - - xorAddr, err := stunx.GetXORMappedAddr(conn, serverAddr, stunGatherTimeout) - if err != nil { - closeConnAndLog(conn, a.log, "failed to get server reflexive address %s %s: %v", network, url, err) - return - } - - ip := xorAddr.IP - port := xorAddr.Port - - lAddr := conn.LocalAddr().(*net.UDPAddr) //nolint:forcetypeassert - srflxConfig := CandidateServerReflexiveConfig{ - Network: network, - Address: ip.String(), - Port: port, - Component: ComponentRTP, - RelAddr: lAddr.IP.String(), - RelPort: lAddr.Port, - } - c, err := NewCandidateServerReflexive(&srflxConfig) - if err != nil { - closeConnAndLog(conn, a.log, "failed to create server reflexive candidate: %s %s %d: %v", network, ip, port, err) - return - } - - if err := a.addCandidate(ctx, c, conn); err != nil { - if closeErr := c.close(); closeErr != nil { - a.log.Warnf("Failed to close candidate: %v", closeErr) - } - a.log.Warnf("Failed to append to localCandidates and run onCandidateHdlr: %v", err) - } - }(*urls[i], networkType.String()) - } - } -} - -func (a *Agent) gatherCandidatesRelay(ctx context.Context, urls []*stun.URI) { //nolint:gocognit - var wg sync.WaitGroup - defer wg.Wait() - - network := NetworkTypeUDP4.String() - for i := range urls { - switch { - case urls[i].Scheme != stun.SchemeTypeTURN && urls[i].Scheme != stun.SchemeTypeTURNS: - continue - case urls[i].Username == "": - a.log.Errorf("Failed to gather relay candidates: %v", ErrUsernameEmpty) - return - case urls[i].Password == "": - a.log.Errorf("Failed to gather relay candidates: %v", ErrPasswordEmpty) - return - } - - wg.Add(1) - go func(url stun.URI) { - defer wg.Done() - turnServerAddr := fmt.Sprintf("%s:%d", url.Host, url.Port) - var ( - locConn net.PacketConn - err error - relAddr string - relPort int - relayProtocol string - ) - - switch { - case url.Proto == stun.ProtoTypeUDP && url.Scheme == stun.SchemeTypeTURN: - if locConn, err = a.net.ListenPacket(network, "0.0.0.0:0"); err != nil { - a.log.Warnf("Failed to listen %s: %v", network, err) - return - } - - relAddr = locConn.LocalAddr().(*net.UDPAddr).IP.String() //nolint:forcetypeassert - relPort = locConn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert - relayProtocol = udp - case a.proxyDialer != nil && url.Proto == stun.ProtoTypeTCP && - (url.Scheme == stun.SchemeTypeTURN || url.Scheme == stun.SchemeTypeTURNS): - conn, connectErr := a.proxyDialer.Dial(NetworkTypeTCP4.String(), turnServerAddr) - if connectErr != nil { - a.log.Warnf("Failed to dial TCP address %s via proxy dialer: %v", turnServerAddr, connectErr) - return - } - - relAddr = conn.LocalAddr().(*net.TCPAddr).IP.String() //nolint:forcetypeassert - relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert - if url.Scheme == stun.SchemeTypeTURN { - relayProtocol = tcp - } else if url.Scheme == stun.SchemeTypeTURNS { - relayProtocol = "tls" - } - locConn = turn.NewSTUNConn(conn) - - case url.Proto == stun.ProtoTypeTCP && url.Scheme == stun.SchemeTypeTURN: - tcpAddr, connectErr := a.net.ResolveTCPAddr(NetworkTypeTCP4.String(), turnServerAddr) - if connectErr != nil { - a.log.Warnf("Failed to resolve TCP address %s: %v", turnServerAddr, connectErr) - return - } - - conn, connectErr := a.net.DialTCP(NetworkTypeTCP4.String(), nil, tcpAddr) - if connectErr != nil { - a.log.Warnf("Failed to dial TCP address %s: %v", turnServerAddr, connectErr) - return - } - - relAddr = conn.LocalAddr().(*net.TCPAddr).IP.String() //nolint:forcetypeassert - relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert - relayProtocol = tcp - locConn = turn.NewSTUNConn(conn) - case url.Proto == stun.ProtoTypeUDP && url.Scheme == stun.SchemeTypeTURNS: - udpAddr, connectErr := a.net.ResolveUDPAddr(network, turnServerAddr) - if connectErr != nil { - a.log.Warnf("Failed to resolve UDP address %s: %v", turnServerAddr, connectErr) - return - } - - udpConn, dialErr := a.net.DialUDP("udp", nil, udpAddr) - if dialErr != nil { - a.log.Warnf("Failed to dial DTLS address %s: %v", turnServerAddr, dialErr) - return - } - - conn, connectErr := dtls.ClientWithContext(ctx, udpConn, &dtls.Config{ - ServerName: url.Host, - InsecureSkipVerify: a.insecureSkipVerify, //nolint:gosec - }) - if connectErr != nil { - a.log.Warnf("Failed to create DTLS client: %v", turnServerAddr, connectErr) - return - } - - relAddr = conn.LocalAddr().(*net.UDPAddr).IP.String() //nolint:forcetypeassert - relPort = conn.LocalAddr().(*net.UDPAddr).Port //nolint:forcetypeassert - relayProtocol = "dtls" - locConn = &fakenet.PacketConn{Conn: conn} - case url.Proto == stun.ProtoTypeTCP && url.Scheme == stun.SchemeTypeTURNS: - tcpAddr, resolvErr := a.net.ResolveTCPAddr(NetworkTypeTCP4.String(), turnServerAddr) - if resolvErr != nil { - a.log.Warnf("Failed to resolve relay address %s: %v", turnServerAddr, resolvErr) - return - } - - tcpConn, dialErr := a.net.DialTCP(NetworkTypeTCP4.String(), nil, tcpAddr) - if dialErr != nil { - a.log.Warnf("Failed to connect to relay: %v", dialErr) - return - } - - conn := tls.Client(tcpConn, &tls.Config{ - ServerName: url.Host, - InsecureSkipVerify: a.insecureSkipVerify, //nolint:gosec - }) - - if hsErr := conn.HandshakeContext(ctx); hsErr != nil { - if closeErr := tcpConn.Close(); closeErr != nil { - a.log.Errorf("Failed to close relay connection: %v", closeErr) - } - a.log.Warnf("Failed to connect to relay: %v", hsErr) - return - } - - relAddr = conn.LocalAddr().(*net.TCPAddr).IP.String() //nolint:forcetypeassert - relPort = conn.LocalAddr().(*net.TCPAddr).Port //nolint:forcetypeassert - relayProtocol = "tls" - locConn = turn.NewSTUNConn(conn) - default: - a.log.Warnf("Unable to handle URL in gatherCandidatesRelay %v", url) - return - } - - client, err := turn.NewClient(&turn.ClientConfig{ - TURNServerAddr: turnServerAddr, - Conn: locConn, - Username: url.Username, - Password: url.Password, - LoggerFactory: a.loggerFactory, - Net: a.net, - }) - if err != nil { - closeConnAndLog(locConn, a.log, "failed to create new TURN client %s %s", turnServerAddr, err) - return - } - - if err = client.Listen(); err != nil { - client.Close() - closeConnAndLog(locConn, a.log, "failed to listen on TURN client %s %s", turnServerAddr, err) - return - } - - relayConn, err := client.Allocate() - if err != nil { - client.Close() - closeConnAndLog(locConn, a.log, "failed to allocate on TURN client %s %s", turnServerAddr, err) - return - } - - rAddr := relayConn.LocalAddr().(*net.UDPAddr) //nolint:forcetypeassert - relayConfig := CandidateRelayConfig{ - Network: network, - Component: ComponentRTP, - Address: rAddr.IP.String(), - Port: rAddr.Port, - RelAddr: relAddr, - RelPort: relPort, - RelayProtocol: relayProtocol, - OnClose: func() error { - client.Close() - return locConn.Close() - }, - } - relayConnClose := func() { - if relayConErr := relayConn.Close(); relayConErr != nil { - a.log.Warnf("Failed to close relay %v", relayConErr) - } - } - candidate, err := NewCandidateRelay(&relayConfig) - if err != nil { - relayConnClose() - - client.Close() - closeConnAndLog(locConn, a.log, "failed to create relay candidate: %s %s: %v", network, rAddr.String(), err) - return - } - - if err := a.addCandidate(ctx, candidate, relayConn); err != nil { - relayConnClose() - - if closeErr := candidate.close(); closeErr != nil { - a.log.Warnf("Failed to close candidate: %v", closeErr) - } - a.log.Warnf("Failed to append to localCandidates and run onCandidateHdlr: %v", err) - } - }(*urls[i]) - } -} diff --git a/vendor/github.com/pion/ice/v2/ice.go b/vendor/github.com/pion/ice/v2/ice.go deleted file mode 100644 index bd551206..00000000 --- a/vendor/github.com/pion/ice/v2/ice.go +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -// ConnectionState is an enum showing the state of a ICE Connection -type ConnectionState int - -// List of supported States -const ( - // ConnectionStateUnknown represents an unknown state - ConnectionStateUnknown ConnectionState = iota - - // ConnectionStateNew ICE agent is gathering addresses - ConnectionStateNew - - // ConnectionStateChecking ICE agent has been given local and remote candidates, and is attempting to find a match - ConnectionStateChecking - - // ConnectionStateConnected ICE agent has a pairing, but is still checking other pairs - ConnectionStateConnected - - // ConnectionStateCompleted ICE agent has finished - ConnectionStateCompleted - - // ConnectionStateFailed ICE agent never could successfully connect - ConnectionStateFailed - - // ConnectionStateDisconnected ICE agent connected successfully, but has entered a failed state - ConnectionStateDisconnected - - // ConnectionStateClosed ICE agent has finished and is no longer handling requests - ConnectionStateClosed -) - -func (c ConnectionState) String() string { - switch c { - case ConnectionStateNew: - return "New" - case ConnectionStateChecking: - return "Checking" - case ConnectionStateConnected: - return "Connected" - case ConnectionStateCompleted: - return "Completed" - case ConnectionStateFailed: - return "Failed" - case ConnectionStateDisconnected: - return "Disconnected" - case ConnectionStateClosed: - return "Closed" - default: - return "Invalid" - } -} - -// GatheringState describes the state of the candidate gathering process -type GatheringState int - -const ( - // GatheringStateUnknown represents an unknown state - GatheringStateUnknown GatheringState = iota - - // GatheringStateNew indicates candidate gathering is not yet started - GatheringStateNew - - // GatheringStateGathering indicates candidate gathering is ongoing - GatheringStateGathering - - // GatheringStateComplete indicates candidate gathering has been completed - GatheringStateComplete -) - -func (t GatheringState) String() string { - switch t { - case GatheringStateNew: - return "new" - case GatheringStateGathering: - return "gathering" - case GatheringStateComplete: - return "complete" - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/ice/v2/icecontrol.go b/vendor/github.com/pion/ice/v2/icecontrol.go deleted file mode 100644 index b086bd89..00000000 --- a/vendor/github.com/pion/ice/v2/icecontrol.go +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "encoding/binary" - - "github.com/pion/stun" -) - -// tiebreaker is common helper for ICE-{CONTROLLED,CONTROLLING} -// and represents the so-called tiebreaker number. -type tiebreaker uint64 - -const tiebreakerSize = 8 // 64 bit - -// AddToAs adds tiebreaker value to m as t attribute. -func (a tiebreaker) AddToAs(m *stun.Message, t stun.AttrType) error { - v := make([]byte, tiebreakerSize) - binary.BigEndian.PutUint64(v, uint64(a)) - m.Add(t, v) - return nil -} - -// GetFromAs decodes tiebreaker value in message getting it as for t type. -func (a *tiebreaker) GetFromAs(m *stun.Message, t stun.AttrType) error { - v, err := m.Get(t) - if err != nil { - return err - } - if err = stun.CheckSize(t, len(v), tiebreakerSize); err != nil { - return err - } - *a = tiebreaker(binary.BigEndian.Uint64(v)) - return nil -} - -// AttrControlled represents ICE-CONTROLLED attribute. -type AttrControlled uint64 - -// AddTo adds ICE-CONTROLLED to message. -func (c AttrControlled) AddTo(m *stun.Message) error { - return tiebreaker(c).AddToAs(m, stun.AttrICEControlled) -} - -// GetFrom decodes ICE-CONTROLLED from message. -func (c *AttrControlled) GetFrom(m *stun.Message) error { - return (*tiebreaker)(c).GetFromAs(m, stun.AttrICEControlled) -} - -// AttrControlling represents ICE-CONTROLLING attribute. -type AttrControlling uint64 - -// AddTo adds ICE-CONTROLLING to message. -func (c AttrControlling) AddTo(m *stun.Message) error { - return tiebreaker(c).AddToAs(m, stun.AttrICEControlling) -} - -// GetFrom decodes ICE-CONTROLLING from message. -func (c *AttrControlling) GetFrom(m *stun.Message) error { - return (*tiebreaker)(c).GetFromAs(m, stun.AttrICEControlling) -} - -// AttrControl is helper that wraps ICE-{CONTROLLED,CONTROLLING}. -type AttrControl struct { - Role Role - Tiebreaker uint64 -} - -// AddTo adds ICE-CONTROLLED or ICE-CONTROLLING attribute depending on Role. -func (c AttrControl) AddTo(m *stun.Message) error { - if c.Role == Controlling { - return tiebreaker(c.Tiebreaker).AddToAs(m, stun.AttrICEControlling) - } - return tiebreaker(c.Tiebreaker).AddToAs(m, stun.AttrICEControlled) -} - -// GetFrom decodes Role and Tiebreaker value from message. -func (c *AttrControl) GetFrom(m *stun.Message) error { - if m.Contains(stun.AttrICEControlling) { - c.Role = Controlling - return (*tiebreaker)(&c.Tiebreaker).GetFromAs(m, stun.AttrICEControlling) - } - if m.Contains(stun.AttrICEControlled) { - c.Role = Controlled - return (*tiebreaker)(&c.Tiebreaker).GetFromAs(m, stun.AttrICEControlled) - } - return stun.ErrAttributeNotFound -} diff --git a/vendor/github.com/pion/ice/v2/internal/atomic/atomic.go b/vendor/github.com/pion/ice/v2/internal/atomic/atomic.go deleted file mode 100644 index f8caf5a2..00000000 --- a/vendor/github.com/pion/ice/v2/internal/atomic/atomic.go +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package atomic contains custom atomic types -package atomic - -import "sync/atomic" - -// Error is an atomic error -type Error struct { - v atomic.Value -} - -// Store updates the value of the atomic variable -func (a *Error) Store(err error) { - a.v.Store(struct{ error }{err}) -} - -// Load retrieves the current value of the atomic variable -func (a *Error) Load() error { - err, _ := a.v.Load().(struct{ error }) - return err.error -} diff --git a/vendor/github.com/pion/ice/v2/internal/fakenet/mock_conn.go b/vendor/github.com/pion/ice/v2/internal/fakenet/mock_conn.go deleted file mode 100644 index cc98849d..00000000 --- a/vendor/github.com/pion/ice/v2/internal/fakenet/mock_conn.go +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package fakenet - -import ( - "net" - "time" -) - -// MockPacketConn for tests -type MockPacketConn struct{} - -func (m *MockPacketConn) ReadFrom([]byte) (n int, addr net.Addr, err error) { return 0, nil, nil } //nolint:revive -func (m *MockPacketConn) WriteTo([]byte, net.Addr) (n int, err error) { return 0, nil } //nolint:revive -func (m *MockPacketConn) Close() error { return nil } //nolint:revive -func (m *MockPacketConn) LocalAddr() net.Addr { return nil } //nolint:revive -func (m *MockPacketConn) SetDeadline(time.Time) error { return nil } //nolint:revive -func (m *MockPacketConn) SetReadDeadline(time.Time) error { return nil } //nolint:revive -func (m *MockPacketConn) SetWriteDeadline(time.Time) error { return nil } //nolint:revive diff --git a/vendor/github.com/pion/ice/v2/internal/fakenet/packet_conn.go b/vendor/github.com/pion/ice/v2/internal/fakenet/packet_conn.go deleted file mode 100644 index 0b9faaa8..00000000 --- a/vendor/github.com/pion/ice/v2/internal/fakenet/packet_conn.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package fakenet contains fake network abstractions -package fakenet - -import ( - "net" -) - -// Compile-time assertion -var _ net.PacketConn = (*PacketConn)(nil) - -// PacketConn wraps a net.Conn and emulates net.PacketConn -type PacketConn struct { - net.Conn -} - -// ReadFrom reads a packet from the connection, -func (f *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { - n, err = f.Conn.Read(p) - addr = f.Conn.RemoteAddr() - return -} - -// WriteTo writes a packet with payload p to addr. -func (f *PacketConn) WriteTo(p []byte, _ net.Addr) (int, error) { - return f.Conn.Write(p) -} diff --git a/vendor/github.com/pion/ice/v2/internal/stun/stun.go b/vendor/github.com/pion/ice/v2/internal/stun/stun.go deleted file mode 100644 index 230cf850..00000000 --- a/vendor/github.com/pion/ice/v2/internal/stun/stun.go +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package stun contains ICE specific STUN code -package stun - -import ( - "errors" - "fmt" - "net" - "time" - - "github.com/pion/stun" -) - -var ( - errGetXorMappedAddrResponse = errors.New("failed to get XOR-MAPPED-ADDRESS response") - errMismatchUsername = errors.New("username mismatch") -) - -// GetXORMappedAddr initiates a STUN requests to serverAddr using conn, reads the response and returns -// the XORMappedAddress returned by the STUN server. -func GetXORMappedAddr(conn net.PacketConn, serverAddr net.Addr, timeout time.Duration) (*stun.XORMappedAddress, error) { - if timeout > 0 { - if err := conn.SetReadDeadline(time.Now().Add(timeout)); err != nil { - return nil, err - } - - // Reset timeout after completion - defer conn.SetReadDeadline(time.Time{}) //nolint:errcheck - } - - req, err := stun.Build(stun.BindingRequest, stun.TransactionID) - if err != nil { - return nil, err - } - - if _, err = conn.WriteTo(req.Raw, serverAddr); err != nil { - return nil, err - } - - const maxMessageSize = 1280 - buf := make([]byte, maxMessageSize) - n, _, err := conn.ReadFrom(buf) - if err != nil { - return nil, err - } - - res := &stun.Message{Raw: buf[:n]} - if err = res.Decode(); err != nil { - return nil, err - } - - var addr stun.XORMappedAddress - if err = addr.GetFrom(res); err != nil { - return nil, fmt.Errorf("%w: %v", errGetXorMappedAddrResponse, err) //nolint:errorlint - } - - return &addr, nil -} - -// AssertUsername checks that the given STUN message m has a USERNAME attribute with a given value -func AssertUsername(m *stun.Message, expectedUsername string) error { - var username stun.Username - if err := username.GetFrom(m); err != nil { - return err - } else if string(username) != expectedUsername { - return fmt.Errorf("%w expected(%x) actual(%x)", errMismatchUsername, expectedUsername, string(username)) - } - - return nil -} diff --git a/vendor/github.com/pion/ice/v2/mdns.go b/vendor/github.com/pion/ice/v2/mdns.go deleted file mode 100644 index aa823164..00000000 --- a/vendor/github.com/pion/ice/v2/mdns.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "github.com/google/uuid" - "github.com/pion/logging" - "github.com/pion/mdns" - "github.com/pion/transport/v2" - "golang.org/x/net/ipv4" -) - -// MulticastDNSMode represents the different Multicast modes ICE can run in -type MulticastDNSMode byte - -// MulticastDNSMode enum -const ( - // MulticastDNSModeDisabled means remote mDNS candidates will be discarded, and local host candidates will use IPs - MulticastDNSModeDisabled MulticastDNSMode = iota + 1 - - // MulticastDNSModeQueryOnly means remote mDNS candidates will be accepted, and local host candidates will use IPs - MulticastDNSModeQueryOnly - - // MulticastDNSModeQueryAndGather means remote mDNS candidates will be accepted, and local host candidates will use mDNS - MulticastDNSModeQueryAndGather -) - -func generateMulticastDNSName() (string, error) { - // https://tools.ietf.org/id/draft-ietf-rtcweb-mdns-ice-candidates-02.html#gathering - // The unique name MUST consist of a version 4 UUID as defined in [RFC4122], followed by “.local”. - u, err := uuid.NewRandom() - return u.String() + ".local", err -} - -func createMulticastDNS(n transport.Net, mDNSMode MulticastDNSMode, mDNSName string, log logging.LeveledLogger) (*mdns.Conn, MulticastDNSMode, error) { - if mDNSMode == MulticastDNSModeDisabled { - return nil, mDNSMode, nil - } - - addr, mdnsErr := n.ResolveUDPAddr("udp4", mdns.DefaultAddress) - if mdnsErr != nil { - return nil, mDNSMode, mdnsErr - } - - l, mdnsErr := n.ListenUDP("udp4", addr) - if mdnsErr != nil { - // If ICE fails to start MulticastDNS server just warn the user and continue - log.Errorf("Failed to enable mDNS, continuing in mDNS disabled mode: (%s)", mdnsErr) - return nil, MulticastDNSModeDisabled, nil - } - - switch mDNSMode { - case MulticastDNSModeQueryOnly: - conn, err := mdns.Server(ipv4.NewPacketConn(l), &mdns.Config{}) - return conn, mDNSMode, err - case MulticastDNSModeQueryAndGather: - conn, err := mdns.Server(ipv4.NewPacketConn(l), &mdns.Config{ - LocalNames: []string{mDNSName}, - }) - return conn, mDNSMode, err - default: - return nil, mDNSMode, nil - } -} diff --git a/vendor/github.com/pion/ice/v2/net.go b/vendor/github.com/pion/ice/v2/net.go deleted file mode 100644 index d716bc19..00000000 --- a/vendor/github.com/pion/ice/v2/net.go +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" - - "github.com/pion/logging" - "github.com/pion/transport/v2" -) - -// The conditions of invalidation written below are defined in -// https://tools.ietf.org/html/rfc8445#section-5.1.1.1 -func isSupportedIPv6(ip net.IP) bool { - if len(ip) != net.IPv6len || - isZeros(ip[0:12]) || // !(IPv4-compatible IPv6) - ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 || // !(IPv6 site-local unicast) - ip.IsLinkLocalUnicast() || - ip.IsLinkLocalMulticast() { - return false - } - return true -} - -func isZeros(ip net.IP) bool { - for i := 0; i < len(ip); i++ { - if ip[i] != 0 { - return false - } - } - return true -} - -func localInterfaces(n transport.Net, interfaceFilter func(string) bool, ipFilter func(net.IP) bool, networkTypes []NetworkType, includeLoopback bool) ([]net.IP, error) { //nolint:gocognit - ips := []net.IP{} - ifaces, err := n.Interfaces() - if err != nil { - return ips, err - } - - var IPv4Requested, IPv6Requested bool - for _, typ := range networkTypes { - if typ.IsIPv4() { - IPv4Requested = true - } - - if typ.IsIPv6() { - IPv6Requested = true - } - } - - for _, iface := range ifaces { - if iface.Flags&net.FlagUp == 0 { - continue // Interface down - } - if (iface.Flags&net.FlagLoopback != 0) && !includeLoopback { - continue // Loopback interface - } - - if interfaceFilter != nil && !interfaceFilter(iface.Name) { - continue - } - - addrs, err := iface.Addrs() - if err != nil { - continue - } - - for _, addr := range addrs { - var ip net.IP - switch addr := addr.(type) { - case *net.IPNet: - ip = addr.IP - case *net.IPAddr: - ip = addr.IP - } - if ip == nil || (ip.IsLoopback() && !includeLoopback) { - continue - } - - if ipv4 := ip.To4(); ipv4 == nil { - if !IPv6Requested { - continue - } else if !isSupportedIPv6(ip) { - continue - } - } else if !IPv4Requested { - continue - } - - if ipFilter != nil && !ipFilter(ip) { - continue - } - - ips = append(ips, ip) - } - } - return ips, nil -} - -func listenUDPInPortRange(n transport.Net, log logging.LeveledLogger, portMax, portMin int, network string, lAddr *net.UDPAddr) (transport.UDPConn, error) { - if (lAddr.Port != 0) || ((portMin == 0) && (portMax == 0)) { - return n.ListenUDP(network, lAddr) - } - var i, j int - i = portMin - if i == 0 { - i = 1 - } - j = portMax - if j == 0 { - j = 0xFFFF - } - if i > j { - return nil, ErrPort - } - - portStart := globalMathRandomGenerator.Intn(j-i+1) + i - portCurrent := portStart - for { - lAddr = &net.UDPAddr{IP: lAddr.IP, Port: portCurrent} - c, e := n.ListenUDP(network, lAddr) - if e == nil { - return c, e //nolint:nilerr - } - log.Debugf("Failed to listen %s: %v", lAddr.String(), e) - portCurrent++ - if portCurrent > j { - portCurrent = i - } - if portCurrent == portStart { - break - } - } - return nil, ErrPort -} diff --git a/vendor/github.com/pion/ice/v2/networktype.go b/vendor/github.com/pion/ice/v2/networktype.go deleted file mode 100644 index 57df1863..00000000 --- a/vendor/github.com/pion/ice/v2/networktype.go +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "fmt" - "net" - "strings" -) - -const ( - udp = "udp" - tcp = "tcp" - udp4 = "udp4" - udp6 = "udp6" - tcp4 = "tcp4" - tcp6 = "tcp6" -) - -func supportedNetworkTypes() []NetworkType { - return []NetworkType{ - NetworkTypeUDP4, - NetworkTypeUDP6, - NetworkTypeTCP4, - NetworkTypeTCP6, - } -} - -// NetworkType represents the type of network -type NetworkType int - -const ( - // NetworkTypeUDP4 indicates UDP over IPv4. - NetworkTypeUDP4 NetworkType = iota + 1 - - // NetworkTypeUDP6 indicates UDP over IPv6. - NetworkTypeUDP6 - - // NetworkTypeTCP4 indicates TCP over IPv4. - NetworkTypeTCP4 - - // NetworkTypeTCP6 indicates TCP over IPv6. - NetworkTypeTCP6 -) - -func (t NetworkType) String() string { - switch t { - case NetworkTypeUDP4: - return udp4 - case NetworkTypeUDP6: - return udp6 - case NetworkTypeTCP4: - return tcp4 - case NetworkTypeTCP6: - return tcp6 - default: - return ErrUnknownType.Error() - } -} - -// IsUDP returns true when network is UDP4 or UDP6. -func (t NetworkType) IsUDP() bool { - return t == NetworkTypeUDP4 || t == NetworkTypeUDP6 -} - -// IsTCP returns true when network is TCP4 or TCP6. -func (t NetworkType) IsTCP() bool { - return t == NetworkTypeTCP4 || t == NetworkTypeTCP6 -} - -// NetworkShort returns the short network description -func (t NetworkType) NetworkShort() string { - switch t { - case NetworkTypeUDP4, NetworkTypeUDP6: - return udp - case NetworkTypeTCP4, NetworkTypeTCP6: - return tcp - default: - return ErrUnknownType.Error() - } -} - -// IsReliable returns true if the network is reliable -func (t NetworkType) IsReliable() bool { - switch t { - case NetworkTypeUDP4, NetworkTypeUDP6: - return false - case NetworkTypeTCP4, NetworkTypeTCP6: - return true - } - return false -} - -// IsIPv4 returns whether the network type is IPv4 or not. -func (t NetworkType) IsIPv4() bool { - switch t { - case NetworkTypeUDP4, NetworkTypeTCP4: - return true - case NetworkTypeUDP6, NetworkTypeTCP6: - return false - } - return false -} - -// IsIPv6 returns whether the network type is IPv6 or not. -func (t NetworkType) IsIPv6() bool { - switch t { - case NetworkTypeUDP4, NetworkTypeTCP4: - return false - case NetworkTypeUDP6, NetworkTypeTCP6: - return true - } - return false -} - -// determineNetworkType determines the type of network based on -// the short network string and an IP address. -func determineNetworkType(network string, ip net.IP) (NetworkType, error) { - ipv4 := ip.To4() != nil - - switch { - case strings.HasPrefix(strings.ToLower(network), udp): - if ipv4 { - return NetworkTypeUDP4, nil - } - return NetworkTypeUDP6, nil - - case strings.HasPrefix(strings.ToLower(network), tcp): - if ipv4 { - return NetworkTypeTCP4, nil - } - return NetworkTypeTCP6, nil - } - - return NetworkType(0), fmt.Errorf("%w from %s %s", ErrDetermineNetworkType, network, ip) -} diff --git a/vendor/github.com/pion/ice/v2/priority.go b/vendor/github.com/pion/ice/v2/priority.go deleted file mode 100644 index 16ac5cc7..00000000 --- a/vendor/github.com/pion/ice/v2/priority.go +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "encoding/binary" - - "github.com/pion/stun" -) - -// PriorityAttr represents PRIORITY attribute. -type PriorityAttr uint32 - -const prioritySize = 4 // 32 bit - -// AddTo adds PRIORITY attribute to message. -func (p PriorityAttr) AddTo(m *stun.Message) error { - v := make([]byte, prioritySize) - binary.BigEndian.PutUint32(v, uint32(p)) - m.Add(stun.AttrPriority, v) - return nil -} - -// GetFrom decodes PRIORITY attribute from message. -func (p *PriorityAttr) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrPriority) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrPriority, len(v), prioritySize); err != nil { - return err - } - *p = PriorityAttr(binary.BigEndian.Uint32(v)) - return nil -} diff --git a/vendor/github.com/pion/ice/v2/rand.go b/vendor/github.com/pion/ice/v2/rand.go deleted file mode 100644 index 3de1f040..00000000 --- a/vendor/github.com/pion/ice/v2/rand.go +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "github.com/pion/randutil" - -const ( - runesAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - runesDigit = "0123456789" - runesCandidateIDFoundation = runesAlpha + runesDigit + "+/" - - lenUFrag = 16 - lenPwd = 32 -) - -// Seeding random generator each time limits number of generated sequence to 31-bits, -// and causes collision on low time accuracy environments. -// Use global random generator seeded by crypto grade random. -var ( - globalMathRandomGenerator = randutil.NewMathRandomGenerator() //nolint:gochecknoglobals - globalCandidateIDGenerator = candidateIDGenerator{globalMathRandomGenerator} //nolint:gochecknoglobals -) - -// candidateIDGenerator is a random candidate ID generator. -// Candidate ID is used in SDP and always shared to the other peer. -// It doesn't require cryptographic random. -type candidateIDGenerator struct { - randutil.MathRandomGenerator -} - -func newCandidateIDGenerator() *candidateIDGenerator { - return &candidateIDGenerator{ - randutil.NewMathRandomGenerator(), - } -} - -func (g *candidateIDGenerator) Generate() string { - // https://tools.ietf.org/html/rfc5245#section-15.1 - // candidate-id = "candidate" ":" foundation - // foundation = 1*32ice-char - // ice-char = ALPHA / DIGIT / "+" / "/" - return "candidate:" + g.MathRandomGenerator.GenerateString(32, runesCandidateIDFoundation) -} - -// generatePwd generates ICE pwd. -// This internally uses generateCryptoRandomString. -func generatePwd() (string, error) { - return randutil.GenerateCryptoRandomString(lenPwd, runesAlpha) -} - -// generateUFrag generates ICE user fragment. -// This internally uses generateCryptoRandomString. -func generateUFrag() (string, error) { - return randutil.GenerateCryptoRandomString(lenUFrag, runesAlpha) -} diff --git a/vendor/github.com/pion/ice/v2/renovate.json b/vendor/github.com/pion/ice/v2/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/ice/v2/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/ice/v2/role.go b/vendor/github.com/pion/ice/v2/role.go deleted file mode 100644 index e9a7bda9..00000000 --- a/vendor/github.com/pion/ice/v2/role.go +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "fmt" -) - -// Role represents ICE agent role, which can be controlling or controlled. -type Role byte - -// Possible ICE agent roles. -const ( - Controlling Role = iota - Controlled -) - -// UnmarshalText implements TextUnmarshaler. -func (r *Role) UnmarshalText(text []byte) error { - switch string(text) { - case "controlling": - *r = Controlling - case "controlled": - *r = Controlled - default: - return fmt.Errorf("%w %q", errUnknownRole, text) - } - return nil -} - -// MarshalText implements TextMarshaler. -func (r Role) MarshalText() (text []byte, err error) { - return []byte(r.String()), nil -} - -func (r Role) String() string { - switch r { - case Controlling: - return "controlling" - case Controlled: - return "controlled" - default: - return "unknown" - } -} diff --git a/vendor/github.com/pion/ice/v2/selection.go b/vendor/github.com/pion/ice/v2/selection.go deleted file mode 100644 index 9f312637..00000000 --- a/vendor/github.com/pion/ice/v2/selection.go +++ /dev/null @@ -1,299 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "net" - "time" - - "github.com/pion/logging" - "github.com/pion/stun" -) - -type pairCandidateSelector interface { - Start() - ContactCandidates() - PingCandidate(local, remote Candidate) - HandleSuccessResponse(m *stun.Message, local, remote Candidate, remoteAddr net.Addr) - HandleBindingRequest(m *stun.Message, local, remote Candidate) -} - -type controllingSelector struct { - startTime time.Time - agent *Agent - nominatedPair *CandidatePair - log logging.LeveledLogger -} - -func (s *controllingSelector) Start() { - s.startTime = time.Now() - s.nominatedPair = nil -} - -func (s *controllingSelector) isNominatable(c Candidate) bool { - switch { - case c.Type() == CandidateTypeHost: - return time.Since(s.startTime).Nanoseconds() > s.agent.hostAcceptanceMinWait.Nanoseconds() - case c.Type() == CandidateTypeServerReflexive: - return time.Since(s.startTime).Nanoseconds() > s.agent.srflxAcceptanceMinWait.Nanoseconds() - case c.Type() == CandidateTypePeerReflexive: - return time.Since(s.startTime).Nanoseconds() > s.agent.prflxAcceptanceMinWait.Nanoseconds() - case c.Type() == CandidateTypeRelay: - return time.Since(s.startTime).Nanoseconds() > s.agent.relayAcceptanceMinWait.Nanoseconds() - } - - s.log.Errorf("Invalid candidate type: %s", c.Type()) - return false -} - -func (s *controllingSelector) ContactCandidates() { - switch { - case s.agent.getSelectedPair() != nil: - if s.agent.validateSelectedPair() { - s.log.Trace("checking keepalive") - s.agent.checkKeepalive() - } - case s.nominatedPair != nil: - s.nominatePair(s.nominatedPair) - default: - p := s.agent.getBestValidCandidatePair() - if p != nil && s.isNominatable(p.Local) && s.isNominatable(p.Remote) { - s.log.Tracef("Nominatable pair found, nominating (%s, %s)", p.Local.String(), p.Remote.String()) - p.nominated = true - s.nominatedPair = p - s.nominatePair(p) - return - } - s.agent.pingAllCandidates() - } -} - -func (s *controllingSelector) nominatePair(pair *CandidatePair) { - // The controlling agent MUST include the USE-CANDIDATE attribute in - // order to nominate a candidate pair (Section 8.1.1). The controlled - // agent MUST NOT include the USE-CANDIDATE attribute in a Binding - // request. - msg, err := stun.Build(stun.BindingRequest, stun.TransactionID, - stun.NewUsername(s.agent.remoteUfrag+":"+s.agent.localUfrag), - UseCandidate(), - AttrControlling(s.agent.tieBreaker), - PriorityAttr(pair.Local.Priority()), - stun.NewShortTermIntegrity(s.agent.remotePwd), - stun.Fingerprint, - ) - if err != nil { - s.log.Error(err.Error()) - return - } - - s.log.Tracef("ping STUN (nominate candidate pair) from %s to %s", pair.Local.String(), pair.Remote.String()) - s.agent.sendBindingRequest(msg, pair.Local, pair.Remote) -} - -func (s *controllingSelector) HandleBindingRequest(m *stun.Message, local, remote Candidate) { - s.agent.sendBindingSuccess(m, local, remote) - - p := s.agent.findPair(local, remote) - - if p == nil { - s.agent.addPair(local, remote) - return - } - - if p.state == CandidatePairStateSucceeded && s.nominatedPair == nil && s.agent.getSelectedPair() == nil { - bestPair := s.agent.getBestAvailableCandidatePair() - if bestPair == nil { - s.log.Tracef("No best pair available") - } else if bestPair.equal(p) && s.isNominatable(p.Local) && s.isNominatable(p.Remote) { - s.log.Tracef("The candidate (%s, %s) is the best candidate available, marking it as nominated", - p.Local.String(), p.Remote.String()) - s.nominatedPair = p - s.nominatePair(p) - } - } -} - -func (s *controllingSelector) HandleSuccessResponse(m *stun.Message, local, remote Candidate, remoteAddr net.Addr) { - ok, pendingRequest := s.agent.handleInboundBindingSuccess(m.TransactionID) - if !ok { - s.log.Warnf("Discard message from (%s), unknown TransactionID 0x%x", remote, m.TransactionID) - return - } - - transactionAddr := pendingRequest.destination - - // Assert that NAT is not symmetric - // https://tools.ietf.org/html/rfc8445#section-7.2.5.2.1 - if !addrEqual(transactionAddr, remoteAddr) { - s.log.Debugf("Discard message: transaction source and destination does not match expected(%s), actual(%s)", transactionAddr, remote) - return - } - - s.log.Tracef("inbound STUN (SuccessResponse) from %s to %s", remote.String(), local.String()) - p := s.agent.findPair(local, remote) - - if p == nil { - // This shouldn't happen - s.log.Error("Success response from invalid candidate pair") - return - } - - p.state = CandidatePairStateSucceeded - s.log.Tracef("Found valid candidate pair: %s", p) - if pendingRequest.isUseCandidate && s.agent.getSelectedPair() == nil { - s.agent.setSelectedPair(p) - } -} - -func (s *controllingSelector) PingCandidate(local, remote Candidate) { - msg, err := stun.Build(stun.BindingRequest, stun.TransactionID, - stun.NewUsername(s.agent.remoteUfrag+":"+s.agent.localUfrag), - AttrControlling(s.agent.tieBreaker), - PriorityAttr(local.Priority()), - stun.NewShortTermIntegrity(s.agent.remotePwd), - stun.Fingerprint, - ) - if err != nil { - s.log.Error(err.Error()) - return - } - - s.agent.sendBindingRequest(msg, local, remote) -} - -type controlledSelector struct { - agent *Agent - log logging.LeveledLogger -} - -func (s *controlledSelector) Start() { -} - -func (s *controlledSelector) ContactCandidates() { - if s.agent.getSelectedPair() != nil { - if s.agent.validateSelectedPair() { - s.log.Trace("checking keepalive") - s.agent.checkKeepalive() - } - } else { - s.agent.pingAllCandidates() - } -} - -func (s *controlledSelector) PingCandidate(local, remote Candidate) { - msg, err := stun.Build(stun.BindingRequest, stun.TransactionID, - stun.NewUsername(s.agent.remoteUfrag+":"+s.agent.localUfrag), - AttrControlled(s.agent.tieBreaker), - PriorityAttr(local.Priority()), - stun.NewShortTermIntegrity(s.agent.remotePwd), - stun.Fingerprint, - ) - if err != nil { - s.log.Error(err.Error()) - return - } - - s.agent.sendBindingRequest(msg, local, remote) -} - -func (s *controlledSelector) HandleSuccessResponse(m *stun.Message, local, remote Candidate, remoteAddr net.Addr) { - //nolint:godox - // TODO according to the standard we should specifically answer a failed nomination: - // https://tools.ietf.org/html/rfc8445#section-7.3.1.5 - // If the controlled agent does not accept the request from the - // controlling agent, the controlled agent MUST reject the nomination - // request with an appropriate error code response (e.g., 400) - // [RFC5389]. - - ok, pendingRequest := s.agent.handleInboundBindingSuccess(m.TransactionID) - if !ok { - s.log.Warnf("Discard message from (%s), unknown TransactionID 0x%x", remote, m.TransactionID) - return - } - - transactionAddr := pendingRequest.destination - - // Assert that NAT is not symmetric - // https://tools.ietf.org/html/rfc8445#section-7.2.5.2.1 - if !addrEqual(transactionAddr, remoteAddr) { - s.log.Debugf("Discard message: transaction source and destination does not match expected(%s), actual(%s)", transactionAddr, remote) - return - } - - s.log.Tracef("inbound STUN (SuccessResponse) from %s to %s", remote.String(), local.String()) - - p := s.agent.findPair(local, remote) - if p == nil { - // This shouldn't happen - s.log.Error("Success response from invalid candidate pair") - return - } - - p.state = CandidatePairStateSucceeded - s.log.Tracef("Found valid candidate pair: %s", p) - if p.nominateOnBindingSuccess { - if selectedPair := s.agent.getSelectedPair(); selectedPair == nil || - (selectedPair != p && selectedPair.priority() <= p.priority()) { - s.agent.setSelectedPair(p) - } else if selectedPair != p { - s.log.Tracef("ignore nominate new pair %s, already nominated pair %s", p, selectedPair) - } - } -} - -func (s *controlledSelector) HandleBindingRequest(m *stun.Message, local, remote Candidate) { - useCandidate := m.Contains(stun.AttrUseCandidate) - - p := s.agent.findPair(local, remote) - if p == nil { - p = s.agent.addPair(local, remote) - } - - if useCandidate { - // https://tools.ietf.org/html/rfc8445#section-7.3.1.5 - - if p.state == CandidatePairStateSucceeded { - // If the state of this pair is Succeeded, it means that the check - // previously sent by this pair produced a successful response and - // generated a valid pair (Section 7.2.5.3.2). The agent sets the - // nominated flag value of the valid pair to true. - if selectedPair := s.agent.getSelectedPair(); selectedPair == nil || - (selectedPair != p && selectedPair.priority() <= p.priority()) { - s.agent.setSelectedPair(p) - } else if selectedPair != p { - s.log.Tracef("ignore nominate new pair %s, already nominated pair %s", p, selectedPair) - } - } else { - // If the received Binding request triggered a new check to be - // enqueued in the triggered-check queue (Section 7.3.1.4), once the - // check is sent and if it generates a successful response, and - // generates a valid pair, the agent sets the nominated flag of the - // pair to true. If the request fails (Section 7.2.5.2), the agent - // MUST remove the candidate pair from the valid list, set the - // candidate pair state to Failed, and set the checklist state to - // Failed. - p.nominateOnBindingSuccess = true - } - } - - s.agent.sendBindingSuccess(m, local, remote) - s.PingCandidate(local, remote) -} - -type liteSelector struct { - pairCandidateSelector -} - -// A lite selector should not contact candidates -func (s *liteSelector) ContactCandidates() { - if _, ok := s.pairCandidateSelector.(*controllingSelector); ok { - //nolint:godox - // https://github.com/pion/ice/issues/96 - // TODO: implement lite controlling agent. For now falling back to full agent. - // This only happens if both peers are lite. See RFC 8445 S6.1.1 and S6.2 - s.pairCandidateSelector.ContactCandidates() - } else if v, ok := s.pairCandidateSelector.(*controlledSelector); ok { - v.agent.validateSelectedPair() - } -} diff --git a/vendor/github.com/pion/ice/v2/stats.go b/vendor/github.com/pion/ice/v2/stats.go deleted file mode 100644 index 9b83bea8..00000000 --- a/vendor/github.com/pion/ice/v2/stats.go +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "time" -) - -// CandidatePairStats contains ICE candidate pair statistics -type CandidatePairStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp time.Time - - // LocalCandidateID is the ID of the local candidate - LocalCandidateID string - - // RemoteCandidateID is the ID of the remote candidate - RemoteCandidateID string - - // State represents the state of the checklist for the local and remote - // candidates in a pair. - State CandidatePairState - - // Nominated is true when this valid pair that should be used for media - // if it is the highest-priority one amongst those whose nominated flag is set - Nominated bool - - // PacketsSent represents the total number of packets sent on this candidate pair. - PacketsSent uint32 - - // PacketsReceived represents the total number of packets received on this candidate pair. - PacketsReceived uint32 - - // BytesSent represents the total number of payload bytes sent on this candidate pair - // not including headers or padding. - BytesSent uint64 - - // BytesReceived represents the total number of payload bytes received on this candidate pair - // not including headers or padding. - BytesReceived uint64 - - // LastPacketSentTimestamp represents the timestamp at which the last packet was - // sent on this particular candidate pair, excluding STUN packets. - LastPacketSentTimestamp time.Time - - // LastPacketReceivedTimestamp represents the timestamp at which the last packet - // was received on this particular candidate pair, excluding STUN packets. - LastPacketReceivedTimestamp time.Time - - // FirstRequestTimestamp represents the timestamp at which the first STUN request - // was sent on this particular candidate pair. - FirstRequestTimestamp time.Time - - // LastRequestTimestamp represents the timestamp at which the last STUN request - // was sent on this particular candidate pair. The average interval between two - // consecutive connectivity checks sent can be calculated with - // (LastRequestTimestamp - FirstRequestTimestamp) / RequestsSent. - LastRequestTimestamp time.Time - - // LastResponseTimestamp represents the timestamp at which the last STUN response - // was received on this particular candidate pair. - LastResponseTimestamp time.Time - - // TotalRoundTripTime represents the sum of all round trip time measurements - // in seconds since the beginning of the session, based on STUN connectivity - // check responses (ResponsesReceived), including those that reply to requests - // that are sent in order to verify consent. The average round trip time can - // be computed from TotalRoundTripTime by dividing it by ResponsesReceived. - TotalRoundTripTime float64 - - // CurrentRoundTripTime represents the latest round trip time measured in seconds, - // computed from both STUN connectivity checks, including those that are sent - // for consent verification. - CurrentRoundTripTime float64 - - // AvailableOutgoingBitrate is calculated by the underlying congestion control - // by combining the available bitrate for all the outgoing RTP streams using - // this candidate pair. The bitrate measurement does not count the size of the - // IP or other transport layers like TCP or UDP. It is similar to the TIAS defined - // in RFC 3890, i.e., it is measured in bits per second and the bitrate is calculated - // over a 1 second window. - AvailableOutgoingBitrate float64 - - // AvailableIncomingBitrate is calculated by the underlying congestion control - // by combining the available bitrate for all the incoming RTP streams using - // this candidate pair. The bitrate measurement does not count the size of the - // IP or other transport layers like TCP or UDP. It is similar to the TIAS defined - // in RFC 3890, i.e., it is measured in bits per second and the bitrate is - // calculated over a 1 second window. - AvailableIncomingBitrate float64 - - // CircuitBreakerTriggerCount represents the number of times the circuit breaker - // is triggered for this particular 5-tuple, ceasing transmission. - CircuitBreakerTriggerCount uint32 - - // RequestsReceived represents the total number of connectivity check requests - // received (including retransmissions). It is impossible for the receiver to - // tell whether the request was sent in order to check connectivity or check - // consent, so all connectivity checks requests are counted here. - RequestsReceived uint64 - - // RequestsSent represents the total number of connectivity check requests - // sent (not including retransmissions). - RequestsSent uint64 - - // ResponsesReceived represents the total number of connectivity check responses received. - ResponsesReceived uint64 - - // ResponsesSent represents the total number of connectivity check responses sent. - // Since we cannot distinguish connectivity check requests and consent requests, - // all responses are counted. - ResponsesSent uint64 - - // RetransmissionsReceived represents the total number of connectivity check - // request retransmissions received. - RetransmissionsReceived uint64 - - // RetransmissionsSent represents the total number of connectivity check - // request retransmissions sent. - RetransmissionsSent uint64 - - // ConsentRequestsSent represents the total number of consent requests sent. - ConsentRequestsSent uint64 - - // ConsentExpiredTimestamp represents the timestamp at which the latest valid - // STUN binding response expired. - ConsentExpiredTimestamp time.Time -} - -// CandidateStats contains ICE candidate statistics related to the ICETransport objects. -type CandidateStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp time.Time - - // ID is the candidate ID - ID string - - // NetworkType represents the type of network interface used by the base of a - // local candidate (the address the ICE agent sends from). Only present for - // local candidates; it's not possible to know what type of network interface - // a remote candidate is using. - // - // Note: - // This stat only tells you about the network interface used by the first "hop"; - // it's possible that a connection will be bottlenecked by another type of network. - // For example, when using Wi-Fi tethering, the networkType of the relevant candidate - // would be "wifi", even when the next hop is over a cellular connection. - NetworkType NetworkType - - // IP is the IP address of the candidate, allowing for IPv4 addresses and - // IPv6 addresses, but fully qualified domain names (FQDNs) are not allowed. - IP string - - // Port is the port number of the candidate. - Port int - - // CandidateType is the "Type" field of the ICECandidate. - CandidateType CandidateType - - // Priority is the "Priority" field of the ICECandidate. - Priority uint32 - - // URL is the URL of the TURN or STUN server indicated in the that translated - // this IP address. It is the URL address surfaced in an PeerConnectionICEEvent. - URL string - - // RelayProtocol is the protocol used by the endpoint to communicate with the - // TURN server. This is only present for local candidates. Valid values for - // the TURN URL protocol is one of UDP, TCP, or TLS. - RelayProtocol string - - // Deleted is true if the candidate has been deleted/freed. For host candidates, - // this means that any network resources (typically a socket) associated with the - // candidate have been released. For TURN candidates, this means the TURN allocation - // is no longer active. - // - // Only defined for local candidates. For remote candidates, this property is not applicable. - Deleted bool -} diff --git a/vendor/github.com/pion/ice/v2/tcp_mux.go b/vendor/github.com/pion/ice/v2/tcp_mux.go deleted file mode 100644 index fb4e5243..00000000 --- a/vendor/github.com/pion/ice/v2/tcp_mux.go +++ /dev/null @@ -1,396 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "encoding/binary" - "errors" - "io" - "net" - "strings" - "sync" - - "github.com/pion/logging" - "github.com/pion/stun" -) - -// ErrGetTransportAddress can't convert net.Addr to underlying type (UDPAddr or TCPAddr). -var ErrGetTransportAddress = errors.New("failed to get local transport address") - -// TCPMux is allows grouping multiple TCP net.Conns and using them like UDP -// net.PacketConns. The main implementation of this is TCPMuxDefault, and this -// interface exists to allow mocking in tests. -type TCPMux interface { - io.Closer - GetConnByUfrag(ufrag string, isIPv6 bool, local net.IP) (net.PacketConn, error) - RemoveConnByUfrag(ufrag string) -} - -type ipAddr string - -// TCPMuxDefault muxes TCP net.Conns into net.PacketConns and groups them by -// Ufrag. It is a default implementation of TCPMux interface. -type TCPMuxDefault struct { - params *TCPMuxParams - closed bool - - // connsIPv4 and connsIPv6 are maps of all tcpPacketConns indexed by ufrag and local address - connsIPv4, connsIPv6 map[string]map[ipAddr]*tcpPacketConn - - mu sync.Mutex - wg sync.WaitGroup -} - -// TCPMuxParams are parameters for TCPMux. -type TCPMuxParams struct { - Listener net.Listener - Logger logging.LeveledLogger - ReadBufferSize int - - // Maximum buffer size for write op. 0 means no write buffer, the write op will block until the whole packet is written - // if the write buffer is full, the subsequent write packet will be dropped until it has enough space. - // a default 4MB is recommended. - WriteBufferSize int -} - -// NewTCPMuxDefault creates a new instance of TCPMuxDefault. -func NewTCPMuxDefault(params TCPMuxParams) *TCPMuxDefault { - if params.Logger == nil { - params.Logger = logging.NewDefaultLoggerFactory().NewLogger("ice") - } - - m := &TCPMuxDefault{ - params: ¶ms, - - connsIPv4: map[string]map[ipAddr]*tcpPacketConn{}, - connsIPv6: map[string]map[ipAddr]*tcpPacketConn{}, - } - - m.wg.Add(1) - go func() { - defer m.wg.Done() - m.start() - }() - - return m -} - -func (m *TCPMuxDefault) start() { - m.params.Logger.Infof("Listening TCP on %s", m.params.Listener.Addr()) - for { - conn, err := m.params.Listener.Accept() - if err != nil { - m.params.Logger.Infof("Error accepting connection: %s", err) - return - } - - m.params.Logger.Debugf("Accepted connection from: %s to %s", conn.RemoteAddr(), conn.LocalAddr()) - - m.wg.Add(1) - go func() { - defer m.wg.Done() - m.handleConn(conn) - }() - } -} - -// LocalAddr returns the listening address of this TCPMuxDefault. -func (m *TCPMuxDefault) LocalAddr() net.Addr { - return m.params.Listener.Addr() -} - -// GetConnByUfrag retrieves an existing or creates a new net.PacketConn. -func (m *TCPMuxDefault) GetConnByUfrag(ufrag string, isIPv6 bool, local net.IP) (net.PacketConn, error) { - m.mu.Lock() - defer m.mu.Unlock() - - if m.closed { - return nil, io.ErrClosedPipe - } - - if conn, ok := m.getConn(ufrag, isIPv6, local); ok { - return conn, nil - } - - return m.createConn(ufrag, isIPv6, local) -} - -func (m *TCPMuxDefault) createConn(ufrag string, isIPv6 bool, local net.IP) (*tcpPacketConn, error) { - addr, ok := m.LocalAddr().(*net.TCPAddr) - if !ok { - return nil, ErrGetTransportAddress - } - localAddr := *addr - localAddr.IP = local - - conn := newTCPPacketConn(tcpPacketParams{ - ReadBuffer: m.params.ReadBufferSize, - WriteBuffer: m.params.WriteBufferSize, - LocalAddr: &localAddr, - Logger: m.params.Logger, - }) - - var conns map[ipAddr]*tcpPacketConn - if isIPv6 { - if conns, ok = m.connsIPv6[ufrag]; !ok { - conns = make(map[ipAddr]*tcpPacketConn) - m.connsIPv6[ufrag] = conns - } - } else { - if conns, ok = m.connsIPv4[ufrag]; !ok { - conns = make(map[ipAddr]*tcpPacketConn) - m.connsIPv4[ufrag] = conns - } - } - conns[ipAddr(local.String())] = conn - - m.wg.Add(1) - go func() { - defer m.wg.Done() - <-conn.CloseChannel() - m.removeConnByUfragAndLocalHost(ufrag, local) - }() - - return conn, nil -} - -func (m *TCPMuxDefault) closeAndLogError(closer io.Closer) { - err := closer.Close() - if err != nil { - m.params.Logger.Warnf("Error closing connection: %s", err) - } -} - -func (m *TCPMuxDefault) handleConn(conn net.Conn) { - buf := make([]byte, receiveMTU) - - n, err := readStreamingPacket(conn, buf) - if err != nil { - m.params.Logger.Warnf("Error reading first packet from %s: %s", conn.RemoteAddr().String(), err) - return - } - - buf = buf[:n] - - msg := &stun.Message{ - Raw: make([]byte, len(buf)), - } - // Explicitly copy raw buffer so Message can own the memory. - copy(msg.Raw, buf) - if err = msg.Decode(); err != nil { - m.closeAndLogError(conn) - m.params.Logger.Warnf("Failed to handle decode ICE from %s to %s: %v", conn.RemoteAddr(), conn.LocalAddr(), err) - return - } - - if m == nil || msg.Type.Method != stun.MethodBinding { // Not a STUN - m.closeAndLogError(conn) - m.params.Logger.Warnf("Not a STUN message from %s to %s", conn.RemoteAddr(), conn.LocalAddr()) - return - } - - for _, attr := range msg.Attributes { - m.params.Logger.Debugf("msg attr: %s", attr.String()) - } - - attr, err := msg.Get(stun.AttrUsername) - if err != nil { - m.closeAndLogError(conn) - m.params.Logger.Warnf("No Username attribute in STUN message from %s to %s", conn.RemoteAddr(), conn.LocalAddr()) - return - } - - ufrag := strings.Split(string(attr), ":")[0] - m.params.Logger.Debugf("Ufrag: %s", ufrag) - - m.mu.Lock() - defer m.mu.Unlock() - - host, _, err := net.SplitHostPort(conn.RemoteAddr().String()) - if err != nil { - m.closeAndLogError(conn) - m.params.Logger.Warnf("Failed to get host in STUN message from %s to %s", conn.RemoteAddr(), conn.LocalAddr()) - return - } - - isIPv6 := net.ParseIP(host).To4() == nil - - localAddr, ok := conn.LocalAddr().(*net.TCPAddr) - if !ok { - m.closeAndLogError(conn) - m.params.Logger.Warnf("Failed to get local tcp address in STUN message from %s to %s", conn.RemoteAddr(), conn.LocalAddr()) - return - } - packetConn, ok := m.getConn(ufrag, isIPv6, localAddr.IP) - if !ok { - packetConn, err = m.createConn(ufrag, isIPv6, localAddr.IP) - if err != nil { - m.closeAndLogError(conn) - m.params.Logger.Warnf("Failed to create packetConn for STUN message from %s to %s", conn.RemoteAddr(), conn.LocalAddr()) - return - } - } - - if err := packetConn.AddConn(conn, buf); err != nil { - m.closeAndLogError(conn) - m.params.Logger.Warnf("Error adding conn to tcpPacketConn from %s to %s: %s", conn.RemoteAddr(), conn.LocalAddr(), err) - return - } -} - -// Close closes the listener and waits for all goroutines to exit. -func (m *TCPMuxDefault) Close() error { - m.mu.Lock() - m.closed = true - - for _, conns := range m.connsIPv4 { - for _, conn := range conns { - m.closeAndLogError(conn) - } - } - for _, conns := range m.connsIPv6 { - for _, conn := range conns { - m.closeAndLogError(conn) - } - } - - m.connsIPv4 = map[string]map[ipAddr]*tcpPacketConn{} - m.connsIPv6 = map[string]map[ipAddr]*tcpPacketConn{} - - err := m.params.Listener.Close() - - m.mu.Unlock() - - m.wg.Wait() - - return err -} - -// RemoveConnByUfrag closes and removes a net.PacketConn by Ufrag. -func (m *TCPMuxDefault) RemoveConnByUfrag(ufrag string) { - removedConns := make([]*tcpPacketConn, 0, 4) - - // Keep lock section small to avoid deadlock with conn lock - m.mu.Lock() - if conns, ok := m.connsIPv4[ufrag]; ok { - delete(m.connsIPv4, ufrag) - for _, conn := range conns { - removedConns = append(removedConns, conn) - } - } - if conns, ok := m.connsIPv6[ufrag]; ok { - delete(m.connsIPv6, ufrag) - for _, conn := range conns { - removedConns = append(removedConns, conn) - } - } - - m.mu.Unlock() - - // Close the connections outside the critical section to avoid - // deadlocking TCP mux if (*tcpPacketConn).Close() blocks. - for _, conn := range removedConns { - m.closeAndLogError(conn) - } -} - -func (m *TCPMuxDefault) removeConnByUfragAndLocalHost(ufrag string, local net.IP) { - removedConns := make([]*tcpPacketConn, 0, 4) - - localIP := ipAddr(local.String()) - // Keep lock section small to avoid deadlock with conn lock - m.mu.Lock() - if conns, ok := m.connsIPv4[ufrag]; ok { - if conn, ok := conns[localIP]; ok { - delete(conns, localIP) - if len(conns) == 0 { - delete(m.connsIPv4, ufrag) - } - removedConns = append(removedConns, conn) - } - } - if conns, ok := m.connsIPv6[ufrag]; ok { - if conn, ok := conns[localIP]; ok { - delete(conns, localIP) - if len(conns) == 0 { - delete(m.connsIPv6, ufrag) - } - removedConns = append(removedConns, conn) - } - } - m.mu.Unlock() - - // Close the connections outside the critical section to avoid - // deadlocking TCP mux if (*tcpPacketConn).Close() blocks. - for _, conn := range removedConns { - m.closeAndLogError(conn) - } -} - -func (m *TCPMuxDefault) getConn(ufrag string, isIPv6 bool, local net.IP) (val *tcpPacketConn, ok bool) { - var conns map[ipAddr]*tcpPacketConn - if isIPv6 { - conns, ok = m.connsIPv6[ufrag] - } else { - conns, ok = m.connsIPv4[ufrag] - } - if conns != nil { - val, ok = conns[ipAddr(local.String())] - } - - return -} - -const streamingPacketHeaderLen = 2 - -// readStreamingPacket reads 1 packet from stream -// read packet bytes https://tools.ietf.org/html/rfc4571#section-2 -// 2-byte length header prepends each packet: -// -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// ----------------------------------------------------------------- -// | LENGTH | RTP or RTCP packet ... | -// ----------------------------------------------------------------- -func readStreamingPacket(conn net.Conn, buf []byte) (int, error) { - header := make([]byte, streamingPacketHeaderLen) - var bytesRead, n int - var err error - - for bytesRead < streamingPacketHeaderLen { - if n, err = conn.Read(header[bytesRead:streamingPacketHeaderLen]); err != nil { - return 0, err - } - bytesRead += n - } - - length := int(binary.BigEndian.Uint16(header)) - - if length > cap(buf) { - return length, io.ErrShortBuffer - } - - bytesRead = 0 - for bytesRead < length { - if n, err = conn.Read(buf[bytesRead:length]); err != nil { - return 0, err - } - bytesRead += n - } - - return bytesRead, nil -} - -func writeStreamingPacket(conn net.Conn, buf []byte) (int, error) { - bufCopy := make([]byte, streamingPacketHeaderLen+len(buf)) - binary.BigEndian.PutUint16(bufCopy, uint16(len(buf))) - copy(bufCopy[2:], buf) - - n, err := conn.Write(bufCopy) - if err != nil { - return 0, err - } - - return n - streamingPacketHeaderLen, nil -} diff --git a/vendor/github.com/pion/ice/v2/tcp_mux_multi.go b/vendor/github.com/pion/ice/v2/tcp_mux_multi.go deleted file mode 100644 index e32acbf3..00000000 --- a/vendor/github.com/pion/ice/v2/tcp_mux_multi.go +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "net" - -// AllConnsGetter allows multiple fixed TCP ports to be used, -// each of which is multiplexed like TCPMux. AllConnsGetter also acts as -// a TCPMux, in which case it will return a single connection for one -// of the ports. -type AllConnsGetter interface { - GetAllConns(ufrag string, isIPv6 bool, localIP net.IP) ([]net.PacketConn, error) -} - -// MultiTCPMuxDefault implements both TCPMux and AllConnsGetter, -// allowing users to pass multiple TCPMux instances to the ICE agent -// configuration. -type MultiTCPMuxDefault struct { - muxes []TCPMux -} - -// NewMultiTCPMuxDefault creates an instance of MultiTCPMuxDefault that -// uses the provided TCPMux instances. -func NewMultiTCPMuxDefault(muxes ...TCPMux) *MultiTCPMuxDefault { - return &MultiTCPMuxDefault{ - muxes: muxes, - } -} - -// GetConnByUfrag returns a PacketConn given the connection's ufrag, network and local address -// creates the connection if an existing one can't be found. This, unlike -// GetAllConns, will only return a single PacketConn from the first mux that was -// passed in to NewMultiTCPMuxDefault. -func (m *MultiTCPMuxDefault) GetConnByUfrag(ufrag string, isIPv6 bool, local net.IP) (net.PacketConn, error) { - // NOTE: We always use the first element here in order to maintain the - // behavior of using an existing connection if one exists. - if len(m.muxes) == 0 { - return nil, errNoTCPMuxAvailable - } - return m.muxes[0].GetConnByUfrag(ufrag, isIPv6, local) -} - -// RemoveConnByUfrag stops and removes the muxed packet connection -// from all underlying TCPMux instances. -func (m *MultiTCPMuxDefault) RemoveConnByUfrag(ufrag string) { - for _, mux := range m.muxes { - mux.RemoveConnByUfrag(ufrag) - } -} - -// GetAllConns returns a PacketConn for each underlying TCPMux -func (m *MultiTCPMuxDefault) GetAllConns(ufrag string, isIPv6 bool, local net.IP) ([]net.PacketConn, error) { - if len(m.muxes) == 0 { - // Make sure that we either return at least one connection or an error. - return nil, errNoTCPMuxAvailable - } - var conns []net.PacketConn - for _, mux := range m.muxes { - conn, err := mux.GetConnByUfrag(ufrag, isIPv6, local) - if err != nil { - // For now, this implementation is all or none. - return nil, err - } - if conn != nil { - conns = append(conns, conn) - } - } - return conns, nil -} - -// Close the multi mux, no further connections could be created -func (m *MultiTCPMuxDefault) Close() error { - var err error - for _, mux := range m.muxes { - if e := mux.Close(); e != nil { - err = e - } - } - return err -} diff --git a/vendor/github.com/pion/ice/v2/tcp_packet_conn.go b/vendor/github.com/pion/ice/v2/tcp_packet_conn.go deleted file mode 100644 index 8c51fd1c..00000000 --- a/vendor/github.com/pion/ice/v2/tcp_packet_conn.go +++ /dev/null @@ -1,304 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "errors" - "fmt" - "io" - "net" - "sync" - "sync/atomic" - "time" - - "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" -) - -type bufferedConn struct { - net.Conn - buf *packetio.Buffer - logger logging.LeveledLogger - closed int32 -} - -func newBufferedConn(conn net.Conn, bufSize int, logger logging.LeveledLogger) net.Conn { - buf := packetio.NewBuffer() - if bufSize > 0 { - buf.SetLimitSize(bufSize) - } - - bc := &bufferedConn{ - Conn: conn, - buf: buf, - logger: logger, - } - - go bc.writeProcess() - return bc -} - -func (bc *bufferedConn) Write(b []byte) (int, error) { - n, err := bc.buf.Write(b) - if err != nil { - return n, err - } - return n, nil -} - -func (bc *bufferedConn) writeProcess() { - pktBuf := make([]byte, receiveMTU) - for atomic.LoadInt32(&bc.closed) == 0 { - n, err := bc.buf.Read(pktBuf) - if errors.Is(err, io.EOF) { - return - } - - if err != nil { - bc.logger.Warnf("read buffer error: %s", err) - continue - } - - if _, err := bc.Conn.Write(pktBuf[:n]); err != nil { - bc.logger.Warnf("write error: %s", err) - continue - } - } -} - -func (bc *bufferedConn) Close() error { - atomic.StoreInt32(&bc.closed, 1) - _ = bc.buf.Close() - return bc.Conn.Close() -} - -type tcpPacketConn struct { - params *tcpPacketParams - - // conns is a map of net.Conns indexed by remote net.Addr.String() - conns map[string]net.Conn - - recvChan chan streamingPacket - - mu sync.Mutex - wg sync.WaitGroup - closedChan chan struct{} - closeOnce sync.Once -} - -type streamingPacket struct { - Data []byte - RAddr net.Addr - Err error -} - -type tcpPacketParams struct { - ReadBuffer int - LocalAddr net.Addr - Logger logging.LeveledLogger - WriteBuffer int -} - -func newTCPPacketConn(params tcpPacketParams) *tcpPacketConn { - p := &tcpPacketConn{ - params: ¶ms, - - conns: map[string]net.Conn{}, - - recvChan: make(chan streamingPacket, params.ReadBuffer), - closedChan: make(chan struct{}), - } - - return p -} - -func (t *tcpPacketConn) AddConn(conn net.Conn, firstPacketData []byte) error { - t.params.Logger.Infof("AddConn: %s remote %s to local %s", conn.RemoteAddr().Network(), conn.RemoteAddr(), conn.LocalAddr()) - - t.mu.Lock() - defer t.mu.Unlock() - - select { - case <-t.closedChan: - return io.ErrClosedPipe - default: - } - - if _, ok := t.conns[conn.RemoteAddr().String()]; ok { - return fmt.Errorf("%w: %s", errConnectionAddrAlreadyExist, conn.RemoteAddr().String()) - } - - if t.params.WriteBuffer > 0 { - conn = newBufferedConn(conn, t.params.WriteBuffer, t.params.Logger) - } - t.conns[conn.RemoteAddr().String()] = conn - - t.wg.Add(1) - go func() { - defer t.wg.Done() - if firstPacketData != nil { - select { - case <-t.closedChan: - // NOTE: recvChan can fill up and never drain in edge - // cases while closing a connection, which can cause the - // packetConn to never finish closing. Bail out early - // here to prevent that. - return - case t.recvChan <- streamingPacket{firstPacketData, conn.RemoteAddr(), nil}: - } - } - t.startReading(conn) - }() - - return nil -} - -func (t *tcpPacketConn) startReading(conn net.Conn) { - buf := make([]byte, receiveMTU) - - for { - n, err := readStreamingPacket(conn, buf) - if err != nil { - t.params.Logger.Infof("%v: %s", errReadingStreamingPacket, err) - t.handleRecv(streamingPacket{nil, conn.RemoteAddr(), err}) - t.removeConn(conn) - return - } - - data := make([]byte, n) - copy(data, buf[:n]) - - t.handleRecv(streamingPacket{data, conn.RemoteAddr(), nil}) - } -} - -func (t *tcpPacketConn) handleRecv(pkt streamingPacket) { - t.mu.Lock() - - recvChan := t.recvChan - if t.isClosed() { - recvChan = nil - } - - t.mu.Unlock() - - select { - case recvChan <- pkt: - case <-t.closedChan: - } -} - -func (t *tcpPacketConn) isClosed() bool { - select { - case <-t.closedChan: - return true - default: - return false - } -} - -// WriteTo is for passive and s-o candidates. -func (t *tcpPacketConn) ReadFrom(b []byte) (n int, rAddr net.Addr, err error) { - pkt, ok := <-t.recvChan - - if !ok { - return 0, nil, io.ErrClosedPipe - } - - if pkt.Err != nil { - return 0, pkt.RAddr, pkt.Err - } - - if cap(b) < len(pkt.Data) { - return 0, pkt.RAddr, io.ErrShortBuffer - } - - n = len(pkt.Data) - copy(b, pkt.Data[:n]) - return n, pkt.RAddr, err -} - -// WriteTo is for active and s-o candidates. -func (t *tcpPacketConn) WriteTo(buf []byte, rAddr net.Addr) (n int, err error) { - t.mu.Lock() - conn, ok := t.conns[rAddr.String()] - t.mu.Unlock() - - if !ok { - return 0, io.ErrClosedPipe - } - - n, err = writeStreamingPacket(conn, buf) - if err != nil { - t.params.Logger.Tracef("%w %s", errWriting, rAddr) - return n, err - } - - return n, err -} - -func (t *tcpPacketConn) closeAndLogError(closer io.Closer) { - err := closer.Close() - if err != nil { - t.params.Logger.Warnf("%v: %s", errClosingConnection, err) - } -} - -func (t *tcpPacketConn) removeConn(conn net.Conn) { - t.mu.Lock() - defer t.mu.Unlock() - - t.closeAndLogError(conn) - - delete(t.conns, conn.RemoteAddr().String()) -} - -func (t *tcpPacketConn) Close() error { - t.mu.Lock() - - var shouldCloseRecvChan bool - t.closeOnce.Do(func() { - close(t.closedChan) - shouldCloseRecvChan = true - }) - - for _, conn := range t.conns { - t.closeAndLogError(conn) - delete(t.conns, conn.RemoteAddr().String()) - } - - t.mu.Unlock() - - t.wg.Wait() - - if shouldCloseRecvChan { - close(t.recvChan) - } - - return nil -} - -func (t *tcpPacketConn) LocalAddr() net.Addr { - return t.params.LocalAddr -} - -func (t *tcpPacketConn) SetDeadline(time.Time) error { - return nil -} - -func (t *tcpPacketConn) SetReadDeadline(time.Time) error { - return nil -} - -func (t *tcpPacketConn) SetWriteDeadline(time.Time) error { - return nil -} - -func (t *tcpPacketConn) CloseChannel() <-chan struct{} { - return t.closedChan -} - -func (t *tcpPacketConn) String() string { - return fmt.Sprintf("tcpPacketConn{LocalAddr: %s}", t.params.LocalAddr) -} diff --git a/vendor/github.com/pion/ice/v2/tcptype.go b/vendor/github.com/pion/ice/v2/tcptype.go deleted file mode 100644 index e500e57f..00000000 --- a/vendor/github.com/pion/ice/v2/tcptype.go +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "strings" - -// TCPType is the type of ICE TCP candidate as described in -// https://tools.ietf.org/html/rfc6544#section-4.5 -type TCPType int - -const ( - // TCPTypeUnspecified is the default value. For example UDP candidates do not - // need this field. - TCPTypeUnspecified TCPType = iota - // TCPTypeActive is active TCP candidate, which initiates TCP connections. - TCPTypeActive - // TCPTypePassive is passive TCP candidate, only accepts TCP connections. - TCPTypePassive - // TCPTypeSimultaneousOpen is like active and passive at the same time. - TCPTypeSimultaneousOpen -) - -// NewTCPType creates a new TCPType from string. -func NewTCPType(value string) TCPType { - switch strings.ToLower(value) { - case "active": - return TCPTypeActive - case "passive": - return TCPTypePassive - case "so": - return TCPTypeSimultaneousOpen - default: - return TCPTypeUnspecified - } -} - -func (t TCPType) String() string { - switch t { - case TCPTypeUnspecified: - return "" - case TCPTypeActive: - return "active" - case TCPTypePassive: - return "passive" - case TCPTypeSimultaneousOpen: - return "so" - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/ice/v2/test_utils.go b/vendor/github.com/pion/ice/v2/test_utils.go deleted file mode 100644 index 235fda31..00000000 --- a/vendor/github.com/pion/ice/v2/test_utils.go +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package ice - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func newHostRemote(t *testing.T) *CandidateHost { - remoteHostConfig := &CandidateHostConfig{ - Network: "udp", - Address: "1.2.3.5", - Port: 12350, - Component: 1, - } - hostRemote, err := NewCandidateHost(remoteHostConfig) - require.NoError(t, err) - return hostRemote -} - -func newPrflxRemote(t *testing.T) *CandidatePeerReflexive { - prflxConfig := &CandidatePeerReflexiveConfig{ - Network: "udp", - Address: "10.10.10.2", - Port: 19217, - Component: 1, - RelAddr: "4.3.2.1", - RelPort: 43211, - } - prflxRemote, err := NewCandidatePeerReflexive(prflxConfig) - require.NoError(t, err) - return prflxRemote -} - -func newSrflxRemote(t *testing.T) *CandidateServerReflexive { - srflxConfig := &CandidateServerReflexiveConfig{ - Network: "udp", - Address: "10.10.10.2", - Port: 19218, - Component: 1, - RelAddr: "4.3.2.1", - RelPort: 43212, - } - srflxRemote, err := NewCandidateServerReflexive(srflxConfig) - require.NoError(t, err) - return srflxRemote -} - -func newRelayRemote(t *testing.T) *CandidateRelay { - relayConfig := &CandidateRelayConfig{ - Network: "udp", - Address: "1.2.3.4", - Port: 12340, - Component: 1, - RelAddr: "4.3.2.1", - RelPort: 43210, - } - relayRemote, err := NewCandidateRelay(relayConfig) - require.NoError(t, err) - return relayRemote -} - -func newHostLocal(t *testing.T) *CandidateHost { - localHostConfig := &CandidateHostConfig{ - Network: "udp", - Address: "192.168.1.1", - Port: 19216, - Component: 1, - } - hostLocal, err := NewCandidateHost(localHostConfig) - require.NoError(t, err) - return hostLocal -} diff --git a/vendor/github.com/pion/ice/v2/transport.go b/vendor/github.com/pion/ice/v2/transport.go deleted file mode 100644 index cd37a9b2..00000000 --- a/vendor/github.com/pion/ice/v2/transport.go +++ /dev/null @@ -1,148 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "context" - "net" - "sync/atomic" - "time" - - "github.com/pion/stun" -) - -// Dial connects to the remote agent, acting as the controlling ice agent. -// Dial blocks until at least one ice candidate pair has successfully connected. -func (a *Agent) Dial(ctx context.Context, remoteUfrag, remotePwd string) (*Conn, error) { - return a.connect(ctx, true, remoteUfrag, remotePwd) -} - -// Accept connects to the remote agent, acting as the controlled ice agent. -// Accept blocks until at least one ice candidate pair has successfully connected. -func (a *Agent) Accept(ctx context.Context, remoteUfrag, remotePwd string) (*Conn, error) { - return a.connect(ctx, false, remoteUfrag, remotePwd) -} - -// Conn represents the ICE connection. -// At the moment the lifetime of the Conn is equal to the Agent. -type Conn struct { - bytesReceived uint64 - bytesSent uint64 - agent *Agent -} - -// BytesSent returns the number of bytes sent -func (c *Conn) BytesSent() uint64 { - return atomic.LoadUint64(&c.bytesSent) -} - -// BytesReceived returns the number of bytes received -func (c *Conn) BytesReceived() uint64 { - return atomic.LoadUint64(&c.bytesReceived) -} - -func (a *Agent) connect(ctx context.Context, isControlling bool, remoteUfrag, remotePwd string) (*Conn, error) { - err := a.ok() - if err != nil { - return nil, err - } - err = a.startConnectivityChecks(isControlling, remoteUfrag, remotePwd) //nolint:contextcheck - if err != nil { - return nil, err - } - - // Block until pair selected - select { - case <-a.done: - return nil, a.getErr() - case <-ctx.Done(): - return nil, ErrCanceledByCaller - case <-a.onConnected: - } - - return &Conn{ - agent: a, - }, nil -} - -// Read implements the Conn Read method. -func (c *Conn) Read(p []byte) (int, error) { - err := c.agent.ok() - if err != nil { - return 0, err - } - - n, err := c.agent.buf.Read(p) - atomic.AddUint64(&c.bytesReceived, uint64(n)) - return n, err -} - -// Write implements the Conn Write method. -func (c *Conn) Write(p []byte) (int, error) { - err := c.agent.ok() - if err != nil { - return 0, err - } - - if stun.IsMessage(p) { - return 0, errICEWriteSTUNMessage - } - - pair := c.agent.getSelectedPair() - if pair == nil { - if err = c.agent.run(c.agent.context(), func(ctx context.Context, a *Agent) { - pair = a.getBestValidCandidatePair() - }); err != nil { - return 0, err - } - - if pair == nil { - return 0, err - } - } - - atomic.AddUint64(&c.bytesSent, uint64(len(p))) - return pair.Write(p) -} - -// Close implements the Conn Close method. It is used to close -// the connection. Any calls to Read and Write will be unblocked and return an error. -func (c *Conn) Close() error { - return c.agent.Close() -} - -// LocalAddr returns the local address of the current selected pair or nil if there is none. -func (c *Conn) LocalAddr() net.Addr { - pair := c.agent.getSelectedPair() - if pair == nil { - return nil - } - - return pair.Local.addr() -} - -// RemoteAddr returns the remote address of the current selected pair or nil if there is none. -func (c *Conn) RemoteAddr() net.Addr { - pair := c.agent.getSelectedPair() - if pair == nil { - return nil - } - - return pair.Remote.addr() -} - -// SetDeadline is a stub -func (c *Conn) SetDeadline(time.Time) error { - return nil -} - -// SetReadDeadline is a stub -func (c *Conn) SetReadDeadline(time.Time) error { - return nil -} - -// SetWriteDeadline is a stub -func (c *Conn) SetWriteDeadline(time.Time) error { - return nil -} diff --git a/vendor/github.com/pion/ice/v2/udp_mux.go b/vendor/github.com/pion/ice/v2/udp_mux.go deleted file mode 100644 index 405bb7b1..00000000 --- a/vendor/github.com/pion/ice/v2/udp_mux.go +++ /dev/null @@ -1,363 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "errors" - "io" - "net" - "os" - "strings" - "sync" - - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" -) - -// UDPMux allows multiple connections to go over a single UDP port -type UDPMux interface { - io.Closer - GetConn(ufrag string, addr net.Addr) (net.PacketConn, error) - RemoveConnByUfrag(ufrag string) - GetListenAddresses() []net.Addr -} - -// UDPMuxDefault is an implementation of the interface -type UDPMuxDefault struct { - params UDPMuxParams - - closedChan chan struct{} - closeOnce sync.Once - - // connsIPv4 and connsIPv6 are maps of all udpMuxedConn indexed by ufrag|network|candidateType - connsIPv4, connsIPv6 map[string]*udpMuxedConn - - addressMapMu sync.RWMutex - addressMap map[string]*udpMuxedConn - - // Buffer pool to recycle buffers for net.UDPAddr encodes/decodes - pool *sync.Pool - - mu sync.Mutex - - // For UDP connection listen at unspecified address - localAddrsForUnspecified []net.Addr -} - -const maxAddrSize = 512 - -// UDPMuxParams are parameters for UDPMux. -type UDPMuxParams struct { - Logger logging.LeveledLogger - UDPConn net.PacketConn - - // Required for gathering local addresses - // in case a un UDPConn is passed which does not - // bind to a specific local address. - Net transport.Net -} - -// NewUDPMuxDefault creates an implementation of UDPMux -func NewUDPMuxDefault(params UDPMuxParams) *UDPMuxDefault { - if params.Logger == nil { - params.Logger = logging.NewDefaultLoggerFactory().NewLogger("ice") - } - - var localAddrsForUnspecified []net.Addr - if addr, ok := params.UDPConn.LocalAddr().(*net.UDPAddr); !ok { - params.Logger.Errorf("LocalAddr is not a net.UDPAddr, got %T", params.UDPConn.LocalAddr()) - } else if ok && addr.IP.IsUnspecified() { - // For unspecified addresses, the correct behavior is to return errListenUnspecified, but - // it will break the applications that are already using unspecified UDP connection - // with UDPMuxDefault, so print a warn log and create a local address list for mux. - params.Logger.Warn("UDPMuxDefault should not listening on unspecified address, use NewMultiUDPMuxFromPort instead") - var networks []NetworkType - switch { - case addr.IP.To4() != nil: - networks = []NetworkType{NetworkTypeUDP4} - - case addr.IP.To16() != nil: - networks = []NetworkType{NetworkTypeUDP4, NetworkTypeUDP6} - - default: - params.Logger.Errorf("LocalAddr expected IPV4 or IPV6, got %T", params.UDPConn.LocalAddr()) - } - if len(networks) > 0 { - if params.Net == nil { - var err error - if params.Net, err = stdnet.NewNet(); err != nil { - params.Logger.Errorf("failed to get create network: %v", err) - } - } - - ips, err := localInterfaces(params.Net, nil, nil, networks, true) - if err == nil { - for _, ip := range ips { - localAddrsForUnspecified = append(localAddrsForUnspecified, &net.UDPAddr{IP: ip, Port: addr.Port}) - } - } else { - params.Logger.Errorf("failed to get local interfaces for unspecified addr: %v", err) - } - } - } - - m := &UDPMuxDefault{ - addressMap: map[string]*udpMuxedConn{}, - params: params, - connsIPv4: make(map[string]*udpMuxedConn), - connsIPv6: make(map[string]*udpMuxedConn), - closedChan: make(chan struct{}, 1), - pool: &sync.Pool{ - New: func() interface{} { - // Big enough buffer to fit both packet and address - return newBufferHolder(receiveMTU + maxAddrSize) - }, - }, - localAddrsForUnspecified: localAddrsForUnspecified, - } - - go m.connWorker() - - return m -} - -// LocalAddr returns the listening address of this UDPMuxDefault -func (m *UDPMuxDefault) LocalAddr() net.Addr { - return m.params.UDPConn.LocalAddr() -} - -// GetListenAddresses returns the list of addresses that this mux is listening on -func (m *UDPMuxDefault) GetListenAddresses() []net.Addr { - if len(m.localAddrsForUnspecified) > 0 { - return m.localAddrsForUnspecified - } - - return []net.Addr{m.LocalAddr()} -} - -// GetConn returns a PacketConn given the connection's ufrag and network address -// creates the connection if an existing one can't be found -func (m *UDPMuxDefault) GetConn(ufrag string, addr net.Addr) (net.PacketConn, error) { - // don't check addr for mux using unspecified address - if len(m.localAddrsForUnspecified) == 0 && m.params.UDPConn.LocalAddr().String() != addr.String() { - return nil, errInvalidAddress - } - - var isIPv6 bool - if udpAddr, _ := addr.(*net.UDPAddr); udpAddr != nil && udpAddr.IP.To4() == nil { - isIPv6 = true - } - m.mu.Lock() - defer m.mu.Unlock() - - if m.IsClosed() { - return nil, io.ErrClosedPipe - } - - if conn, ok := m.getConn(ufrag, isIPv6); ok { - return conn, nil - } - - c := m.createMuxedConn(ufrag) - go func() { - <-c.CloseChannel() - m.RemoveConnByUfrag(ufrag) - }() - - if isIPv6 { - m.connsIPv6[ufrag] = c - } else { - m.connsIPv4[ufrag] = c - } - - return c, nil -} - -// RemoveConnByUfrag stops and removes the muxed packet connection -func (m *UDPMuxDefault) RemoveConnByUfrag(ufrag string) { - removedConns := make([]*udpMuxedConn, 0, 2) - - // Keep lock section small to avoid deadlock with conn lock - m.mu.Lock() - if c, ok := m.connsIPv4[ufrag]; ok { - delete(m.connsIPv4, ufrag) - removedConns = append(removedConns, c) - } - if c, ok := m.connsIPv6[ufrag]; ok { - delete(m.connsIPv6, ufrag) - removedConns = append(removedConns, c) - } - m.mu.Unlock() - - if len(removedConns) == 0 { - // No need to lock if no connection was found - return - } - - m.addressMapMu.Lock() - defer m.addressMapMu.Unlock() - - for _, c := range removedConns { - addresses := c.getAddresses() - for _, addr := range addresses { - delete(m.addressMap, addr) - } - } -} - -// IsClosed returns true if the mux had been closed -func (m *UDPMuxDefault) IsClosed() bool { - select { - case <-m.closedChan: - return true - default: - return false - } -} - -// Close the mux, no further connections could be created -func (m *UDPMuxDefault) Close() error { - var err error - m.closeOnce.Do(func() { - m.mu.Lock() - defer m.mu.Unlock() - - for _, c := range m.connsIPv4 { - _ = c.Close() - } - for _, c := range m.connsIPv6 { - _ = c.Close() - } - - m.connsIPv4 = make(map[string]*udpMuxedConn) - m.connsIPv6 = make(map[string]*udpMuxedConn) - - close(m.closedChan) - - _ = m.params.UDPConn.Close() - }) - return err -} - -func (m *UDPMuxDefault) writeTo(buf []byte, rAddr net.Addr) (n int, err error) { - return m.params.UDPConn.WriteTo(buf, rAddr) -} - -func (m *UDPMuxDefault) registerConnForAddress(conn *udpMuxedConn, addr string) { - if m.IsClosed() { - return - } - - m.addressMapMu.Lock() - defer m.addressMapMu.Unlock() - - existing, ok := m.addressMap[addr] - if ok { - existing.removeAddress(addr) - } - m.addressMap[addr] = conn - - m.params.Logger.Debugf("Registered %s for %s", addr, conn.params.Key) -} - -func (m *UDPMuxDefault) createMuxedConn(key string) *udpMuxedConn { - c := newUDPMuxedConn(&udpMuxedConnParams{ - Mux: m, - Key: key, - AddrPool: m.pool, - LocalAddr: m.LocalAddr(), - Logger: m.params.Logger, - }) - return c -} - -func (m *UDPMuxDefault) connWorker() { - logger := m.params.Logger - - defer func() { - _ = m.Close() - }() - - buf := make([]byte, receiveMTU) - for { - n, addr, err := m.params.UDPConn.ReadFrom(buf) - if m.IsClosed() { - return - } else if err != nil { - if os.IsTimeout(err) { - continue - } else if !errors.Is(err, io.EOF) { - logger.Errorf("could not read udp packet: %v", err) - } - - return - } - - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - logger.Errorf("underlying PacketConn did not return a UDPAddr") - return - } - - // If we have already seen this address dispatch to the appropriate destination - m.addressMapMu.Lock() - destinationConn := m.addressMap[addr.String()] - m.addressMapMu.Unlock() - - // If we haven't seen this address before but is a STUN packet lookup by ufrag - if destinationConn == nil && stun.IsMessage(buf[:n]) { - msg := &stun.Message{ - Raw: append([]byte{}, buf[:n]...), - } - - if err = msg.Decode(); err != nil { - m.params.Logger.Warnf("Failed to handle decode ICE from %s: %v", addr.String(), err) - continue - } - - attr, stunAttrErr := msg.Get(stun.AttrUsername) - if stunAttrErr != nil { - m.params.Logger.Warnf("No Username attribute in STUN message from %s", addr.String()) - continue - } - - ufrag := strings.Split(string(attr), ":")[0] - isIPv6 := udpAddr.IP.To4() == nil - - m.mu.Lock() - destinationConn, _ = m.getConn(ufrag, isIPv6) - m.mu.Unlock() - } - - if destinationConn == nil { - m.params.Logger.Tracef("dropping packet from %s, addr: %s", udpAddr.String(), addr.String()) - continue - } - - if err = destinationConn.writePacket(buf[:n], udpAddr); err != nil { - m.params.Logger.Errorf("could not write packet: %v", err) - } - } -} - -func (m *UDPMuxDefault) getConn(ufrag string, isIPv6 bool) (val *udpMuxedConn, ok bool) { - if isIPv6 { - val, ok = m.connsIPv6[ufrag] - } else { - val, ok = m.connsIPv4[ufrag] - } - return -} - -type bufferHolder struct { - buf []byte -} - -func newBufferHolder(size int) *bufferHolder { - return &bufferHolder{ - buf: make([]byte, size), - } -} diff --git a/vendor/github.com/pion/ice/v2/udp_mux_multi.go b/vendor/github.com/pion/ice/v2/udp_mux_multi.go deleted file mode 100644 index 158cbc37..00000000 --- a/vendor/github.com/pion/ice/v2/udp_mux_multi.go +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "fmt" - "net" - - "github.com/pion/logging" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" -) - -// MultiUDPMuxDefault implements both UDPMux and AllConnsGetter, -// allowing users to pass multiple UDPMux instances to the ICE agent -// configuration. -type MultiUDPMuxDefault struct { - muxes []UDPMux - localAddrToMux map[string]UDPMux -} - -// NewMultiUDPMuxDefault creates an instance of MultiUDPMuxDefault that -// uses the provided UDPMux instances. -func NewMultiUDPMuxDefault(muxes ...UDPMux) *MultiUDPMuxDefault { - addrToMux := make(map[string]UDPMux) - for _, mux := range muxes { - for _, addr := range mux.GetListenAddresses() { - addrToMux[addr.String()] = mux - } - } - return &MultiUDPMuxDefault{ - muxes: muxes, - localAddrToMux: addrToMux, - } -} - -// GetConn returns a PacketConn given the connection's ufrag and network -// creates the connection if an existing one can't be found. -func (m *MultiUDPMuxDefault) GetConn(ufrag string, addr net.Addr) (net.PacketConn, error) { - mux, ok := m.localAddrToMux[addr.String()] - if !ok { - return nil, errNoUDPMuxAvailable - } - return mux.GetConn(ufrag, addr) -} - -// RemoveConnByUfrag stops and removes the muxed packet connection -// from all underlying UDPMux instances. -func (m *MultiUDPMuxDefault) RemoveConnByUfrag(ufrag string) { - for _, mux := range m.muxes { - mux.RemoveConnByUfrag(ufrag) - } -} - -// Close the multi mux, no further connections could be created -func (m *MultiUDPMuxDefault) Close() error { - var err error - for _, mux := range m.muxes { - if e := mux.Close(); e != nil { - err = e - } - } - return err -} - -// GetListenAddresses returns the list of addresses that this mux is listening on -func (m *MultiUDPMuxDefault) GetListenAddresses() []net.Addr { - addrs := make([]net.Addr, 0, len(m.localAddrToMux)) - for _, mux := range m.muxes { - addrs = append(addrs, mux.GetListenAddresses()...) - } - return addrs -} - -// NewMultiUDPMuxFromPort creates an instance of MultiUDPMuxDefault that -// listen all interfaces on the provided port. -func NewMultiUDPMuxFromPort(port int, opts ...UDPMuxFromPortOption) (*MultiUDPMuxDefault, error) { - params := multiUDPMuxFromPortParam{ - networks: []NetworkType{NetworkTypeUDP4, NetworkTypeUDP6}, - } - for _, opt := range opts { - opt.apply(¶ms) - } - - if params.net == nil { - var err error - if params.net, err = stdnet.NewNet(); err != nil { - return nil, fmt.Errorf("failed to get create network: %w", err) - } - } - - ips, err := localInterfaces(params.net, params.ifFilter, params.ipFilter, params.networks, params.includeLoopback) - if err != nil { - return nil, err - } - - conns := make([]net.PacketConn, 0, len(ips)) - for _, ip := range ips { - conn, listenErr := params.net.ListenUDP("udp", &net.UDPAddr{IP: ip, Port: port}) - if listenErr != nil { - err = listenErr - break - } - if params.readBufferSize > 0 { - _ = conn.SetReadBuffer(params.readBufferSize) - } - if params.writeBufferSize > 0 { - _ = conn.SetWriteBuffer(params.writeBufferSize) - } - conns = append(conns, conn) - } - - if err != nil { - for _, conn := range conns { - _ = conn.Close() - } - return nil, err - } - - muxes := make([]UDPMux, 0, len(conns)) - for _, conn := range conns { - mux := NewUDPMuxDefault(UDPMuxParams{ - Logger: params.logger, - UDPConn: conn, - Net: params.net, - }) - muxes = append(muxes, mux) - } - - return NewMultiUDPMuxDefault(muxes...), nil -} - -// UDPMuxFromPortOption provide options for NewMultiUDPMuxFromPort -type UDPMuxFromPortOption interface { - apply(*multiUDPMuxFromPortParam) -} - -type multiUDPMuxFromPortParam struct { - ifFilter func(string) bool - ipFilter func(ip net.IP) bool - networks []NetworkType - readBufferSize int - writeBufferSize int - logger logging.LeveledLogger - includeLoopback bool - net transport.Net -} - -type udpMuxFromPortOption struct { - f func(*multiUDPMuxFromPortParam) -} - -func (o *udpMuxFromPortOption) apply(p *multiUDPMuxFromPortParam) { - o.f(p) -} - -// UDPMuxFromPortWithInterfaceFilter set the filter to filter out interfaces that should not be used -func UDPMuxFromPortWithInterfaceFilter(f func(string) bool) UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.ifFilter = f - }, - } -} - -// UDPMuxFromPortWithIPFilter set the filter to filter out IP addresses that should not be used -func UDPMuxFromPortWithIPFilter(f func(ip net.IP) bool) UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.ipFilter = f - }, - } -} - -// UDPMuxFromPortWithNetworks set the networks that should be used. default is both IPv4 and IPv6 -func UDPMuxFromPortWithNetworks(networks ...NetworkType) UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.networks = networks - }, - } -} - -// UDPMuxFromPortWithReadBufferSize set the UDP connection read buffer size -func UDPMuxFromPortWithReadBufferSize(size int) UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.readBufferSize = size - }, - } -} - -// UDPMuxFromPortWithWriteBufferSize set the UDP connection write buffer size -func UDPMuxFromPortWithWriteBufferSize(size int) UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.writeBufferSize = size - }, - } -} - -// UDPMuxFromPortWithLogger set the logger for the created UDPMux -func UDPMuxFromPortWithLogger(logger logging.LeveledLogger) UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.logger = logger - }, - } -} - -// UDPMuxFromPortWithLoopback set loopback interface should be included -func UDPMuxFromPortWithLoopback() UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.includeLoopback = true - }, - } -} - -// UDPMuxFromPortWithNet sets the network transport to use. -func UDPMuxFromPortWithNet(n transport.Net) UDPMuxFromPortOption { - return &udpMuxFromPortOption{ - f: func(p *multiUDPMuxFromPortParam) { - p.net = n - }, - } -} diff --git a/vendor/github.com/pion/ice/v2/udp_mux_universal.go b/vendor/github.com/pion/ice/v2/udp_mux_universal.go deleted file mode 100644 index 07b6a70e..00000000 --- a/vendor/github.com/pion/ice/v2/udp_mux_universal.go +++ /dev/null @@ -1,271 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "fmt" - "net" - "time" - - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" -) - -// UniversalUDPMux allows multiple connections to go over a single UDP port for -// host, server reflexive and relayed candidates. -// Actual connection muxing is happening in the UDPMux. -type UniversalUDPMux interface { - UDPMux - GetXORMappedAddr(stunAddr net.Addr, deadline time.Duration) (*stun.XORMappedAddress, error) - GetRelayedAddr(turnAddr net.Addr, deadline time.Duration) (*net.Addr, error) - GetConnForURL(ufrag string, url string, addr net.Addr) (net.PacketConn, error) -} - -// UniversalUDPMuxDefault handles STUN and TURN servers packets by wrapping the original UDPConn overriding ReadFrom. -// It the passes packets to the UDPMux that does the actual connection muxing. -type UniversalUDPMuxDefault struct { - *UDPMuxDefault - params UniversalUDPMuxParams - - // Since we have a shared socket, for srflx candidates it makes sense to have a shared mapped address across all the agents - // stun.XORMappedAddress indexed by the STUN server addr - xorMappedMap map[string]*xorMapped -} - -// UniversalUDPMuxParams are parameters for UniversalUDPMux server reflexive. -type UniversalUDPMuxParams struct { - Logger logging.LeveledLogger - UDPConn net.PacketConn - XORMappedAddrCacheTTL time.Duration - Net transport.Net -} - -// NewUniversalUDPMuxDefault creates an implementation of UniversalUDPMux embedding UDPMux -func NewUniversalUDPMuxDefault(params UniversalUDPMuxParams) *UniversalUDPMuxDefault { - if params.Logger == nil { - params.Logger = logging.NewDefaultLoggerFactory().NewLogger("ice") - } - if params.XORMappedAddrCacheTTL == 0 { - params.XORMappedAddrCacheTTL = time.Second * 25 - } - - m := &UniversalUDPMuxDefault{ - params: params, - xorMappedMap: make(map[string]*xorMapped), - } - - // Wrap UDP connection, process server reflexive messages - // before they are passed to the UDPMux connection handler (connWorker) - m.params.UDPConn = &udpConn{ - PacketConn: params.UDPConn, - mux: m, - logger: params.Logger, - } - - // Embed UDPMux - udpMuxParams := UDPMuxParams{ - Logger: params.Logger, - UDPConn: m.params.UDPConn, - Net: m.params.Net, - } - m.UDPMuxDefault = NewUDPMuxDefault(udpMuxParams) - - return m -} - -// udpConn is a wrapper around UDPMux conn that overrides ReadFrom and handles STUN/TURN packets -type udpConn struct { - net.PacketConn - mux *UniversalUDPMuxDefault - logger logging.LeveledLogger -} - -// GetRelayedAddr creates relayed connection to the given TURN service and returns the relayed addr. -// Not implemented yet. -func (m *UniversalUDPMuxDefault) GetRelayedAddr(net.Addr, time.Duration) (*net.Addr, error) { - return nil, errNotImplemented -} - -// GetConnForURL add uniques to the muxed connection by concatenating ufrag and URL (e.g. STUN URL) to be able to support multiple STUN/TURN servers -// and return a unique connection per server. -func (m *UniversalUDPMuxDefault) GetConnForURL(ufrag string, url string, addr net.Addr) (net.PacketConn, error) { - return m.UDPMuxDefault.GetConn(fmt.Sprintf("%s%s", ufrag, url), addr) -} - -// ReadFrom is called by UDPMux connWorker and handles packets coming from the STUN server discovering a mapped address. -// It passes processed packets further to the UDPMux (maybe this is not really necessary). -func (c *udpConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { - n, addr, err = c.PacketConn.ReadFrom(p) - if err != nil { - return - } - - if stun.IsMessage(p[:n]) { - msg := &stun.Message{ - Raw: append([]byte{}, p[:n]...), - } - - if err = msg.Decode(); err != nil { - c.logger.Warnf("Failed to handle decode ICE from %s: %v", addr.String(), err) - err = nil - return - } - - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - // Message about this err will be logged in the UDPMux - return - } - - if c.mux.isXORMappedResponse(msg, udpAddr.String()) { - err = c.mux.handleXORMappedResponse(udpAddr, msg) - if err != nil { - c.logger.Debugf("%w: %v", errGetXorMappedAddrResponse, err) - err = nil - } - return - } - } - return n, addr, err -} - -// isXORMappedResponse indicates whether the message is a XORMappedAddress and is coming from the known STUN server. -func (m *UniversalUDPMuxDefault) isXORMappedResponse(msg *stun.Message, stunAddr string) bool { - m.mu.Lock() - defer m.mu.Unlock() - // Check first if it is a STUN server address because remote peer can also send similar messages but as a BindingSuccess - _, ok := m.xorMappedMap[stunAddr] - _, err := msg.Get(stun.AttrXORMappedAddress) - return err == nil && ok -} - -// handleXORMappedResponse parses response from the STUN server, extracts XORMappedAddress attribute -// and set the mapped address for the server -func (m *UniversalUDPMuxDefault) handleXORMappedResponse(stunAddr *net.UDPAddr, msg *stun.Message) error { - m.mu.Lock() - defer m.mu.Unlock() - - mappedAddr, ok := m.xorMappedMap[stunAddr.String()] - if !ok { - return errNoXorAddrMapping - } - - var addr stun.XORMappedAddress - if err := addr.GetFrom(msg); err != nil { - return err - } - - m.xorMappedMap[stunAddr.String()] = mappedAddr - mappedAddr.SetAddr(&addr) - - return nil -} - -// GetXORMappedAddr returns *stun.XORMappedAddress if already present for a given STUN server. -// Makes a STUN binding request to discover mapped address otherwise. -// Blocks until the stun.XORMappedAddress has been discovered or deadline. -// Method is safe for concurrent use. -func (m *UniversalUDPMuxDefault) GetXORMappedAddr(serverAddr net.Addr, deadline time.Duration) (*stun.XORMappedAddress, error) { - m.mu.Lock() - mappedAddr, ok := m.xorMappedMap[serverAddr.String()] - // If we already have a mapping for this STUN server (address already received) - // and if it is not too old we return it without making a new request to STUN server - if ok { - if mappedAddr.expired() { - mappedAddr.closeWaiters() - delete(m.xorMappedMap, serverAddr.String()) - ok = false - } else if mappedAddr.pending() { - ok = false - } - } - m.mu.Unlock() - if ok { - return mappedAddr.addr, nil - } - - // Otherwise, make a STUN request to discover the address - // or wait for already sent request to complete - waitAddrReceived, err := m.sendSTUN(serverAddr) - if err != nil { - return nil, fmt.Errorf("%w: %s", errSendSTUNPacket, err) //nolint:errorlint - } - - // Block until response was handled by the connWorker routine and XORMappedAddress was updated - select { - case <-waitAddrReceived: - // When channel closed, addr was obtained - m.mu.Lock() - mappedAddr := *m.xorMappedMap[serverAddr.String()] - m.mu.Unlock() - if mappedAddr.addr == nil { - return nil, errNoXorAddrMapping - } - return mappedAddr.addr, nil - case <-time.After(deadline): - return nil, errXORMappedAddrTimeout - } -} - -// sendSTUN sends a STUN request via UDP conn. -// -// The returned channel is closed when the STUN response has been received. -// Method is safe for concurrent use. -func (m *UniversalUDPMuxDefault) sendSTUN(serverAddr net.Addr) (chan struct{}, error) { - m.mu.Lock() - defer m.mu.Unlock() - - // If record present in the map, we already sent a STUN request, - // just wait when waitAddrReceived will be closed - addrMap, ok := m.xorMappedMap[serverAddr.String()] - if !ok { - addrMap = &xorMapped{ - expiresAt: time.Now().Add(m.params.XORMappedAddrCacheTTL), - waitAddrReceived: make(chan struct{}), - } - m.xorMappedMap[serverAddr.String()] = addrMap - } - - req, err := stun.Build(stun.BindingRequest, stun.TransactionID) - if err != nil { - return nil, err - } - - if _, err = m.params.UDPConn.WriteTo(req.Raw, serverAddr); err != nil { - return nil, err - } - - return addrMap.waitAddrReceived, nil -} - -type xorMapped struct { - addr *stun.XORMappedAddress - waitAddrReceived chan struct{} - expiresAt time.Time -} - -func (a *xorMapped) closeWaiters() { - select { - case <-a.waitAddrReceived: - // Notify was close, ok, that means we received duplicate response just exit - break - default: - // Notify tha twe have a new addr - close(a.waitAddrReceived) - } -} - -func (a *xorMapped) pending() bool { - return a.addr == nil -} - -func (a *xorMapped) expired() bool { - return a.expiresAt.Before(time.Now()) -} - -func (a *xorMapped) SetAddr(addr *stun.XORMappedAddress) { - a.addr = addr - a.closeWaiters() -} diff --git a/vendor/github.com/pion/ice/v2/udp_muxed_conn.go b/vendor/github.com/pion/ice/v2/udp_muxed_conn.go deleted file mode 100644 index 09e4b3a8..00000000 --- a/vendor/github.com/pion/ice/v2/udp_muxed_conn.go +++ /dev/null @@ -1,246 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import ( - "encoding/binary" - "io" - "net" - "sync" - "time" - - "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" -) - -type udpMuxedConnParams struct { - Mux *UDPMuxDefault - AddrPool *sync.Pool - Key string - LocalAddr net.Addr - Logger logging.LeveledLogger -} - -// udpMuxedConn represents a logical packet conn for a single remote as identified by ufrag -type udpMuxedConn struct { - params *udpMuxedConnParams - // Remote addresses that we have sent to on this conn - addresses []string - - // Channel holding incoming packets - buf *packetio.Buffer - closedChan chan struct{} - closeOnce sync.Once - mu sync.Mutex -} - -func newUDPMuxedConn(params *udpMuxedConnParams) *udpMuxedConn { - p := &udpMuxedConn{ - params: params, - buf: packetio.NewBuffer(), - closedChan: make(chan struct{}), - } - - return p -} - -func (c *udpMuxedConn) ReadFrom(b []byte) (n int, rAddr net.Addr, err error) { - buf := c.params.AddrPool.Get().(*bufferHolder) //nolint:forcetypeassert - defer c.params.AddrPool.Put(buf) - - // Read address - total, err := c.buf.Read(buf.buf) - if err != nil { - return 0, nil, err - } - - dataLen := int(binary.LittleEndian.Uint16(buf.buf[:2])) - if dataLen > total || dataLen > len(b) { - return 0, nil, io.ErrShortBuffer - } - - // Read data and then address - offset := 2 - copy(b, buf.buf[offset:offset+dataLen]) - offset += dataLen - - // Read address len & decode address - addrLen := int(binary.LittleEndian.Uint16(buf.buf[offset : offset+2])) - offset += 2 - - if rAddr, err = decodeUDPAddr(buf.buf[offset : offset+addrLen]); err != nil { - return 0, nil, err - } - - return dataLen, rAddr, nil -} - -func (c *udpMuxedConn) WriteTo(buf []byte, rAddr net.Addr) (n int, err error) { - if c.isClosed() { - return 0, io.ErrClosedPipe - } - // Each time we write to a new address, we'll register it with the mux - addr := rAddr.String() - if !c.containsAddress(addr) { - c.addAddress(addr) - } - - return c.params.Mux.writeTo(buf, rAddr) -} - -func (c *udpMuxedConn) LocalAddr() net.Addr { - return c.params.LocalAddr -} - -func (c *udpMuxedConn) SetDeadline(time.Time) error { - return nil -} - -func (c *udpMuxedConn) SetReadDeadline(time.Time) error { - return nil -} - -func (c *udpMuxedConn) SetWriteDeadline(time.Time) error { - return nil -} - -func (c *udpMuxedConn) CloseChannel() <-chan struct{} { - return c.closedChan -} - -func (c *udpMuxedConn) Close() error { - var err error - c.closeOnce.Do(func() { - err = c.buf.Close() - close(c.closedChan) - }) - return err -} - -func (c *udpMuxedConn) isClosed() bool { - select { - case <-c.closedChan: - return true - default: - return false - } -} - -func (c *udpMuxedConn) getAddresses() []string { - c.mu.Lock() - defer c.mu.Unlock() - addresses := make([]string, len(c.addresses)) - copy(addresses, c.addresses) - return addresses -} - -func (c *udpMuxedConn) addAddress(addr string) { - c.mu.Lock() - c.addresses = append(c.addresses, addr) - c.mu.Unlock() - - // Map it on mux - c.params.Mux.registerConnForAddress(c, addr) -} - -func (c *udpMuxedConn) removeAddress(addr string) { - c.mu.Lock() - defer c.mu.Unlock() - - newAddresses := make([]string, 0, len(c.addresses)) - for _, a := range c.addresses { - if a != addr { - newAddresses = append(newAddresses, a) - } - } - - c.addresses = newAddresses -} - -func (c *udpMuxedConn) containsAddress(addr string) bool { - c.mu.Lock() - defer c.mu.Unlock() - for _, a := range c.addresses { - if addr == a { - return true - } - } - return false -} - -func (c *udpMuxedConn) writePacket(data []byte, addr *net.UDPAddr) error { - // Write two packets, address and data - buf := c.params.AddrPool.Get().(*bufferHolder) //nolint:forcetypeassert - defer c.params.AddrPool.Put(buf) - - // Format of buffer | data len | data bytes | addr len | addr bytes | - if len(buf.buf) < len(data)+maxAddrSize { - return io.ErrShortBuffer - } - // Data length - binary.LittleEndian.PutUint16(buf.buf, uint16(len(data))) - offset := 2 - - // Data - copy(buf.buf[offset:], data) - offset += len(data) - - // Write address first, leaving room for its length - n, err := encodeUDPAddr(addr, buf.buf[offset+2:]) - if err != nil { - return err - } - total := offset + n + 2 - - // Address len - binary.LittleEndian.PutUint16(buf.buf[offset:], uint16(n)) - - if _, err := c.buf.Write(buf.buf[:total]); err != nil { - return err - } - return nil -} - -func encodeUDPAddr(addr *net.UDPAddr, buf []byte) (int, error) { - ipData, err := addr.IP.MarshalText() - if err != nil { - return 0, err - } - total := 2 + len(ipData) + 2 + len(addr.Zone) - if total > len(buf) { - return 0, io.ErrShortBuffer - } - - binary.LittleEndian.PutUint16(buf, uint16(len(ipData))) - offset := 2 - n := copy(buf[offset:], ipData) - offset += n - binary.LittleEndian.PutUint16(buf[offset:], uint16(addr.Port)) - offset += 2 - copy(buf[offset:], addr.Zone) - return total, nil -} - -func decodeUDPAddr(buf []byte) (*net.UDPAddr, error) { - addr := net.UDPAddr{} - - offset := 0 - ipLen := int(binary.LittleEndian.Uint16(buf[:2])) - offset += 2 - // Basic bounds checking - if ipLen+offset > len(buf) { - return nil, io.ErrShortBuffer - } - if err := addr.IP.UnmarshalText(buf[offset : offset+ipLen]); err != nil { - return nil, err - } - offset += ipLen - addr.Port = int(binary.LittleEndian.Uint16(buf[offset : offset+2])) - offset += 2 - zone := make([]byte, len(buf[offset:])) - copy(zone, buf[offset:]) - addr.Zone = string(zone) - - return &addr, nil -} diff --git a/vendor/github.com/pion/ice/v2/url.go b/vendor/github.com/pion/ice/v2/url.go deleted file mode 100644 index b2b9f8bd..00000000 --- a/vendor/github.com/pion/ice/v2/url.go +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "github.com/pion/stun" - -type ( - // URL represents a STUN (rfc7064) or TURN (rfc7065) URI - // - // Deprecated: Please use pion/stun.URI - URL = stun.URI - - // ProtoType indicates the transport protocol type that is used in the ice.URL - // structure. - // - // Deprecated: TPlease use pion/stun.ProtoType - ProtoType = stun.ProtoType - - // SchemeType indicates the type of server used in the ice.URL structure. - // - // Deprecated: Please use pion/stun.SchemeType - SchemeType = stun.SchemeType -) - -const ( - // SchemeTypeSTUN indicates the URL represents a STUN server. - // - // Deprecated: Please use pion/stun.SchemeTypeSTUN - SchemeTypeSTUN = stun.SchemeTypeSTUN - - // SchemeTypeSTUNS indicates the URL represents a STUNS (secure) server. - // - // Deprecated: Please use pion/stun.SchemeTypeSTUNS - SchemeTypeSTUNS = stun.SchemeTypeSTUNS - - // SchemeTypeTURN indicates the URL represents a TURN server. - // - // Deprecated: Please use pion/stun.SchemeTypeTURN - SchemeTypeTURN = stun.SchemeTypeTURN - - // SchemeTypeTURNS indicates the URL represents a TURNS (secure) server. - // - // Deprecated: Please use pion/stun.SchemeTypeTURNS - SchemeTypeTURNS = stun.SchemeTypeTURNS -) - -const ( - // ProtoTypeUDP indicates the URL uses a UDP transport. - // - // Deprecated: Please use pion/stun.ProtoTypeUDP - ProtoTypeUDP = stun.ProtoTypeUDP - - // ProtoTypeTCP indicates the URL uses a TCP transport. - // - // Deprecated: Please use pion/stun.ProtoTypeTCP - ProtoTypeTCP = stun.ProtoTypeTCP -) - -// Unknown represents and unknown ProtoType or SchemeType -// -// Deprecated: Please use pion/stun.SchemeTypeUnknown or pion/stun.ProtoTypeUnknown -const Unknown = 0 - -// ParseURL parses a STUN or TURN urls following the ABNF syntax described in -// https://tools.ietf.org/html/rfc7064 and https://tools.ietf.org/html/rfc7065 -// respectively. -// -// Deprecated: Please use pion/stun.ParseURI -var ParseURL = stun.ParseURI //nolint:gochecknoglobals - -// NewSchemeType defines a procedure for creating a new SchemeType from a raw -// string naming the scheme type. -// -// Deprecated: Please use pion/stun.NewSchemeType -var NewSchemeType = stun.NewSchemeType //nolint:gochecknoglobals - -// NewProtoType defines a procedure for creating a new ProtoType from a raw -// string naming the transport protocol type. -// -// Deprecated: Please use pion/stun.NewProtoType -var NewProtoType = stun.NewProtoType //nolint:gochecknoglobals diff --git a/vendor/github.com/pion/ice/v2/usecandidate.go b/vendor/github.com/pion/ice/v2/usecandidate.go deleted file mode 100644 index 6fc7ed50..00000000 --- a/vendor/github.com/pion/ice/v2/usecandidate.go +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package ice - -import "github.com/pion/stun" - -// UseCandidateAttr represents USE-CANDIDATE attribute. -type UseCandidateAttr struct{} - -// AddTo adds USE-CANDIDATE attribute to message. -func (UseCandidateAttr) AddTo(m *stun.Message) error { - m.Add(stun.AttrUseCandidate, nil) - return nil -} - -// IsSet returns true if USE-CANDIDATE attribute is set. -func (UseCandidateAttr) IsSet(m *stun.Message) bool { - _, err := m.Get(stun.AttrUseCandidate) - return err == nil -} - -// UseCandidate is shorthand for UseCandidateAttr. -func UseCandidate() UseCandidateAttr { - return UseCandidateAttr{} -} diff --git a/vendor/github.com/pion/interceptor/AUTHORS.txt b/vendor/github.com/pion/interceptor/AUTHORS.txt deleted file mode 100644 index 44a421ef..00000000 --- a/vendor/github.com/pion/interceptor/AUTHORS.txt +++ /dev/null @@ -1,30 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aaron Boushley -Adam Kiss -adamroach -Aditya Kumar -aler9 <46489434+aler9@users.noreply.github.com> -Antoine Baché -Atsushi Watanabe -Bobby Peck -boks1971 -David Zhao -Jonathan Müller -Kevin Caffrey -Maksim Nesterov -Mathis Engelbart -Miroslav -Miroslav Šedivý -Quentin Renard -Rayleigh Li -Sean DuBois -Steffen Vogel -XLPolar -ziminghua <565209960@qq.com> - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/interceptor/pkg/nack/retainable_packet.go b/vendor/github.com/pion/interceptor/pkg/nack/retainable_packet.go deleted file mode 100644 index 31e9d832..00000000 --- a/vendor/github.com/pion/interceptor/pkg/nack/retainable_packet.go +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package nack - -import ( - "io" - "sync" - - "github.com/pion/rtp" -) - -const maxPayloadLen = 1460 - -type packetManager struct { - headerPool *sync.Pool - payloadPool *sync.Pool -} - -func newPacketManager() *packetManager { - return &packetManager{ - headerPool: &sync.Pool{ - New: func() interface{} { - return &rtp.Header{} - }, - }, - payloadPool: &sync.Pool{ - New: func() interface{} { - buf := make([]byte, maxPayloadLen) - return &buf - }, - }, - } -} - -func (m *packetManager) NewPacket(header *rtp.Header, payload []byte) (*retainablePacket, error) { - if len(payload) > maxPayloadLen { - return nil, io.ErrShortBuffer - } - - p := &retainablePacket{ - onRelease: m.releasePacket, - // new packets have retain count of 1 - count: 1, - } - - var ok bool - p.header, ok = m.headerPool.Get().(*rtp.Header) - if !ok { - return nil, errFailedToCastHeaderPool - } - - *p.header = header.Clone() - - if payload != nil { - p.buffer, ok = m.payloadPool.Get().(*[]byte) - if !ok { - return nil, errFailedToCastPayloadPool - } - - size := copy(*p.buffer, payload) - p.payload = (*p.buffer)[:size] - } - - return p, nil -} - -func (m *packetManager) releasePacket(header *rtp.Header, payload *[]byte) { - m.headerPool.Put(header) - if payload != nil { - m.payloadPool.Put(payload) - } -} - -type noOpPacketFactory struct{} - -func (f *noOpPacketFactory) NewPacket(header *rtp.Header, payload []byte) (*retainablePacket, error) { - return &retainablePacket{ - onRelease: f.releasePacket, - count: 1, - header: header, - payload: payload, - }, nil -} - -func (f *noOpPacketFactory) releasePacket(_ *rtp.Header, _ *[]byte) { - // no-op -} - -type retainablePacket struct { - onRelease func(*rtp.Header, *[]byte) - - countMu sync.Mutex - count int - - header *rtp.Header - buffer *[]byte - payload []byte -} - -func (p *retainablePacket) Header() *rtp.Header { - return p.header -} - -func (p *retainablePacket) Payload() []byte { - return p.payload -} - -func (p *retainablePacket) Retain() error { - p.countMu.Lock() - defer p.countMu.Unlock() - if p.count == 0 { - // already released - return errPacketReleased - } - p.count++ - return nil -} - -func (p *retainablePacket) Release() { - p.countMu.Lock() - defer p.countMu.Unlock() - p.count-- - - if p.count == 0 { - // release back to pool - p.onRelease(p.header, p.buffer) - p.header = nil - p.buffer = nil - p.payload = nil - } -} diff --git a/vendor/github.com/pion/interceptor/pkg/nack/send_buffer.go b/vendor/github.com/pion/interceptor/pkg/nack/send_buffer.go deleted file mode 100644 index e8e816f6..00000000 --- a/vendor/github.com/pion/interceptor/pkg/nack/send_buffer.go +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package nack - -import ( - "fmt" - "sync" -) - -const ( - uint16SizeHalf = 1 << 15 -) - -type sendBuffer struct { - packets []*retainablePacket - size uint16 - lastAdded uint16 - started bool - - m sync.RWMutex -} - -func newSendBuffer(size uint16) (*sendBuffer, error) { - allowedSizes := make([]uint16, 0) - correctSize := false - for i := 0; i < 16; i++ { - if size == 1<= uint16SizeHalf { - return nil - } - - if diff >= s.size { - return nil - } - - pkt := s.packets[seq%s.size] - if pkt != nil { - if pkt.Header().SequenceNumber != seq { - return nil - } - // already released - if err := pkt.Retain(); err != nil { - return nil - } - } - return pkt -} diff --git a/vendor/github.com/pion/logging/.travis.yml b/vendor/github.com/pion/logging/.travis.yml deleted file mode 100644 index b96a1edb..00000000 --- a/vendor/github.com/pion/logging/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: go - -go: - - "1.x" # use the latest Go release - -env: - - GO111MODULE=on - -before_script: - - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.15.0 - -script: - - golangci-lint run ./... -# - rm -rf examples # Remove examples, no test coverage for them - - go test -coverpkg=$(go list ./... | tr '\n' ',') -coverprofile=cover.out -v -race -covermode=atomic ./... - - bash <(curl -s https://codecov.io/bash) - - bash .github/assert-contributors.sh - - bash .github/lint-disallowed-functions-in-library.sh - - bash .github/lint-commit-message.sh diff --git a/vendor/github.com/pion/mdns/.gitignore b/vendor/github.com/pion/mdns/.gitignore deleted file mode 100644 index f977e748..00000000 --- a/vendor/github.com/pion/mdns/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/mdns/.golangci.yml b/vendor/github.com/pion/mdns/.golangci.yml deleted file mode 100644 index 48696f16..00000000 --- a/vendor/github.com/pion/mdns/.golangci.yml +++ /dev/null @@ -1,116 +0,0 @@ -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - forbidigo # Forbids identifiers - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/mdns/.goreleaser.yml b/vendor/github.com/pion/mdns/.goreleaser.yml deleted file mode 100644 index 2caa5fbd..00000000 --- a/vendor/github.com/pion/mdns/.goreleaser.yml +++ /dev/null @@ -1,2 +0,0 @@ -builds: -- skip: true diff --git a/vendor/github.com/pion/mdns/AUTHORS.txt b/vendor/github.com/pion/mdns/AUTHORS.txt deleted file mode 100644 index 48ceb821..00000000 --- a/vendor/github.com/pion/mdns/AUTHORS.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Atsushi Watanabe -Bjørn Remseth -Doug Cone -Hugo Arregui -Javier Peletier -Jonas van den Berg <24623262+vonas@users.noreply.github.com> -Konstantin Itskov -Sean DuBois -Sean DuBois - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/mdns/LICENSE b/vendor/github.com/pion/mdns/LICENSE deleted file mode 100644 index ab602974..00000000 --- a/vendor/github.com/pion/mdns/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/pion/mdns/README.md b/vendor/github.com/pion/mdns/README.md deleted file mode 100644 index b2d7d9c7..00000000 --- a/vendor/github.com/pion/mdns/README.md +++ /dev/null @@ -1,59 +0,0 @@ -

-
- Pion mDNS -
-

-

A Go implementation of mDNS

-

- Pion mDNS - Slack Widget -
- Build Status - GoDoc - Coverage Status - Go Report Card - License: MIT -

-
- -Go mDNS implementation. The original user is Pion WebRTC, but we would love to see it work for everyone. - -### Running Server -For a mDNS server that responds to queries for `pion-test.local` -```sh -go run examples/server/main.go -``` - - -### Running Client -To query using Pion you can run the `query` example -```sh -go run examples/query/main.go -``` - -You can use the macOS client -``` -dns-sd -q pion-test.local -``` - -Or the avahi client -``` -avahi-resolve -a pion-test.local -``` - -### References -https://tools.ietf.org/html/rfc6762 -https://tools.ietf.org/id/draft-ietf-rtcweb-mdns-ice-candidates-02.html - -### Community -Pion has an active community on the [Golang Slack](https://invite.slack.golangbridge.org/). Sign up and join the **#pion** channel for discussions and support. You can also use [Pion mailing list](https://groups.google.com/forum/#!forum/pion). - -We are always looking to support **your projects**. Please reach out if you have something to build! - -If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) - -### Contributing -Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible: - -### License -MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/mdns/codecov.yml b/vendor/github.com/pion/mdns/codecov.yml deleted file mode 100644 index 085200a4..00000000 --- a/vendor/github.com/pion/mdns/codecov.yml +++ /dev/null @@ -1,20 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/mdns/config.go b/vendor/github.com/pion/mdns/config.go deleted file mode 100644 index e028046e..00000000 --- a/vendor/github.com/pion/mdns/config.go +++ /dev/null @@ -1,27 +0,0 @@ -package mdns - -import ( - "time" - - "github.com/pion/logging" -) - -const ( - // DefaultAddress is the default used by mDNS - // and in most cases should be the address that the - // net.Conn passed to Server is bound to - DefaultAddress = "224.0.0.0:5353" -) - -// Config is used to configure a mDNS client or server. -type Config struct { - // QueryInterval controls how often we sends Queries until we - // get a response for the requested name - QueryInterval time.Duration - - // LocalNames are the names that we will generate answers for - // when we get questions - LocalNames []string - - LoggerFactory logging.LoggerFactory -} diff --git a/vendor/github.com/pion/mdns/conn.go b/vendor/github.com/pion/mdns/conn.go deleted file mode 100644 index 31037e25..00000000 --- a/vendor/github.com/pion/mdns/conn.go +++ /dev/null @@ -1,384 +0,0 @@ -package mdns - -import ( - "context" - "errors" - "math/big" - "net" - "runtime" - "sync" - "time" - - "github.com/pion/logging" - "golang.org/x/net/dns/dnsmessage" - "golang.org/x/net/ipv4" -) - -// Conn represents a mDNS Server -type Conn struct { - mu sync.RWMutex - log logging.LeveledLogger - - socket *ipv4.PacketConn - dstAddr *net.UDPAddr - - queryInterval time.Duration - localNames []string - queries []query - ifaces []net.Interface - - closed chan interface{} -} - -type query struct { - nameWithSuffix string - queryResultChan chan queryResult -} - -type queryResult struct { - answer dnsmessage.ResourceHeader - addr net.Addr -} - -const ( - defaultQueryInterval = time.Second - destinationAddress = "224.0.0.251:5353" - maxMessageRecords = 3 - responseTTL = 120 -) - -var errNoPositiveMTUFound = errors.New("no positive MTU found") - -// Server establishes a mDNS connection over an existing conn -func Server(conn *ipv4.PacketConn, config *Config) (*Conn, error) { - if config == nil { - return nil, errNilConfig - } - - ifaces, err := net.Interfaces() - if err != nil { - return nil, err - } - - inboundBufferSize := 0 - joinErrCount := 0 - ifacesToUse := make([]net.Interface, 0, len(ifaces)) - for i, ifc := range ifaces { - if err = conn.JoinGroup(&ifaces[i], &net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)}); err != nil { - joinErrCount++ - continue - } - - ifcCopy := ifc - ifacesToUse = append(ifacesToUse, ifcCopy) - if ifaces[i].MTU > inboundBufferSize { - inboundBufferSize = ifaces[i].MTU - } - } - - if inboundBufferSize == 0 { - return nil, errNoPositiveMTUFound - } - if joinErrCount >= len(ifaces) { - return nil, errJoiningMulticastGroup - } - - dstAddr, err := net.ResolveUDPAddr("udp", destinationAddress) - if err != nil { - return nil, err - } - - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - localNames := []string{} - for _, l := range config.LocalNames { - localNames = append(localNames, l+".") - } - - c := &Conn{ - queryInterval: defaultQueryInterval, - queries: []query{}, - socket: conn, - dstAddr: dstAddr, - localNames: localNames, - ifaces: ifacesToUse, - log: loggerFactory.NewLogger("mdns"), - closed: make(chan interface{}), - } - if config.QueryInterval != 0 { - c.queryInterval = config.QueryInterval - } - - // https://www.rfc-editor.org/rfc/rfc6762.html#section-17 - // Multicast DNS messages carried by UDP may be up to the IP MTU of the - // physical interface, less the space required for the IP header (20 - // bytes for IPv4; 40 bytes for IPv6) and the UDP header (8 bytes). - go c.start(inboundBufferSize - 20 - 8) - return c, nil -} - -// Close closes the mDNS Conn -func (c *Conn) Close() error { - select { - case <-c.closed: - return nil - default: - } - - if err := c.socket.Close(); err != nil { - return err - } - - <-c.closed - return nil -} - -// Query sends mDNS Queries for the following name until -// either the Context is canceled/expires or we get a result -func (c *Conn) Query(ctx context.Context, name string) (dnsmessage.ResourceHeader, net.Addr, error) { - select { - case <-c.closed: - return dnsmessage.ResourceHeader{}, nil, errConnectionClosed - default: - } - - nameWithSuffix := name + "." - - queryChan := make(chan queryResult, 1) - c.mu.Lock() - c.queries = append(c.queries, query{nameWithSuffix, queryChan}) - ticker := time.NewTicker(c.queryInterval) - c.mu.Unlock() - - defer ticker.Stop() - - c.sendQuestion(nameWithSuffix) - for { - select { - case <-ticker.C: - c.sendQuestion(nameWithSuffix) - case <-c.closed: - return dnsmessage.ResourceHeader{}, nil, errConnectionClosed - case res := <-queryChan: - return res.answer, res.addr, nil - case <-ctx.Done(): - return dnsmessage.ResourceHeader{}, nil, errContextElapsed - } - } -} - -func ipToBytes(ip net.IP) (out [4]byte) { - rawIP := ip.To4() - if rawIP == nil { - return - } - - ipInt := big.NewInt(0) - ipInt.SetBytes(rawIP) - copy(out[:], ipInt.Bytes()) - return -} - -func interfaceForRemote(remote string) (net.IP, error) { - conn, err := net.Dial("udp", remote) - if err != nil { - return nil, err - } - - localAddr, ok := conn.LocalAddr().(*net.UDPAddr) - if !ok { - return nil, errFailedCast - } - - if err := conn.Close(); err != nil { - return nil, err - } - - return localAddr.IP, nil -} - -func (c *Conn) sendQuestion(name string) { - packedName, err := dnsmessage.NewName(name) - if err != nil { - c.log.Warnf("Failed to construct mDNS packet %v", err) - return - } - - msg := dnsmessage.Message{ - Header: dnsmessage.Header{}, - Questions: []dnsmessage.Question{ - { - Type: dnsmessage.TypeA, - Class: dnsmessage.ClassINET, - Name: packedName, - }, - }, - } - - rawQuery, err := msg.Pack() - if err != nil { - c.log.Warnf("Failed to construct mDNS packet %v", err) - return - } - - c.writeToSocket(rawQuery) -} - -const isWindows = runtime.GOOS == "windows" - -func (c *Conn) writeToSocket(b []byte) { - var wcm ipv4.ControlMessage - for i := range c.ifaces { - if isWindows { - if err := c.socket.SetMulticastInterface(&c.ifaces[i]); err != nil { - c.log.Warnf("Failed to set multicast interface for %d: %v", i, err) - } - } else { - wcm.IfIndex = c.ifaces[i].Index - } - if _, err := c.socket.WriteTo(b, &wcm, c.dstAddr); err != nil { - c.log.Warnf("Failed to send mDNS packet on interface %d: %v", i, err) - } - } -} - -func (c *Conn) sendAnswer(name string, dst net.IP) { - packedName, err := dnsmessage.NewName(name) - if err != nil { - c.log.Warnf("Failed to construct mDNS packet %v", err) - return - } - - msg := dnsmessage.Message{ - Header: dnsmessage.Header{ - Response: true, - Authoritative: true, - }, - Answers: []dnsmessage.Resource{ - { - Header: dnsmessage.ResourceHeader{ - Type: dnsmessage.TypeA, - Class: dnsmessage.ClassINET, - Name: packedName, - TTL: responseTTL, - }, - Body: &dnsmessage.AResource{ - A: ipToBytes(dst), - }, - }, - }, - } - - rawAnswer, err := msg.Pack() - if err != nil { - c.log.Warnf("Failed to construct mDNS packet %v", err) - return - } - - c.writeToSocket(rawAnswer) -} - -func (c *Conn) start(inboundBufferSize int) { //nolint gocognit - defer func() { - c.mu.Lock() - defer c.mu.Unlock() - close(c.closed) - }() - - b := make([]byte, inboundBufferSize) - p := dnsmessage.Parser{} - - for { - n, _, src, err := c.socket.ReadFrom(b) - if err != nil { - if errors.Is(err, net.ErrClosed) { - return - } - c.log.Warnf("Failed to ReadFrom %q %v", src, err) - continue - } - - func() { - c.mu.RLock() - defer c.mu.RUnlock() - - if _, err := p.Start(b[:n]); err != nil { - c.log.Warnf("Failed to parse mDNS packet %v", err) - return - } - - for i := 0; i <= maxMessageRecords; i++ { - q, err := p.Question() - if errors.Is(err, dnsmessage.ErrSectionDone) { - break - } else if err != nil { - c.log.Warnf("Failed to parse mDNS packet %v", err) - return - } - - for _, localName := range c.localNames { - if localName == q.Name.String() { - localAddress, err := interfaceForRemote(src.String()) - if err != nil { - c.log.Warnf("Failed to get local interface to communicate with %s: %v", src.String(), err) - continue - } - - c.sendAnswer(q.Name.String(), localAddress) - } - } - } - - for i := 0; i <= maxMessageRecords; i++ { - a, err := p.AnswerHeader() - if errors.Is(err, dnsmessage.ErrSectionDone) { - return - } - if err != nil { - c.log.Warnf("Failed to parse mDNS packet %v", err) - return - } - - if a.Type != dnsmessage.TypeA && a.Type != dnsmessage.TypeAAAA { - continue - } - - for i := len(c.queries) - 1; i >= 0; i-- { - if c.queries[i].nameWithSuffix == a.Name.String() { - ip, err := ipFromAnswerHeader(a, p) - if err != nil { - c.log.Warnf("Failed to parse mDNS answer %v", err) - return - } - - c.queries[i].queryResultChan <- queryResult{a, &net.IPAddr{ - IP: ip, - }} - c.queries = append(c.queries[:i], c.queries[i+1:]...) - } - } - } - }() - } -} - -func ipFromAnswerHeader(a dnsmessage.ResourceHeader, p dnsmessage.Parser) (ip []byte, err error) { - if a.Type == dnsmessage.TypeA { - resource, err := p.AResource() - if err != nil { - return nil, err - } - ip = net.IP(resource.A[:]) - } else { - resource, err := p.AAAAResource() - if err != nil { - return nil, err - } - ip = resource.AAAA[:] - } - - return -} diff --git a/vendor/github.com/pion/mdns/errors.go b/vendor/github.com/pion/mdns/errors.go deleted file mode 100644 index 0a1b6124..00000000 --- a/vendor/github.com/pion/mdns/errors.go +++ /dev/null @@ -1,11 +0,0 @@ -package mdns - -import "errors" - -var ( - errJoiningMulticastGroup = errors.New("mDNS: failed to join multicast group") - errConnectionClosed = errors.New("mDNS: connection is closed") - errContextElapsed = errors.New("mDNS: context has elapsed") - errNilConfig = errors.New("mDNS: config must not be nil") - errFailedCast = errors.New("mDNS: failed to cast listener to UDPAddr") -) diff --git a/vendor/github.com/pion/mdns/mdns.go b/vendor/github.com/pion/mdns/mdns.go deleted file mode 100644 index 853ae833..00000000 --- a/vendor/github.com/pion/mdns/mdns.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package mdns implements mDNS (multicast DNS) -package mdns diff --git a/vendor/github.com/pion/mdns/renovate.json b/vendor/github.com/pion/mdns/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/mdns/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/rtcp/AUTHORS.txt b/vendor/github.com/pion/rtcp/AUTHORS.txt deleted file mode 100644 index 5d5a53cc..00000000 --- a/vendor/github.com/pion/rtcp/AUTHORS.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see `.github/generate-authors.sh` for the scripting -Adam Roach -adwpc -aggresss -Atsushi Watanabe -cnderrauber -Gabor Pongracz -Hugo Arregui -Hugo Arregui -Juliusz Chroboczek -Kevin Wang -lllf -Luke Curley -Mathis Engelbart -Max Hawkins -Sean DuBois -Sean DuBois -Simone Gotti -Woodrow Douglass diff --git a/vendor/github.com/pion/rtcp/fuzz.go b/vendor/github.com/pion/rtcp/fuzz.go deleted file mode 100644 index b8118224..00000000 --- a/vendor/github.com/pion/rtcp/fuzz.go +++ /dev/null @@ -1,52 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package rtcp - -import ( - "bytes" - "io" -) - -// Fuzz implements a randomized fuzz test of the rtcp -// parser using go-fuzz. -// -// To run the fuzzer, first download go-fuzz: -// `go get github.com/dvyukov/go-fuzz/...` -// -// Then build the testing package: -// `go-fuzz-build github.com/pion/webrtc` -// -// And run the fuzzer on the corpus: -// ``` -// mkdir workdir -// -// # optionally add a starter corpus of valid rtcp packets. -// # the corpus should be as compact and diverse as possible. -// cp -r ~/my-rtcp-packets workdir/corpus -// -// go-fuzz -bin=ase-fuzz.zip -workdir=workdir -// ```` -func Fuzz(data []byte) int { - r := NewReader(bytes.NewReader(data)) - for { - _, data, err := r.ReadPacket() - if err == io.EOF { - break - } - if err != nil { - return 0 - } - - packet, err := Unmarshal(data) - if err != nil { - return 0 - } - - if _, err := packet.Marshal(); err != nil { - return 0 - } - } - - return 1 -} diff --git a/vendor/github.com/pion/rtp/AUTHORS.txt b/vendor/github.com/pion/rtp/AUTHORS.txt deleted file mode 100644 index a7bc7a02..00000000 --- a/vendor/github.com/pion/rtp/AUTHORS.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see `.github/generate-authors.sh` for the scripting -adwpc -aler9 <46489434+aler9@users.noreply.github.com> -Antoine Baché -Antoine Baché -Atsushi Watanabe -baiyufei -Bao Nguyen -boks1971 -debiandebiandebian -ffmiyo -Guilherme -Haiyang Wang -Hugo Arregui -John Bradley -Juliusz Chroboczek -Kazuyuki Honda -Luke Curley -lxb -Michael MacDonald -Michael MacDonald -Michael Uti -Raphael Derosso Pereira -Rob Lofthouse -Robin Raymond -Sean DuBois -Sean DuBois -Sean DuBois -Simone Gotti -Tarrence van As -wangzixiang -Woodrow Douglass diff --git a/vendor/github.com/pion/rtp/pkg/frame/av1.go b/vendor/github.com/pion/rtp/pkg/frame/av1.go deleted file mode 100644 index 30525abc..00000000 --- a/vendor/github.com/pion/rtp/pkg/frame/av1.go +++ /dev/null @@ -1,44 +0,0 @@ -// Package frame provides code to construct complete media frames from packetized media -package frame - -import "github.com/pion/rtp/codecs" - -// AV1 represents a collection of OBUs given a stream of AV1 Packets. -// Each AV1 RTP Packet is a collection of OBU Elements. Each OBU Element may be a full OBU, or just a fragment of one. -// AV1 provides the tools to construct a collection of OBUs from a collection of OBU Elements. This structure -// contains an internal cache and should be used for the entire RTP Stream. -type AV1 struct { - // Buffer for fragmented OBU. If ReadFrames is called on a RTP Packet - // that doesn't contain a fully formed OBU - obuBuffer []byte -} - -func (f *AV1) pushOBUElement(isFirstOBUFragment *bool, obuElement []byte, obuList [][]byte) [][]byte { - if *isFirstOBUFragment { - *isFirstOBUFragment = false - // Discard pushed because we don't have a fragment to combine it with - if f.obuBuffer == nil { - return obuList - } - obuElement = append(f.obuBuffer, obuElement...) - f.obuBuffer = nil - } - return append(obuList, obuElement) -} - -// ReadFrames processes the codecs.AV1Packet and returns fully constructed frames -func (f *AV1) ReadFrames(pkt *codecs.AV1Packet) ([][]byte, error) { - OBUs := [][]byte{} - isFirstOBUFragment := pkt.Z - - for i := range pkt.OBUElements { - OBUs = f.pushOBUElement(&isFirstOBUFragment, pkt.OBUElements[i], OBUs) - } - - if pkt.Y && len(OBUs) > 0 { - // Take copy of OBUElement that is being cached - f.obuBuffer = append(f.obuBuffer, append([]byte{}, OBUs[len(OBUs)-1]...)...) - OBUs = OBUs[:len(OBUs)-1] - } - return OBUs, nil -} diff --git a/vendor/github.com/pion/rtp/pkg/obu/leb128.go b/vendor/github.com/pion/rtp/pkg/obu/leb128.go deleted file mode 100644 index 988a8f44..00000000 --- a/vendor/github.com/pion/rtp/pkg/obu/leb128.go +++ /dev/null @@ -1,66 +0,0 @@ -// Package obu implements tools for working with the "Open Bitstream Unit" -package obu - -import "errors" - -const ( - sevenLsbBitmask = uint(0b01111111) - msbBitmask = uint(0b10000000) -) - -// ErrFailedToReadLEB128 indicates that a buffer ended before a LEB128 value could be successfully read -var ErrFailedToReadLEB128 = errors.New("payload ended before LEB128 was finished") - -// EncodeLEB128 encodes a uint as LEB128 -func EncodeLEB128(in uint) (out uint) { - for { - // Copy seven bits from in and discard - // what we have copied from in - out |= (in & sevenLsbBitmask) - in >>= 7 - - // If we have more bits to encode set MSB - // otherwise we are done - if in != 0 { - out |= msbBitmask - out <<= 8 - } else { - return out - } - } -} - -func decodeLEB128(in uint) (out uint) { - for { - // Take 7 LSB from in - out |= (in & sevenLsbBitmask) - - // Discard the MSB - in >>= 8 - if in == 0 { - return out - } - - out <<= 7 - } -} - -// ReadLeb128 scans an buffer and decodes a Leb128 value. -// If the end of the buffer is reached and all MSB are set -// an error is returned -func ReadLeb128(in []byte) (uint, uint, error) { - var encodedLength uint - - for i := range in { - encodedLength |= uint(in[i]) - - if in[i]&byte(msbBitmask) == 0 { - return decodeLEB128(encodedLength), uint(i + 1), nil - } - - // Make more room for next read - encodedLength <<= 8 - } - - return 0, 0, ErrFailedToReadLEB128 -} diff --git a/vendor/github.com/pion/sctp/AUTHORS.txt b/vendor/github.com/pion/sctp/AUTHORS.txt deleted file mode 100644 index ed95135c..00000000 --- a/vendor/github.com/pion/sctp/AUTHORS.txt +++ /dev/null @@ -1,33 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aaron France -Adrian Cable -Atsushi Watanabe -backkem -Cecylia Bocovich -chenkaiC4 -Eric Daniels -Hugo Arregui -Hugo Arregui -Jerko Steiner -Jerry Tao -John Bradley -Konstantin Itskov -Lukas Herman -Luke Curley -Michael MacDonald -ronan -Sam Lancia -Sean DuBois -Sean DuBois -Steffen Vogel -Teddy -Will Forcey -Yutaka Takeda -ZHENK - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/sdp/v3/AUTHORS.txt b/vendor/github.com/pion/sdp/v3/AUTHORS.txt deleted file mode 100644 index 038e5991..00000000 --- a/vendor/github.com/pion/sdp/v3/AUTHORS.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see `.github/generate-authors.sh` for the scripting -adwpc -Atsushi Watanabe -backkem -Brendan Abolivier -chenkaiC4 -cnderrauber -Daniele Sluijters -Graham King -Guilherme -Hugo Arregui -Jason -Jerko Steiner -John Bradley -Konstantin Itskov -korymiller1489 -Luke S -Max Hawkins -Maxim Oransky -mchlrhw <4028654+mchlrhw@users.noreply.github.com> -Michael MacDonald -Mustafa Navruz -Roman Romanenko -Sean DuBois -Sean DuBois -tarrencev -Woodrow Douglass -ZHENK diff --git a/vendor/github.com/pion/sdp/v3/fuzz.go b/vendor/github.com/pion/sdp/v3/fuzz.go deleted file mode 100644 index f41ef78c..00000000 --- a/vendor/github.com/pion/sdp/v3/fuzz.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build gofuzz - -package sdp - -// Fuzz implements a randomized fuzz test of the sdp -// parser using go-fuzz. -// -// To run the fuzzer, first download go-fuzz: -// `go get github.com/dvyukov/go-fuzz/...` -// -// Then build the testing package: -// `go-fuzz-build` -// -// And run the fuzzer on the corpus: -// `go-fuzz` -func Fuzz(data []byte) int { - // Check that unmarshalling any byte slice does not panic. - var sd SessionDescription - if err := sd.Unmarshal(data); err != nil { - return 0 - } - // Check that we can marshal anything we unmarshalled. - _, err := sd.Marshal() - if err != nil { - panic("failed to marshal") // nolint - } - // It'd be nice to check that if we round trip Marshal then Unmarshal, - // we get the original back. Right now, though, we frequently don't, - // and we'd need to fix that first. - return 1 -} diff --git a/vendor/github.com/pion/srtp/v2/.gitignore b/vendor/github.com/pion/srtp/v2/.gitignore deleted file mode 100644 index 6e2f206a..00000000 --- a/vendor/github.com/pion/srtp/v2/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/srtp/v2/.golangci.yml b/vendor/github.com/pion/srtp/v2/.golangci.yml deleted file mode 100644 index 4e3eddf4..00000000 --- a/vendor/github.com/pion/srtp/v2/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/srtp/v2/.goreleaser.yml b/vendor/github.com/pion/srtp/v2/.goreleaser.yml deleted file mode 100644 index 30093e9d..00000000 --- a/vendor/github.com/pion/srtp/v2/.goreleaser.yml +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -builds: -- skip: true diff --git a/vendor/github.com/pion/srtp/v2/AUTHORS.txt b/vendor/github.com/pion/srtp/v2/AUTHORS.txt deleted file mode 100644 index daca101e..00000000 --- a/vendor/github.com/pion/srtp/v2/AUTHORS.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -adamroach -Adrian Cable -Agniva De Sarker -Antoine Baché -Atsushi Watanabe -backkem -chenkaiC4 -Chris Hiszpanski -cszdlt -Hugo Arregui -Jerko Steiner -Juliusz Chroboczek -Luke Curley -Luke Curley -Max Hawkins -mission-liao -Novel Corpse -OrlandoCo -Patryk -Patryk Rogalski -Sean DuBois -Sean DuBois -SeongGyu Park -Steffen -Steffen Vogel -Tobias Fridén -Woodrow Douglass -Yutaka Takeda - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/srtp/v2/LICENSE b/vendor/github.com/pion/srtp/v2/LICENSE deleted file mode 100644 index 491caf6b..00000000 --- a/vendor/github.com/pion/srtp/v2/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2023 The Pion community - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/pion/srtp/v2/README.md b/vendor/github.com/pion/srtp/v2/README.md deleted file mode 100644 index d0e94e7a..00000000 --- a/vendor/github.com/pion/srtp/v2/README.md +++ /dev/null @@ -1,35 +0,0 @@ -

-
- Pion SRTP -
-

-

A Go implementation of SRTP

-

- Pion SRTP - Sourcegraph Widget - Slack Widget -
- GitHub Workflow Status - Go Reference - Coverage Status - Go Report Card - License: MIT -

-
- -### Roadmap -The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones. - -### Community -Pion has an active community on the [Slack](https://pion.ly/slack). - -Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news. - -We are always looking to support **your projects**. Please reach out if you have something to build! -If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) - -### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) - -### License -MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/srtp/v2/codecov.yml b/vendor/github.com/pion/srtp/v2/codecov.yml deleted file mode 100644 index 263e4d45..00000000 --- a/vendor/github.com/pion/srtp/v2/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/srtp/v2/context.go b/vendor/github.com/pion/srtp/v2/context.go deleted file mode 100644 index 27da02cf..00000000 --- a/vendor/github.com/pion/srtp/v2/context.go +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "fmt" - - "github.com/pion/transport/v2/replaydetector" -) - -const ( - labelSRTPEncryption = 0x00 - labelSRTPAuthenticationTag = 0x01 - labelSRTPSalt = 0x02 - - labelSRTCPEncryption = 0x03 - labelSRTCPAuthenticationTag = 0x04 - labelSRTCPSalt = 0x05 - - maxSequenceNumber = 65535 - maxROC = (1 << 32) - 1 - - seqNumMedian = 1 << 15 - seqNumMax = 1 << 16 - - srtcpIndexSize = 4 -) - -// Encrypt/Decrypt state for a single SRTP SSRC -type srtpSSRCState struct { - ssrc uint32 - rolloverHasProcessed bool - index uint64 - replayDetector replaydetector.ReplayDetector -} - -// Encrypt/Decrypt state for a single SRTCP SSRC -type srtcpSSRCState struct { - srtcpIndex uint32 - ssrc uint32 - replayDetector replaydetector.ReplayDetector -} - -// Context represents a SRTP cryptographic context. -// Context can only be used for one-way operations. -// it must either used ONLY for encryption or ONLY for decryption. -// Note that Context does not provide any concurrency protection: -// access to a Context from multiple goroutines requires external -// synchronization. -type Context struct { - cipher srtpCipher - - srtpSSRCStates map[uint32]*srtpSSRCState - srtcpSSRCStates map[uint32]*srtcpSSRCState - - newSRTCPReplayDetector func() replaydetector.ReplayDetector - newSRTPReplayDetector func() replaydetector.ReplayDetector -} - -// CreateContext creates a new SRTP Context. -// -// CreateContext receives variable number of ContextOption-s. -// Passing multiple options which set the same parameter let the last one valid. -// Following example create SRTP Context with replay protection with window size of 256. -// -// decCtx, err := srtp.CreateContext(key, salt, profile, srtp.SRTPReplayProtection(256)) -func CreateContext(masterKey, masterSalt []byte, profile ProtectionProfile, opts ...ContextOption) (c *Context, err error) { - keyLen, err := profile.keyLen() - if err != nil { - return nil, err - } - - saltLen, err := profile.saltLen() - if err != nil { - return nil, err - } - - if masterKeyLen := len(masterKey); masterKeyLen != keyLen { - return c, fmt.Errorf("%w expected(%d) actual(%d)", errShortSrtpMasterKey, masterKey, keyLen) - } else if masterSaltLen := len(masterSalt); masterSaltLen != saltLen { - return c, fmt.Errorf("%w expected(%d) actual(%d)", errShortSrtpMasterSalt, saltLen, masterSaltLen) - } - - c = &Context{ - srtpSSRCStates: map[uint32]*srtpSSRCState{}, - srtcpSSRCStates: map[uint32]*srtcpSSRCState{}, - } - - switch profile { - case ProtectionProfileAeadAes128Gcm, ProtectionProfileAeadAes256Gcm: - c.cipher, err = newSrtpCipherAeadAesGcm(profile, masterKey, masterSalt) - case ProtectionProfileAes128CmHmacSha1_32, ProtectionProfileAes128CmHmacSha1_80: - c.cipher, err = newSrtpCipherAesCmHmacSha1(profile, masterKey, masterSalt) - default: - return nil, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, profile) - } - if err != nil { - return nil, err - } - - for _, o := range append( - []ContextOption{ // Default options - SRTPNoReplayProtection(), - SRTCPNoReplayProtection(), - }, - opts..., // User specified options - ) { - if errOpt := o(c); errOpt != nil { - return nil, errOpt - } - } - - return c, nil -} - -// https://tools.ietf.org/html/rfc3550#appendix-A.1 -func (s *srtpSSRCState) nextRolloverCount(sequenceNumber uint16) (roc uint32, diff int32, overflow bool) { - seq := int32(sequenceNumber) - localRoc := uint32(s.index >> 16) - localSeq := int32(s.index & (seqNumMax - 1)) - - guessRoc := localRoc - var difference int32 - - if s.rolloverHasProcessed { - // When localROC is equal to 0, and entering seq-localSeq > seqNumMedian - // judgment, it will cause guessRoc calculation error - if s.index > seqNumMedian { - if localSeq < seqNumMedian { - if seq-localSeq > seqNumMedian { - guessRoc = localRoc - 1 - difference = seq - localSeq - seqNumMax - } else { - guessRoc = localRoc - difference = seq - localSeq - } - } else { - if localSeq-seqNumMedian > seq { - guessRoc = localRoc + 1 - difference = seq - localSeq + seqNumMax - } else { - guessRoc = localRoc - difference = seq - localSeq - } - } - } else { - // localRoc is equal to 0 - difference = seq - localSeq - } - } - - return guessRoc, difference, (guessRoc == 0 && localRoc == maxROC) -} - -func (s *srtpSSRCState) updateRolloverCount(sequenceNumber uint16, difference int32) { - if !s.rolloverHasProcessed { - s.index |= uint64(sequenceNumber) - s.rolloverHasProcessed = true - return - } - if difference > 0 { - s.index += uint64(difference) - } -} - -func (c *Context) getSRTPSSRCState(ssrc uint32) *srtpSSRCState { - s, ok := c.srtpSSRCStates[ssrc] - if ok { - return s - } - - s = &srtpSSRCState{ - ssrc: ssrc, - replayDetector: c.newSRTPReplayDetector(), - } - c.srtpSSRCStates[ssrc] = s - return s -} - -func (c *Context) getSRTCPSSRCState(ssrc uint32) *srtcpSSRCState { - s, ok := c.srtcpSSRCStates[ssrc] - if ok { - return s - } - - s = &srtcpSSRCState{ - ssrc: ssrc, - replayDetector: c.newSRTCPReplayDetector(), - } - c.srtcpSSRCStates[ssrc] = s - return s -} - -// ROC returns SRTP rollover counter value of specified SSRC. -func (c *Context) ROC(ssrc uint32) (uint32, bool) { - s, ok := c.srtpSSRCStates[ssrc] - if !ok { - return 0, false - } - return uint32(s.index >> 16), true -} - -// SetROC sets SRTP rollover counter value of specified SSRC. -func (c *Context) SetROC(ssrc uint32, roc uint32) { - s := c.getSRTPSSRCState(ssrc) - s.index = uint64(roc) << 16 - s.rolloverHasProcessed = false -} - -// Index returns SRTCP index value of specified SSRC. -func (c *Context) Index(ssrc uint32) (uint32, bool) { - s, ok := c.srtcpSSRCStates[ssrc] - if !ok { - return 0, false - } - return s.srtcpIndex, true -} - -// SetIndex sets SRTCP index value of specified SSRC. -func (c *Context) SetIndex(ssrc uint32, index uint32) { - s := c.getSRTCPSSRCState(ssrc) - s.srtcpIndex = index % (maxSRTCPIndex + 1) -} diff --git a/vendor/github.com/pion/srtp/v2/crypto.go b/vendor/github.com/pion/srtp/v2/crypto.go deleted file mode 100644 index 9696e8f2..00000000 --- a/vendor/github.com/pion/srtp/v2/crypto.go +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "crypto/cipher" - - "github.com/pion/transport/v2/utils/xor" -) - -// incrementCTR increments a big-endian integer of arbitrary size. -func incrementCTR(ctr []byte) { - for i := len(ctr) - 1; i >= 0; i-- { - ctr[i]++ - if ctr[i] != 0 { - break - } - } -} - -// xorBytesCTR performs CTR encryption and decryption. -// It is equivalent to cipher.NewCTR followed by XORKeyStream. -func xorBytesCTR(block cipher.Block, iv []byte, dst, src []byte) error { - if len(iv) != block.BlockSize() { - return errBadIVLength - } - - ctr := make([]byte, len(iv)) - copy(ctr, iv) - bs := block.BlockSize() - stream := make([]byte, bs) - - i := 0 - for i < len(src) { - block.Encrypt(stream, ctr) - incrementCTR(ctr) - n := xor.XorBytes(dst[i:], src[i:], stream) - if n == 0 { - break - } - i += n - } - return nil -} diff --git a/vendor/github.com/pion/srtp/v2/errors.go b/vendor/github.com/pion/srtp/v2/errors.go deleted file mode 100644 index 5b1751d3..00000000 --- a/vendor/github.com/pion/srtp/v2/errors.go +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "errors" - "fmt" -) - -var ( - errDuplicated = errors.New("duplicated packet") - errShortSrtpMasterKey = errors.New("SRTP master key is not long enough") - errShortSrtpMasterSalt = errors.New("SRTP master salt is not long enough") - errNoSuchSRTPProfile = errors.New("no such SRTP Profile") - errNonZeroKDRNotSupported = errors.New("indexOverKdr > 0 is not supported yet") - errExporterWrongLabel = errors.New("exporter called with wrong label") - errNoConfig = errors.New("no config provided") - errNoConn = errors.New("no conn provided") - errFailedToVerifyAuthTag = errors.New("failed to verify auth tag") - errTooShortRTCP = errors.New("packet is too short to be rtcp packet") - errPayloadDiffers = errors.New("payload differs") - errStartedChannelUsedIncorrectly = errors.New("started channel used incorrectly, should only be closed") - errBadIVLength = errors.New("bad iv length in xorBytesCTR") - errExceededMaxPackets = errors.New("exceeded the maximum number of packets") - - errStreamNotInited = errors.New("stream has not been inited, unable to close") - errStreamAlreadyClosed = errors.New("stream is already closed") - errStreamAlreadyInited = errors.New("stream is already inited") - errFailedTypeAssertion = errors.New("failed to cast child") -) - -type duplicatedError struct { - Proto string // srtp or srtcp - SSRC uint32 - Index uint32 // sequence number or index -} - -func (e *duplicatedError) Error() string { - return fmt.Sprintf("%s ssrc=%d index=%d: %v", e.Proto, e.SSRC, e.Index, errDuplicated) -} - -func (e *duplicatedError) Unwrap() error { - return errDuplicated -} diff --git a/vendor/github.com/pion/srtp/v2/key_derivation.go b/vendor/github.com/pion/srtp/v2/key_derivation.go deleted file mode 100644 index 05f0f29f..00000000 --- a/vendor/github.com/pion/srtp/v2/key_derivation.go +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "crypto/aes" - "encoding/binary" -) - -func aesCmKeyDerivation(label byte, masterKey, masterSalt []byte, indexOverKdr int, outLen int) ([]byte, error) { - if indexOverKdr != 0 { - // 24-bit "index DIV kdr" must be xored to prf input. - return nil, errNonZeroKDRNotSupported - } - - // https://tools.ietf.org/html/rfc3711#appendix-B.3 - // The input block for AES-CM is generated by exclusive-oring the master salt with the - // concatenation of the encryption key label 0x00 with (index DIV kdr), - // - index is 'rollover count' and DIV is 'divided by' - - nMasterKey := len(masterKey) - nMasterSalt := len(masterSalt) - - prfIn := make([]byte, 16) - copy(prfIn[:nMasterSalt], masterSalt) - - prfIn[7] ^= label - - // The resulting value is then AES encrypted using the master key to get the cipher key. - block, err := aes.NewCipher(masterKey) - if err != nil { - return nil, err - } - - out := make([]byte, ((outLen+nMasterKey)/nMasterKey)*nMasterKey) - var i uint16 - for n := 0; n < outLen; n += block.BlockSize() { - binary.BigEndian.PutUint16(prfIn[len(prfIn)-2:], i) - block.Encrypt(out[n:n+nMasterKey], prfIn) - i++ - } - return out[:outLen], nil -} - -// Generate IV https://tools.ietf.org/html/rfc3711#section-4.1.1 -// where the 128-bit integer value IV SHALL be defined by the SSRC, the -// SRTP packet index i, and the SRTP session salting key k_s, as below. -// - ROC = a 32-bit unsigned rollover counter (ROC), which records how many -// - times the 16-bit RTP sequence number has been reset to zero after -// - passing through 65,535 -// i = 2^16 * ROC + SEQ -// IV = (salt*2 ^ 16) | (ssrc*2 ^ 64) | (i*2 ^ 16) -func generateCounter(sequenceNumber uint16, rolloverCounter uint32, ssrc uint32, sessionSalt []byte) (counter [16]byte) { - copy(counter[:], sessionSalt) - - counter[4] ^= byte(ssrc >> 24) - counter[5] ^= byte(ssrc >> 16) - counter[6] ^= byte(ssrc >> 8) - counter[7] ^= byte(ssrc) - counter[8] ^= byte(rolloverCounter >> 24) - counter[9] ^= byte(rolloverCounter >> 16) - counter[10] ^= byte(rolloverCounter >> 8) - counter[11] ^= byte(rolloverCounter) - counter[12] ^= byte(sequenceNumber >> 8) - counter[13] ^= byte(sequenceNumber) - - return counter -} diff --git a/vendor/github.com/pion/srtp/v2/keying.go b/vendor/github.com/pion/srtp/v2/keying.go deleted file mode 100644 index c5977c39..00000000 --- a/vendor/github.com/pion/srtp/v2/keying.go +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -const labelExtractorDtlsSrtp = "EXTRACTOR-dtls_srtp" - -// KeyingMaterialExporter allows package SRTP to extract keying material -type KeyingMaterialExporter interface { - ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) -} - -// ExtractSessionKeysFromDTLS allows setting the Config SessionKeys by -// extracting them from DTLS. This behavior is defined in RFC5764: -// https://tools.ietf.org/html/rfc5764 -func (c *Config) ExtractSessionKeysFromDTLS(exporter KeyingMaterialExporter, isClient bool) error { - keyLen, err := c.Profile.keyLen() - if err != nil { - return err - } - - saltLen, err := c.Profile.saltLen() - if err != nil { - return err - } - - keyingMaterial, err := exporter.ExportKeyingMaterial(labelExtractorDtlsSrtp, nil, (keyLen*2)+(saltLen*2)) - if err != nil { - return err - } - - offset := 0 - clientWriteKey := append([]byte{}, keyingMaterial[offset:offset+keyLen]...) - offset += keyLen - - serverWriteKey := append([]byte{}, keyingMaterial[offset:offset+keyLen]...) - offset += keyLen - - clientWriteKey = append(clientWriteKey, keyingMaterial[offset:offset+saltLen]...) - offset += saltLen - - serverWriteKey = append(serverWriteKey, keyingMaterial[offset:offset+saltLen]...) - - if isClient { - c.Keys.LocalMasterKey = clientWriteKey[0:keyLen] - c.Keys.LocalMasterSalt = clientWriteKey[keyLen:] - c.Keys.RemoteMasterKey = serverWriteKey[0:keyLen] - c.Keys.RemoteMasterSalt = serverWriteKey[keyLen:] - return nil - } - - c.Keys.LocalMasterKey = serverWriteKey[0:keyLen] - c.Keys.LocalMasterSalt = serverWriteKey[keyLen:] - c.Keys.RemoteMasterKey = clientWriteKey[0:keyLen] - c.Keys.RemoteMasterSalt = clientWriteKey[keyLen:] - return nil -} diff --git a/vendor/github.com/pion/srtp/v2/option.go b/vendor/github.com/pion/srtp/v2/option.go deleted file mode 100644 index 7e2618e3..00000000 --- a/vendor/github.com/pion/srtp/v2/option.go +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "github.com/pion/transport/v2/replaydetector" -) - -// ContextOption represents option of Context using the functional options pattern. -type ContextOption func(*Context) error - -// SRTPReplayProtection sets SRTP replay protection window size. -func SRTPReplayProtection(windowSize uint) ContextOption { // nolint:revive - return func(c *Context) error { - c.newSRTPReplayDetector = func() replaydetector.ReplayDetector { - return replaydetector.New(windowSize, maxROC<<16|maxSequenceNumber) - } - return nil - } -} - -// SRTCPReplayProtection sets SRTCP replay protection window size. -func SRTCPReplayProtection(windowSize uint) ContextOption { - return func(c *Context) error { - c.newSRTCPReplayDetector = func() replaydetector.ReplayDetector { - return replaydetector.New(windowSize, maxSRTCPIndex) - } - return nil - } -} - -// SRTPNoReplayProtection disables SRTP replay protection. -func SRTPNoReplayProtection() ContextOption { // nolint:revive - return func(c *Context) error { - c.newSRTPReplayDetector = func() replaydetector.ReplayDetector { - return &nopReplayDetector{} - } - return nil - } -} - -// SRTCPNoReplayProtection disables SRTCP replay protection. -func SRTCPNoReplayProtection() ContextOption { - return func(c *Context) error { - c.newSRTCPReplayDetector = func() replaydetector.ReplayDetector { - return &nopReplayDetector{} - } - return nil - } -} - -type nopReplayDetector struct{} - -func (s *nopReplayDetector) Check(uint64) (func(), bool) { - return func() {}, true -} diff --git a/vendor/github.com/pion/srtp/v2/protection_profile.go b/vendor/github.com/pion/srtp/v2/protection_profile.go deleted file mode 100644 index c9b0fce3..00000000 --- a/vendor/github.com/pion/srtp/v2/protection_profile.go +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import "fmt" - -// ProtectionProfile specifies Cipher and AuthTag details, similar to TLS cipher suite -type ProtectionProfile uint16 - -// Supported protection profiles -// See https://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml -const ( - ProtectionProfileAes128CmHmacSha1_80 ProtectionProfile = 0x0001 - ProtectionProfileAes128CmHmacSha1_32 ProtectionProfile = 0x0002 - ProtectionProfileAeadAes128Gcm ProtectionProfile = 0x0007 - ProtectionProfileAeadAes256Gcm ProtectionProfile = 0x0008 -) - -func (p ProtectionProfile) keyLen() (int, error) { - switch p { - case ProtectionProfileAes128CmHmacSha1_32, ProtectionProfileAes128CmHmacSha1_80, ProtectionProfileAeadAes128Gcm: - return 16, nil - case ProtectionProfileAeadAes256Gcm: - return 32, nil - default: - return 0, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, p) - } -} - -func (p ProtectionProfile) saltLen() (int, error) { - switch p { - case ProtectionProfileAes128CmHmacSha1_32, ProtectionProfileAes128CmHmacSha1_80: - return 14, nil - case ProtectionProfileAeadAes128Gcm, ProtectionProfileAeadAes256Gcm: - return 12, nil - default: - return 0, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, p) - } -} - -func (p ProtectionProfile) rtpAuthTagLen() (int, error) { - switch p { - case ProtectionProfileAes128CmHmacSha1_80: - return 10, nil - case ProtectionProfileAes128CmHmacSha1_32: - return 4, nil - case ProtectionProfileAeadAes128Gcm, ProtectionProfileAeadAes256Gcm: - return 0, nil - default: - return 0, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, p) - } -} - -func (p ProtectionProfile) rtcpAuthTagLen() (int, error) { - switch p { - case ProtectionProfileAes128CmHmacSha1_32, ProtectionProfileAes128CmHmacSha1_80: - return 10, nil - case ProtectionProfileAeadAes128Gcm, ProtectionProfileAeadAes256Gcm: - return 0, nil - default: - return 0, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, p) - } -} - -func (p ProtectionProfile) aeadAuthTagLen() (int, error) { - switch p { - case ProtectionProfileAes128CmHmacSha1_32, ProtectionProfileAes128CmHmacSha1_80: - return 0, nil - case ProtectionProfileAeadAes128Gcm, ProtectionProfileAeadAes256Gcm: - return 16, nil - default: - return 0, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, p) - } -} - -func (p ProtectionProfile) authKeyLen() (int, error) { - switch p { - case ProtectionProfileAes128CmHmacSha1_32, ProtectionProfileAes128CmHmacSha1_80: - return 20, nil - case ProtectionProfileAeadAes128Gcm, ProtectionProfileAeadAes256Gcm: - return 0, nil - default: - return 0, fmt.Errorf("%w: %#v", errNoSuchSRTPProfile, p) - } -} diff --git a/vendor/github.com/pion/srtp/v2/renovate.json b/vendor/github.com/pion/srtp/v2/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/srtp/v2/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/srtp/v2/session.go b/vendor/github.com/pion/srtp/v2/session.go deleted file mode 100644 index 2e1f4fe3..00000000 --- a/vendor/github.com/pion/srtp/v2/session.go +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "errors" - "io" - "net" - "sync" - "time" - - "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" -) - -type streamSession interface { - Close() error - write([]byte) (int, error) - decrypt([]byte) error -} - -type session struct { - localContextMutex sync.Mutex - localContext, remoteContext *Context - localOptions, remoteOptions []ContextOption - - newStream chan readStream - acceptStreamTimeout time.Time - - started chan interface{} - closed chan interface{} - - readStreamsClosed bool - readStreams map[uint32]readStream - readStreamsLock sync.Mutex - - log logging.LeveledLogger - bufferFactory func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser - - nextConn net.Conn -} - -// Config is used to configure a session. -// You can provide either a KeyingMaterialExporter to export keys -// or directly pass the keys themselves. -// After a Config is passed to a session it must not be modified. -type Config struct { - Keys SessionKeys - Profile ProtectionProfile - BufferFactory func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser - LoggerFactory logging.LoggerFactory - AcceptStreamTimeout time.Time - - // List of local/remote context options. - // ReplayProtection is enabled on remote context by default. - // Default replay protection window size is 64. - LocalOptions, RemoteOptions []ContextOption -} - -// SessionKeys bundles the keys required to setup an SRTP session -type SessionKeys struct { - LocalMasterKey []byte - LocalMasterSalt []byte - RemoteMasterKey []byte - RemoteMasterSalt []byte -} - -func (s *session) getOrCreateReadStream(ssrc uint32, child streamSession, proto func() readStream) (readStream, bool) { - s.readStreamsLock.Lock() - defer s.readStreamsLock.Unlock() - - if s.readStreamsClosed { - return nil, false - } - - r, ok := s.readStreams[ssrc] - if ok { - return r, false - } - - // Create the readStream. - r = proto() - - if err := r.init(child, ssrc); err != nil { - return nil, false - } - - s.readStreams[ssrc] = r - return r, true -} - -func (s *session) removeReadStream(ssrc uint32) { - s.readStreamsLock.Lock() - defer s.readStreamsLock.Unlock() - - if s.readStreamsClosed { - return - } - - delete(s.readStreams, ssrc) -} - -func (s *session) close() error { - if s.nextConn == nil { - return nil - } else if err := s.nextConn.Close(); err != nil { - return err - } - - <-s.closed - return nil -} - -func (s *session) start(localMasterKey, localMasterSalt, remoteMasterKey, remoteMasterSalt []byte, profile ProtectionProfile, child streamSession) error { - var err error - s.localContext, err = CreateContext(localMasterKey, localMasterSalt, profile, s.localOptions...) - if err != nil { - return err - } - - s.remoteContext, err = CreateContext(remoteMasterKey, remoteMasterSalt, profile, s.remoteOptions...) - if err != nil { - return err - } - - if err = s.nextConn.SetReadDeadline(s.acceptStreamTimeout); err != nil { - return err - } - - go func() { - defer func() { - close(s.newStream) - - s.readStreamsLock.Lock() - s.readStreamsClosed = true - s.readStreamsLock.Unlock() - close(s.closed) - }() - - b := make([]byte, 8192) - for { - var i int - i, err = s.nextConn.Read(b) - if err != nil { - if !errors.Is(err, io.EOF) { - s.log.Error(err.Error()) - } - return - } - - if err = child.decrypt(b[:i]); err != nil { - s.log.Info(err.Error()) - } - } - }() - - close(s.started) - - return nil -} diff --git a/vendor/github.com/pion/srtp/v2/session_srtcp.go b/vendor/github.com/pion/srtp/v2/session_srtcp.go deleted file mode 100644 index 13f1a958..00000000 --- a/vendor/github.com/pion/srtp/v2/session_srtcp.go +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "net" - "time" - - "github.com/pion/logging" - "github.com/pion/rtcp" -) - -const defaultSessionSRTCPReplayProtectionWindow = 64 - -// SessionSRTCP implements io.ReadWriteCloser and provides a bi-directional SRTCP session -// SRTCP itself does not have a design like this, but it is common in most applications -// for local/remote to each have their own keying material. This provides those patterns -// instead of making everyone re-implement -type SessionSRTCP struct { - session - writeStream *WriteStreamSRTCP -} - -// NewSessionSRTCP creates a SRTCP session using conn as the underlying transport. -func NewSessionSRTCP(conn net.Conn, config *Config) (*SessionSRTCP, error) { //nolint:dupl - if config == nil { - return nil, errNoConfig - } else if conn == nil { - return nil, errNoConn - } - - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - localOpts := append( - []ContextOption{}, - config.LocalOptions..., - ) - remoteOpts := append( - []ContextOption{ - // Default options - SRTCPReplayProtection(defaultSessionSRTCPReplayProtectionWindow), - }, - config.RemoteOptions..., - ) - - s := &SessionSRTCP{ - session: session{ - nextConn: conn, - localOptions: localOpts, - remoteOptions: remoteOpts, - readStreams: map[uint32]readStream{}, - newStream: make(chan readStream), - acceptStreamTimeout: config.AcceptStreamTimeout, - started: make(chan interface{}), - closed: make(chan interface{}), - bufferFactory: config.BufferFactory, - log: loggerFactory.NewLogger("srtp"), - }, - } - s.writeStream = &WriteStreamSRTCP{s} - - err := s.session.start( - config.Keys.LocalMasterKey, config.Keys.LocalMasterSalt, - config.Keys.RemoteMasterKey, config.Keys.RemoteMasterSalt, - config.Profile, - s, - ) - if err != nil { - return nil, err - } - return s, nil -} - -// OpenWriteStream returns the global write stream for the Session -func (s *SessionSRTCP) OpenWriteStream() (*WriteStreamSRTCP, error) { - return s.writeStream, nil -} - -// OpenReadStream opens a read stream for the given SSRC, it can be used -// if you want a certain SSRC, but don't want to wait for AcceptStream -func (s *SessionSRTCP) OpenReadStream(ssrc uint32) (*ReadStreamSRTCP, error) { - r, _ := s.session.getOrCreateReadStream(ssrc, s, newReadStreamSRTCP) - - if readStream, ok := r.(*ReadStreamSRTCP); ok { - return readStream, nil - } - return nil, errFailedTypeAssertion -} - -// AcceptStream returns a stream to handle RTCP for a single SSRC -func (s *SessionSRTCP) AcceptStream() (*ReadStreamSRTCP, uint32, error) { - stream, ok := <-s.newStream - if !ok { - return nil, 0, errStreamAlreadyClosed - } - - readStream, ok := stream.(*ReadStreamSRTCP) - if !ok { - return nil, 0, errFailedTypeAssertion - } - - return readStream, stream.GetSSRC(), nil -} - -// Close ends the session -func (s *SessionSRTCP) Close() error { - return s.session.close() -} - -// Private - -func (s *SessionSRTCP) write(buf []byte) (int, error) { - if _, ok := <-s.session.started; ok { - return 0, errStartedChannelUsedIncorrectly - } - - ibuf := bufferpool.Get() - defer bufferpool.Put(ibuf) - - s.session.localContextMutex.Lock() - encrypted, err := s.localContext.EncryptRTCP(ibuf.([]byte), buf, nil) - s.session.localContextMutex.Unlock() - - if err != nil { - return 0, err - } - return s.session.nextConn.Write(encrypted) -} - -func (s *SessionSRTCP) setWriteDeadline(t time.Time) error { - return s.session.nextConn.SetWriteDeadline(t) -} - -// create a list of Destination SSRCs -// that's a superset of all Destinations in the slice. -func destinationSSRC(pkts []rtcp.Packet) []uint32 { - ssrcSet := make(map[uint32]struct{}) - for _, p := range pkts { - for _, ssrc := range p.DestinationSSRC() { - ssrcSet[ssrc] = struct{}{} - } - } - - out := make([]uint32, 0, len(ssrcSet)) - for ssrc := range ssrcSet { - out = append(out, ssrc) - } - - return out -} - -func (s *SessionSRTCP) decrypt(buf []byte) error { - decrypted, err := s.remoteContext.DecryptRTCP(buf, buf, nil) - if err != nil { - return err - } - - pkt, err := rtcp.Unmarshal(decrypted) - if err != nil { - return err - } - - for _, ssrc := range destinationSSRC(pkt) { - r, isNew := s.session.getOrCreateReadStream(ssrc, s, newReadStreamSRTCP) - if r == nil { - return nil // Session has been closed - } else if isNew { - if !s.session.acceptStreamTimeout.IsZero() { - _ = s.session.nextConn.SetReadDeadline(time.Time{}) - } - s.session.newStream <- r // Notify AcceptStream - } - - readStream, ok := r.(*ReadStreamSRTCP) - if !ok { - return errFailedTypeAssertion - } - - _, err = readStream.write(decrypted) - if err != nil { - return err - } - } - - return nil -} diff --git a/vendor/github.com/pion/srtp/v2/session_srtp.go b/vendor/github.com/pion/srtp/v2/session_srtp.go deleted file mode 100644 index e07cbe21..00000000 --- a/vendor/github.com/pion/srtp/v2/session_srtp.go +++ /dev/null @@ -1,200 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "net" - "sync" - "time" - - "github.com/pion/logging" - "github.com/pion/rtp" -) - -const defaultSessionSRTPReplayProtectionWindow = 64 - -// SessionSRTP implements io.ReadWriteCloser and provides a bi-directional SRTP session -// SRTP itself does not have a design like this, but it is common in most applications -// for local/remote to each have their own keying material. This provides those patterns -// instead of making everyone re-implement -type SessionSRTP struct { - session - writeStream *WriteStreamSRTP -} - -// NewSessionSRTP creates a SRTP session using conn as the underlying transport. -func NewSessionSRTP(conn net.Conn, config *Config) (*SessionSRTP, error) { //nolint:dupl - if config == nil { - return nil, errNoConfig - } else if conn == nil { - return nil, errNoConn - } - - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - localOpts := append( - []ContextOption{}, - config.LocalOptions..., - ) - remoteOpts := append( - []ContextOption{ - // Default options - SRTPReplayProtection(defaultSessionSRTPReplayProtectionWindow), - }, - config.RemoteOptions..., - ) - - s := &SessionSRTP{ - session: session{ - nextConn: conn, - localOptions: localOpts, - remoteOptions: remoteOpts, - readStreams: map[uint32]readStream{}, - newStream: make(chan readStream), - acceptStreamTimeout: config.AcceptStreamTimeout, - started: make(chan interface{}), - closed: make(chan interface{}), - bufferFactory: config.BufferFactory, - log: loggerFactory.NewLogger("srtp"), - }, - } - s.writeStream = &WriteStreamSRTP{s} - - err := s.session.start( - config.Keys.LocalMasterKey, config.Keys.LocalMasterSalt, - config.Keys.RemoteMasterKey, config.Keys.RemoteMasterSalt, - config.Profile, - s, - ) - if err != nil { - return nil, err - } - return s, nil -} - -// OpenWriteStream returns the global write stream for the Session -func (s *SessionSRTP) OpenWriteStream() (*WriteStreamSRTP, error) { - return s.writeStream, nil -} - -// OpenReadStream opens a read stream for the given SSRC, it can be used -// if you want a certain SSRC, but don't want to wait for AcceptStream -func (s *SessionSRTP) OpenReadStream(ssrc uint32) (*ReadStreamSRTP, error) { - r, _ := s.session.getOrCreateReadStream(ssrc, s, newReadStreamSRTP) - - if readStream, ok := r.(*ReadStreamSRTP); ok { - return readStream, nil - } - - return nil, errFailedTypeAssertion -} - -// AcceptStream returns a stream to handle RTCP for a single SSRC -func (s *SessionSRTP) AcceptStream() (*ReadStreamSRTP, uint32, error) { - stream, ok := <-s.newStream - if !ok { - return nil, 0, errStreamAlreadyClosed - } - - readStream, ok := stream.(*ReadStreamSRTP) - if !ok { - return nil, 0, errFailedTypeAssertion - } - - return readStream, stream.GetSSRC(), nil -} - -// Close ends the session -func (s *SessionSRTP) Close() error { - return s.session.close() -} - -func (s *SessionSRTP) write(b []byte) (int, error) { - packet := &rtp.Packet{} - - if err := packet.Unmarshal(b); err != nil { - return 0, err - } - - return s.writeRTP(&packet.Header, packet.Payload) -} - -// bufferpool is a global pool of buffers used for encrypted packets in -// writeRTP below. Since it's global, buffers can be shared between -// different sessions, which amortizes the cost of allocating the pool. -// -// 1472 is the maximum Ethernet UDP payload. We give ourselves 20 bytes -// of slack for any authentication tags, which is more than enough for -// either CTR or GCM. If the buffer is too small, no harm, it will just -// get expanded by growBuffer. -var bufferpool = sync.Pool{ // nolint:gochecknoglobals - New: func() interface{} { - return make([]byte, 1492) - }, -} - -func (s *SessionSRTP) writeRTP(header *rtp.Header, payload []byte) (int, error) { - if _, ok := <-s.session.started; ok { - return 0, errStartedChannelUsedIncorrectly - } - - // encryptRTP will either return our buffer, or, if it is too - // small, allocate a new buffer itself. In either case, it is - // safe to put the buffer back into the pool, but only after - // nextConn.Write has returned. - ibuf := bufferpool.Get() - defer bufferpool.Put(ibuf) - - s.session.localContextMutex.Lock() - encrypted, err := s.localContext.encryptRTP(ibuf.([]byte), header, payload) - s.session.localContextMutex.Unlock() - - if err != nil { - return 0, err - } - - return s.session.nextConn.Write(encrypted) -} - -func (s *SessionSRTP) setWriteDeadline(t time.Time) error { - return s.session.nextConn.SetWriteDeadline(t) -} - -func (s *SessionSRTP) decrypt(buf []byte) error { - h := &rtp.Header{} - headerLen, err := h.Unmarshal(buf) - if err != nil { - return err - } - - r, isNew := s.session.getOrCreateReadStream(h.SSRC, s, newReadStreamSRTP) - if r == nil { - return nil // Session has been closed - } else if isNew { - if !s.session.acceptStreamTimeout.IsZero() { - _ = s.session.nextConn.SetReadDeadline(time.Time{}) - } - s.session.newStream <- r // Notify AcceptStream - } - - readStream, ok := r.(*ReadStreamSRTP) - if !ok { - return errFailedTypeAssertion - } - - decrypted, err := s.remoteContext.decryptRTP(buf, buf, h, headerLen) - if err != nil { - return err - } - - _, err = readStream.write(decrypted) - if err != nil { - return err - } - - return nil -} diff --git a/vendor/github.com/pion/srtp/v2/srtcp.go b/vendor/github.com/pion/srtp/v2/srtcp.go deleted file mode 100644 index 7fd0746b..00000000 --- a/vendor/github.com/pion/srtp/v2/srtcp.go +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "encoding/binary" - "fmt" - - "github.com/pion/rtcp" -) - -const maxSRTCPIndex = 0x7FFFFFFF - -func (c *Context) decryptRTCP(dst, encrypted []byte) ([]byte, error) { - out := allocateIfMismatch(dst, encrypted) - - authTagLen, err := c.cipher.rtcpAuthTagLen() - if err != nil { - return nil, err - } - aeadAuthTagLen, err := c.cipher.aeadAuthTagLen() - if err != nil { - return nil, err - } - tailOffset := len(encrypted) - (authTagLen + srtcpIndexSize) - - if tailOffset < aeadAuthTagLen { - return nil, fmt.Errorf("%w: %d", errTooShortRTCP, len(encrypted)) - } else if isEncrypted := encrypted[tailOffset] >> 7; isEncrypted == 0 { - return out, nil - } - - index := c.cipher.getRTCPIndex(encrypted) - ssrc := binary.BigEndian.Uint32(encrypted[4:]) - - s := c.getSRTCPSSRCState(ssrc) - markAsValid, ok := s.replayDetector.Check(uint64(index)) - if !ok { - return nil, &duplicatedError{Proto: "srtcp", SSRC: ssrc, Index: index} - } - - out, err = c.cipher.decryptRTCP(out, encrypted, index, ssrc) - if err != nil { - return nil, err - } - - markAsValid() - return out, nil -} - -// DecryptRTCP decrypts a buffer that contains a RTCP packet -func (c *Context) DecryptRTCP(dst, encrypted []byte, header *rtcp.Header) ([]byte, error) { - if header == nil { - header = &rtcp.Header{} - } - - if err := header.Unmarshal(encrypted); err != nil { - return nil, err - } - - return c.decryptRTCP(dst, encrypted) -} - -func (c *Context) encryptRTCP(dst, decrypted []byte) ([]byte, error) { - ssrc := binary.BigEndian.Uint32(decrypted[4:]) - s := c.getSRTCPSSRCState(ssrc) - - if s.srtcpIndex >= maxSRTCPIndex { - // ... when 2^48 SRTP packets or 2^31 SRTCP packets have been secured with the same key - // (whichever occurs before), the key management MUST be called to provide new master key(s) - // (previously stored and used keys MUST NOT be used again), or the session MUST be terminated. - // https://www.rfc-editor.org/rfc/rfc3711#section-9.2 - return nil, errExceededMaxPackets - } - - // We roll over early because MSB is used for marking as encrypted - s.srtcpIndex++ - - return c.cipher.encryptRTCP(dst, decrypted, s.srtcpIndex, ssrc) -} - -// EncryptRTCP Encrypts a RTCP packet -func (c *Context) EncryptRTCP(dst, decrypted []byte, header *rtcp.Header) ([]byte, error) { - if header == nil { - header = &rtcp.Header{} - } - - if err := header.Unmarshal(decrypted); err != nil { - return nil, err - } - - return c.encryptRTCP(dst, decrypted) -} diff --git a/vendor/github.com/pion/srtp/v2/srtp.go b/vendor/github.com/pion/srtp/v2/srtp.go deleted file mode 100644 index 42c71be0..00000000 --- a/vendor/github.com/pion/srtp/v2/srtp.go +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package srtp implements Secure Real-time Transport Protocol -package srtp - -import ( - "github.com/pion/rtp" -) - -func (c *Context) decryptRTP(dst, ciphertext []byte, header *rtp.Header, headerLen int) ([]byte, error) { - s := c.getSRTPSSRCState(header.SSRC) - - roc, diff, _ := s.nextRolloverCount(header.SequenceNumber) - markAsValid, ok := s.replayDetector.Check( - (uint64(roc) << 16) | uint64(header.SequenceNumber), - ) - if !ok { - return nil, &duplicatedError{ - Proto: "srtp", SSRC: header.SSRC, Index: uint32(header.SequenceNumber), - } - } - - authTagLen, err := c.cipher.rtpAuthTagLen() - if err != nil { - return nil, err - } - dst = growBufferSize(dst, len(ciphertext)-authTagLen) - - dst, err = c.cipher.decryptRTP(dst, ciphertext, header, headerLen, roc) - if err != nil { - return nil, err - } - - markAsValid() - s.updateRolloverCount(header.SequenceNumber, diff) - return dst, nil -} - -// DecryptRTP decrypts a RTP packet with an encrypted payload -func (c *Context) DecryptRTP(dst, encrypted []byte, header *rtp.Header) ([]byte, error) { - if header == nil { - header = &rtp.Header{} - } - - headerLen, err := header.Unmarshal(encrypted) - if err != nil { - return nil, err - } - - return c.decryptRTP(dst, encrypted, header, headerLen) -} - -// EncryptRTP marshals and encrypts an RTP packet, writing to the dst buffer provided. -// If the dst buffer does not have the capacity to hold `len(plaintext) + 10` bytes, a new one will be allocated and returned. -// If a rtp.Header is provided, it will be Unmarshaled using the plaintext. -func (c *Context) EncryptRTP(dst []byte, plaintext []byte, header *rtp.Header) ([]byte, error) { - if header == nil { - header = &rtp.Header{} - } - - headerLen, err := header.Unmarshal(plaintext) - if err != nil { - return nil, err - } - - return c.encryptRTP(dst, header, plaintext[headerLen:]) -} - -// encryptRTP marshals and encrypts an RTP packet, writing to the dst buffer provided. -// If the dst buffer does not have the capacity, a new one will be allocated and returned. -// Similar to above but faster because it can avoid unmarshaling the header and marshaling the payload. -func (c *Context) encryptRTP(dst []byte, header *rtp.Header, payload []byte) (ciphertext []byte, err error) { - s := c.getSRTPSSRCState(header.SSRC) - roc, diff, ovf := s.nextRolloverCount(header.SequenceNumber) - if ovf { - // ... when 2^48 SRTP packets or 2^31 SRTCP packets have been secured with the same key - // (whichever occurs before), the key management MUST be called to provide new master key(s) - // (previously stored and used keys MUST NOT be used again), or the session MUST be terminated. - // https://www.rfc-editor.org/rfc/rfc3711#section-9.2 - return nil, errExceededMaxPackets - } - s.updateRolloverCount(header.SequenceNumber, diff) - - return c.cipher.encryptRTP(dst, header, payload, roc) -} diff --git a/vendor/github.com/pion/srtp/v2/srtp_cipher.go b/vendor/github.com/pion/srtp/v2/srtp_cipher.go deleted file mode 100644 index db501472..00000000 --- a/vendor/github.com/pion/srtp/v2/srtp_cipher.go +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import "github.com/pion/rtp" - -// cipher represents a implementation of one -// of the SRTP Specific ciphers -type srtpCipher interface { - // authTagLen returns auth key length of the cipher. - // See the note below. - rtpAuthTagLen() (int, error) - rtcpAuthTagLen() (int, error) - // aeadAuthTagLen returns AEAD auth key length of the cipher. - // See the note below. - aeadAuthTagLen() (int, error) - getRTCPIndex([]byte) uint32 - - encryptRTP([]byte, *rtp.Header, []byte, uint32) ([]byte, error) - encryptRTCP([]byte, []byte, uint32, uint32) ([]byte, error) - - decryptRTP([]byte, []byte, *rtp.Header, int, uint32) ([]byte, error) - decryptRTCP([]byte, []byte, uint32, uint32) ([]byte, error) -} - -/* -NOTE: Auth tag and AEAD auth tag are placed at the different position in SRTCP - -In non-AEAD cipher, the authentication tag is placed *after* the ESRTCP word -(Encrypted-flag and SRTCP index). - -> AES_128_CM_HMAC_SHA1_80 -> | RTCP Header | Encrypted payload |E| SRTCP Index | Auth tag | -> ^ |----------| -> | ^ -> | authTagLen=10 -> aeadAuthTagLen=0 - -In AEAD cipher, the AEAD authentication tag is embedded in the ciphertext. -It is *before* the ESRTCP word (Encrypted-flag and SRTCP index). - -> AEAD_AES_128_GCM -> | RTCP Header | Encrypted payload | AEAD auth tag |E| SRTCP Index | -> |---------------| ^ -> ^ authTagLen=0 -> aeadAuthTagLen=16 - -See https://tools.ietf.org/html/rfc7714 for the full specifications. -*/ diff --git a/vendor/github.com/pion/srtp/v2/srtp_cipher_aead_aes_gcm.go b/vendor/github.com/pion/srtp/v2/srtp_cipher_aead_aes_gcm.go deleted file mode 100644 index 90643d92..00000000 --- a/vendor/github.com/pion/srtp/v2/srtp_cipher_aead_aes_gcm.go +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "crypto/aes" - "crypto/cipher" - "encoding/binary" - - "github.com/pion/rtp" -) - -const ( - rtcpEncryptionFlag = 0x80 -) - -type srtpCipherAeadAesGcm struct { - ProtectionProfile - - srtpCipher, srtcpCipher cipher.AEAD - - srtpSessionSalt, srtcpSessionSalt []byte -} - -func newSrtpCipherAeadAesGcm(profile ProtectionProfile, masterKey, masterSalt []byte) (*srtpCipherAeadAesGcm, error) { - s := &srtpCipherAeadAesGcm{ProtectionProfile: profile} - - srtpSessionKey, err := aesCmKeyDerivation(labelSRTPEncryption, masterKey, masterSalt, 0, len(masterKey)) - if err != nil { - return nil, err - } - - srtpBlock, err := aes.NewCipher(srtpSessionKey) - if err != nil { - return nil, err - } - - s.srtpCipher, err = cipher.NewGCM(srtpBlock) - if err != nil { - return nil, err - } - - srtcpSessionKey, err := aesCmKeyDerivation(labelSRTCPEncryption, masterKey, masterSalt, 0, len(masterKey)) - if err != nil { - return nil, err - } - - srtcpBlock, err := aes.NewCipher(srtcpSessionKey) - if err != nil { - return nil, err - } - - s.srtcpCipher, err = cipher.NewGCM(srtcpBlock) - if err != nil { - return nil, err - } - - if s.srtpSessionSalt, err = aesCmKeyDerivation(labelSRTPSalt, masterKey, masterSalt, 0, len(masterSalt)); err != nil { - return nil, err - } else if s.srtcpSessionSalt, err = aesCmKeyDerivation(labelSRTCPSalt, masterKey, masterSalt, 0, len(masterSalt)); err != nil { - return nil, err - } - - return s, nil -} - -func (s *srtpCipherAeadAesGcm) encryptRTP(dst []byte, header *rtp.Header, payload []byte, roc uint32) (ciphertext []byte, err error) { - // Grow the given buffer to fit the output. - authTagLen, err := s.aeadAuthTagLen() - if err != nil { - return nil, err - } - dst = growBufferSize(dst, header.MarshalSize()+len(payload)+authTagLen) - - n, err := header.MarshalTo(dst) - if err != nil { - return nil, err - } - - iv := s.rtpInitializationVector(header, roc) - s.srtpCipher.Seal(dst[n:n], iv[:], payload, dst[:n]) - return dst, nil -} - -func (s *srtpCipherAeadAesGcm) decryptRTP(dst, ciphertext []byte, header *rtp.Header, headerLen int, roc uint32) ([]byte, error) { - // Grow the given buffer to fit the output. - authTagLen, err := s.aeadAuthTagLen() - if err != nil { - return nil, err - } - nDst := len(ciphertext) - authTagLen - if nDst < 0 { - // Size of ciphertext is shorter than AEAD auth tag len. - return nil, errFailedToVerifyAuthTag - } - dst = growBufferSize(dst, nDst) - - iv := s.rtpInitializationVector(header, roc) - - if _, err := s.srtpCipher.Open( - dst[headerLen:headerLen], iv[:], ciphertext[headerLen:], ciphertext[:headerLen], - ); err != nil { - return nil, err - } - - copy(dst[:headerLen], ciphertext[:headerLen]) - return dst, nil -} - -func (s *srtpCipherAeadAesGcm) encryptRTCP(dst, decrypted []byte, srtcpIndex uint32, ssrc uint32) ([]byte, error) { - authTagLen, err := s.aeadAuthTagLen() - if err != nil { - return nil, err - } - aadPos := len(decrypted) + authTagLen - // Grow the given buffer to fit the output. - dst = growBufferSize(dst, aadPos+srtcpIndexSize) - - iv := s.rtcpInitializationVector(srtcpIndex, ssrc) - aad := s.rtcpAdditionalAuthenticatedData(decrypted, srtcpIndex) - - s.srtcpCipher.Seal(dst[8:8], iv[:], decrypted[8:], aad[:]) - - copy(dst[:8], decrypted[:8]) - copy(dst[aadPos:aadPos+4], aad[8:12]) - return dst, nil -} - -func (s *srtpCipherAeadAesGcm) decryptRTCP(dst, encrypted []byte, srtcpIndex, ssrc uint32) ([]byte, error) { - aadPos := len(encrypted) - srtcpIndexSize - // Grow the given buffer to fit the output. - authTagLen, err := s.aeadAuthTagLen() - if err != nil { - return nil, err - } - nDst := aadPos - authTagLen - if nDst < 0 { - // Size of ciphertext is shorter than AEAD auth tag len. - return nil, errFailedToVerifyAuthTag - } - dst = growBufferSize(dst, nDst) - - iv := s.rtcpInitializationVector(srtcpIndex, ssrc) - aad := s.rtcpAdditionalAuthenticatedData(encrypted, srtcpIndex) - - if _, err := s.srtcpCipher.Open(dst[8:8], iv[:], encrypted[8:aadPos], aad[:]); err != nil { - return nil, err - } - - copy(dst[:8], encrypted[:8]) - return dst, nil -} - -// The 12-octet IV used by AES-GCM SRTP is formed by first concatenating -// 2 octets of zeroes, the 4-octet SSRC, the 4-octet rollover counter -// (ROC), and the 2-octet sequence number (SEQ). The resulting 12-octet -// value is then XORed to the 12-octet salt to form the 12-octet IV. -// -// https://tools.ietf.org/html/rfc7714#section-8.1 -func (s *srtpCipherAeadAesGcm) rtpInitializationVector(header *rtp.Header, roc uint32) [12]byte { - var iv [12]byte - binary.BigEndian.PutUint32(iv[2:], header.SSRC) - binary.BigEndian.PutUint32(iv[6:], roc) - binary.BigEndian.PutUint16(iv[10:], header.SequenceNumber) - - for i := range iv { - iv[i] ^= s.srtpSessionSalt[i] - } - return iv -} - -// The 12-octet IV used by AES-GCM SRTCP is formed by first -// concatenating 2 octets of zeroes, the 4-octet SSRC identifier, -// 2 octets of zeroes, a single "0" bit, and the 31-bit SRTCP index. -// The resulting 12-octet value is then XORed to the 12-octet salt to -// form the 12-octet IV. -// -// https://tools.ietf.org/html/rfc7714#section-9.1 -func (s *srtpCipherAeadAesGcm) rtcpInitializationVector(srtcpIndex uint32, ssrc uint32) [12]byte { - var iv [12]byte - - binary.BigEndian.PutUint32(iv[2:], ssrc) - binary.BigEndian.PutUint32(iv[8:], srtcpIndex) - - for i := range iv { - iv[i] ^= s.srtcpSessionSalt[i] - } - return iv -} - -// In an SRTCP packet, a 1-bit Encryption flag is prepended to the -// 31-bit SRTCP index to form a 32-bit value we shall call the -// "ESRTCP word" -// -// https://tools.ietf.org/html/rfc7714#section-17 -func (s *srtpCipherAeadAesGcm) rtcpAdditionalAuthenticatedData(rtcpPacket []byte, srtcpIndex uint32) [12]byte { - var aad [12]byte - - copy(aad[:], rtcpPacket[:8]) - binary.BigEndian.PutUint32(aad[8:], srtcpIndex) - aad[8] |= rtcpEncryptionFlag - - return aad -} - -func (s *srtpCipherAeadAesGcm) getRTCPIndex(in []byte) uint32 { - return binary.BigEndian.Uint32(in[len(in)-4:]) &^ (rtcpEncryptionFlag << 24) -} diff --git a/vendor/github.com/pion/srtp/v2/srtp_cipher_aes_cm_hmac_sha1.go b/vendor/github.com/pion/srtp/v2/srtp_cipher_aes_cm_hmac_sha1.go deleted file mode 100644 index d56e6afb..00000000 --- a/vendor/github.com/pion/srtp/v2/srtp_cipher_aes_cm_hmac_sha1.go +++ /dev/null @@ -1,250 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( //nolint:gci - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/sha1" //nolint:gosec - "crypto/subtle" - "encoding/binary" - "hash" - - "github.com/pion/rtp" -) - -type srtpCipherAesCmHmacSha1 struct { - ProtectionProfile - - srtpSessionSalt []byte - srtpSessionAuth hash.Hash - srtpBlock cipher.Block - - srtcpSessionSalt []byte - srtcpSessionAuth hash.Hash - srtcpBlock cipher.Block -} - -func newSrtpCipherAesCmHmacSha1(profile ProtectionProfile, masterKey, masterSalt []byte) (*srtpCipherAesCmHmacSha1, error) { - s := &srtpCipherAesCmHmacSha1{ProtectionProfile: profile} - srtpSessionKey, err := aesCmKeyDerivation(labelSRTPEncryption, masterKey, masterSalt, 0, len(masterKey)) - if err != nil { - return nil, err - } else if s.srtpBlock, err = aes.NewCipher(srtpSessionKey); err != nil { - return nil, err - } - - srtcpSessionKey, err := aesCmKeyDerivation(labelSRTCPEncryption, masterKey, masterSalt, 0, len(masterKey)) - if err != nil { - return nil, err - } else if s.srtcpBlock, err = aes.NewCipher(srtcpSessionKey); err != nil { - return nil, err - } - - if s.srtpSessionSalt, err = aesCmKeyDerivation(labelSRTPSalt, masterKey, masterSalt, 0, len(masterSalt)); err != nil { - return nil, err - } else if s.srtcpSessionSalt, err = aesCmKeyDerivation(labelSRTCPSalt, masterKey, masterSalt, 0, len(masterSalt)); err != nil { - return nil, err - } - - authKeyLen, err := profile.authKeyLen() - if err != nil { - return nil, err - } - - srtpSessionAuthTag, err := aesCmKeyDerivation(labelSRTPAuthenticationTag, masterKey, masterSalt, 0, authKeyLen) - if err != nil { - return nil, err - } - - srtcpSessionAuthTag, err := aesCmKeyDerivation(labelSRTCPAuthenticationTag, masterKey, masterSalt, 0, authKeyLen) - if err != nil { - return nil, err - } - - s.srtcpSessionAuth = hmac.New(sha1.New, srtcpSessionAuthTag) - s.srtpSessionAuth = hmac.New(sha1.New, srtpSessionAuthTag) - return s, nil -} - -func (s *srtpCipherAesCmHmacSha1) encryptRTP(dst []byte, header *rtp.Header, payload []byte, roc uint32) (ciphertext []byte, err error) { - // Grow the given buffer to fit the output. - authTagLen, err := s.rtpAuthTagLen() - if err != nil { - return nil, err - } - dst = growBufferSize(dst, header.MarshalSize()+len(payload)+authTagLen) - - // Copy the header unencrypted. - n, err := header.MarshalTo(dst) - if err != nil { - return nil, err - } - - // Encrypt the payload - counter := generateCounter(header.SequenceNumber, roc, header.SSRC, s.srtpSessionSalt) - if err = xorBytesCTR(s.srtpBlock, counter[:], dst[n:], payload); err != nil { - return nil, err - } - n += len(payload) - - // Generate the auth tag. - authTag, err := s.generateSrtpAuthTag(dst[:n], roc) - if err != nil { - return nil, err - } - - // Write the auth tag to the dest. - copy(dst[n:], authTag) - - return dst, nil -} - -func (s *srtpCipherAesCmHmacSha1) decryptRTP(dst, ciphertext []byte, header *rtp.Header, headerLen int, roc uint32) ([]byte, error) { - // Split the auth tag and the cipher text into two parts. - authTagLen, err := s.rtpAuthTagLen() - if err != nil { - return nil, err - } - actualTag := ciphertext[len(ciphertext)-authTagLen:] - ciphertext = ciphertext[:len(ciphertext)-authTagLen] - - // Generate the auth tag we expect to see from the ciphertext. - expectedTag, err := s.generateSrtpAuthTag(ciphertext, roc) - if err != nil { - return nil, err - } - - // See if the auth tag actually matches. - // We use a constant time comparison to prevent timing attacks. - if subtle.ConstantTimeCompare(actualTag, expectedTag) != 1 { - return nil, errFailedToVerifyAuthTag - } - - // Write the plaintext header to the destination buffer. - copy(dst, ciphertext[:headerLen]) - - // Decrypt the ciphertext for the payload. - counter := generateCounter(header.SequenceNumber, roc, header.SSRC, s.srtpSessionSalt) - err = xorBytesCTR( - s.srtpBlock, counter[:], dst[headerLen:], ciphertext[headerLen:], - ) - return dst, err -} - -func (s *srtpCipherAesCmHmacSha1) encryptRTCP(dst, decrypted []byte, srtcpIndex uint32, ssrc uint32) ([]byte, error) { - dst = allocateIfMismatch(dst, decrypted) - - // Encrypt everything after header - counter := generateCounter(uint16(srtcpIndex&0xffff), srtcpIndex>>16, ssrc, s.srtcpSessionSalt) - if err := xorBytesCTR(s.srtcpBlock, counter[:], dst[8:], dst[8:]); err != nil { - return nil, err - } - - // Add SRTCP Index and set Encryption bit - dst = append(dst, make([]byte, 4)...) - binary.BigEndian.PutUint32(dst[len(dst)-4:], srtcpIndex) - dst[len(dst)-4] |= 0x80 - - authTag, err := s.generateSrtcpAuthTag(dst) - if err != nil { - return nil, err - } - return append(dst, authTag...), nil -} - -func (s *srtpCipherAesCmHmacSha1) decryptRTCP(out, encrypted []byte, index, ssrc uint32) ([]byte, error) { - authTagLen, err := s.rtcpAuthTagLen() - if err != nil { - return nil, err - } - tailOffset := len(encrypted) - (authTagLen + srtcpIndexSize) - out = out[0:tailOffset] - - expectedTag, err := s.generateSrtcpAuthTag(encrypted[:len(encrypted)-authTagLen]) - if err != nil { - return nil, err - } - - actualTag := encrypted[len(encrypted)-authTagLen:] - if subtle.ConstantTimeCompare(actualTag, expectedTag) != 1 { - return nil, errFailedToVerifyAuthTag - } - - counter := generateCounter(uint16(index&0xffff), index>>16, ssrc, s.srtcpSessionSalt) - err = xorBytesCTR(s.srtcpBlock, counter[:], out[8:], out[8:]) - - return out, err -} - -func (s *srtpCipherAesCmHmacSha1) generateSrtpAuthTag(buf []byte, roc uint32) ([]byte, error) { - // https://tools.ietf.org/html/rfc3711#section-4.2 - // In the case of SRTP, M SHALL consist of the Authenticated - // Portion of the packet (as specified in Figure 1) concatenated with - // the ROC, M = Authenticated Portion || ROC; - // - // The pre-defined authentication transform for SRTP is HMAC-SHA1 - // [RFC2104]. With HMAC-SHA1, the SRTP_PREFIX_LENGTH (Figure 3) SHALL - // be 0. For SRTP (respectively SRTCP), the HMAC SHALL be applied to - // the session authentication key and M as specified above, i.e., - // HMAC(k_a, M). The HMAC output SHALL then be truncated to the n_tag - // left-most bits. - // - Authenticated portion of the packet is everything BEFORE MKI - // - k_a is the session message authentication key - // - n_tag is the bit-length of the output authentication tag - s.srtpSessionAuth.Reset() - - if _, err := s.srtpSessionAuth.Write(buf); err != nil { - return nil, err - } - - // For SRTP only, we need to hash the rollover counter as well. - rocRaw := [4]byte{} - binary.BigEndian.PutUint32(rocRaw[:], roc) - - _, err := s.srtpSessionAuth.Write(rocRaw[:]) - if err != nil { - return nil, err - } - - // Truncate the hash to the size indicated by the profile - authTagLen, err := s.rtpAuthTagLen() - if err != nil { - return nil, err - } - return s.srtpSessionAuth.Sum(nil)[0:authTagLen], nil -} - -func (s *srtpCipherAesCmHmacSha1) generateSrtcpAuthTag(buf []byte) ([]byte, error) { - // https://tools.ietf.org/html/rfc3711#section-4.2 - // - // The pre-defined authentication transform for SRTP is HMAC-SHA1 - // [RFC2104]. With HMAC-SHA1, the SRTP_PREFIX_LENGTH (Figure 3) SHALL - // be 0. For SRTP (respectively SRTCP), the HMAC SHALL be applied to - // the session authentication key and M as specified above, i.e., - // HMAC(k_a, M). The HMAC output SHALL then be truncated to the n_tag - // left-most bits. - // - Authenticated portion of the packet is everything BEFORE MKI - // - k_a is the session message authentication key - // - n_tag is the bit-length of the output authentication tag - s.srtcpSessionAuth.Reset() - - if _, err := s.srtcpSessionAuth.Write(buf); err != nil { - return nil, err - } - authTagLen, err := s.rtcpAuthTagLen() - if err != nil { - return nil, err - } - - return s.srtcpSessionAuth.Sum(nil)[0:authTagLen], nil -} - -func (s *srtpCipherAesCmHmacSha1) getRTCPIndex(in []byte) uint32 { - authTagLen, _ := s.rtcpAuthTagLen() - tailOffset := len(in) - (authTagLen + srtcpIndexSize) - srtcpIndexBuffer := in[tailOffset : tailOffset+srtcpIndexSize] - return binary.BigEndian.Uint32(srtcpIndexBuffer) &^ (1 << 31) -} diff --git a/vendor/github.com/pion/srtp/v2/stream.go b/vendor/github.com/pion/srtp/v2/stream.go deleted file mode 100644 index 5f9c58a7..00000000 --- a/vendor/github.com/pion/srtp/v2/stream.go +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -type readStream interface { - init(child streamSession, ssrc uint32) error - - Read(buf []byte) (int, error) - GetSSRC() uint32 -} diff --git a/vendor/github.com/pion/srtp/v2/stream_srtcp.go b/vendor/github.com/pion/srtp/v2/stream_srtcp.go deleted file mode 100644 index 08d36dca..00000000 --- a/vendor/github.com/pion/srtp/v2/stream_srtcp.go +++ /dev/null @@ -1,160 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "errors" - "io" - "sync" - "time" - - "github.com/pion/rtcp" - "github.com/pion/transport/v2/packetio" -) - -// Limit the buffer size to 100KB -const srtcpBufferSize = 100 * 1000 - -// ReadStreamSRTCP handles decryption for a single RTCP SSRC -type ReadStreamSRTCP struct { - mu sync.Mutex - - isClosed chan bool - - session *SessionSRTCP - ssrc uint32 - isInited bool - - buffer io.ReadWriteCloser -} - -func (r *ReadStreamSRTCP) write(buf []byte) (n int, err error) { - n, err = r.buffer.Write(buf) - - if errors.Is(err, packetio.ErrFull) { - // Silently drop data when the buffer is full. - return len(buf), nil - } - - return n, err -} - -// Used by getOrCreateReadStream -func newReadStreamSRTCP() readStream { - return &ReadStreamSRTCP{} -} - -// ReadRTCP reads and decrypts full RTCP packet and its header from the nextConn -func (r *ReadStreamSRTCP) ReadRTCP(buf []byte) (int, *rtcp.Header, error) { - n, err := r.Read(buf) - if err != nil { - return 0, nil, err - } - - header := &rtcp.Header{} - err = header.Unmarshal(buf[:n]) - if err != nil { - return 0, nil, err - } - - return n, header, nil -} - -// Read reads and decrypts full RTCP packet from the nextConn -func (r *ReadStreamSRTCP) Read(buf []byte) (int, error) { - return r.buffer.Read(buf) -} - -// SetReadDeadline sets the deadline for the Read operation. -// Setting to zero means no deadline. -func (r *ReadStreamSRTCP) SetReadDeadline(t time.Time) error { - if b, ok := r.buffer.(interface { - SetReadDeadline(time.Time) error - }); ok { - return b.SetReadDeadline(t) - } - return nil -} - -// Close removes the ReadStream from the session and cleans up any associated state -func (r *ReadStreamSRTCP) Close() error { - r.mu.Lock() - defer r.mu.Unlock() - - if !r.isInited { - return errStreamNotInited - } - - select { - case <-r.isClosed: - return errStreamAlreadyClosed - default: - err := r.buffer.Close() - if err != nil { - return err - } - - r.session.removeReadStream(r.ssrc) - return nil - } -} - -func (r *ReadStreamSRTCP) init(child streamSession, ssrc uint32) error { - sessionSRTCP, ok := child.(*SessionSRTCP) - - r.mu.Lock() - defer r.mu.Unlock() - if !ok { - return errFailedTypeAssertion - } else if r.isInited { - return errStreamAlreadyInited - } - - r.session = sessionSRTCP - r.ssrc = ssrc - r.isInited = true - r.isClosed = make(chan bool) - - if r.session.bufferFactory != nil { - r.buffer = r.session.bufferFactory(packetio.RTCPBufferPacket, ssrc) - } else { - // Create a buffer and limit it to 100KB - buff := packetio.NewBuffer() - buff.SetLimitSize(srtcpBufferSize) - r.buffer = buff - } - - return nil -} - -// GetSSRC returns the SSRC we are demuxing for -func (r *ReadStreamSRTCP) GetSSRC() uint32 { - return r.ssrc -} - -// WriteStreamSRTCP is stream for a single Session that is used to encrypt RTCP -type WriteStreamSRTCP struct { - session *SessionSRTCP -} - -// WriteRTCP encrypts a RTCP header and its payload to the nextConn -func (w *WriteStreamSRTCP) WriteRTCP(header *rtcp.Header, payload []byte) (int, error) { - headerRaw, err := header.Marshal() - if err != nil { - return 0, err - } - - return w.session.write(append(headerRaw, payload...)) -} - -// Write encrypts and writes a full RTCP packets to the nextConn -func (w *WriteStreamSRTCP) Write(b []byte) (int, error) { - return w.session.write(b) -} - -// SetWriteDeadline sets the deadline for the Write operation. -// Setting to zero means no deadline. -func (w *WriteStreamSRTCP) SetWriteDeadline(t time.Time) error { - return w.session.setWriteDeadline(t) -} diff --git a/vendor/github.com/pion/srtp/v2/stream_srtp.go b/vendor/github.com/pion/srtp/v2/stream_srtp.go deleted file mode 100644 index 85897008..00000000 --- a/vendor/github.com/pion/srtp/v2/stream_srtp.go +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import ( - "errors" - "io" - "sync" - "time" - - "github.com/pion/rtp" - "github.com/pion/transport/v2/packetio" -) - -// Limit the buffer size to 1MB -const srtpBufferSize = 1000 * 1000 - -// ReadStreamSRTP handles decryption for a single RTP SSRC -type ReadStreamSRTP struct { - mu sync.Mutex - - isClosed chan bool - - session *SessionSRTP - ssrc uint32 - isInited bool - - buffer io.ReadWriteCloser -} - -// Used by getOrCreateReadStream -func newReadStreamSRTP() readStream { - return &ReadStreamSRTP{} -} - -func (r *ReadStreamSRTP) init(child streamSession, ssrc uint32) error { - sessionSRTP, ok := child.(*SessionSRTP) - - r.mu.Lock() - defer r.mu.Unlock() - - if !ok { - return errFailedTypeAssertion - } else if r.isInited { - return errStreamAlreadyInited - } - - r.session = sessionSRTP - r.ssrc = ssrc - r.isInited = true - r.isClosed = make(chan bool) - - // Create a buffer with a 1MB limit - if r.session.bufferFactory != nil { - r.buffer = r.session.bufferFactory(packetio.RTPBufferPacket, ssrc) - } else { - buff := packetio.NewBuffer() - buff.SetLimitSize(srtpBufferSize) - r.buffer = buff - } - - return nil -} - -func (r *ReadStreamSRTP) write(buf []byte) (n int, err error) { - n, err = r.buffer.Write(buf) - - if errors.Is(err, packetio.ErrFull) { - // Silently drop data when the buffer is full. - return len(buf), nil - } - - return n, err -} - -// Read reads and decrypts full RTP packet from the nextConn -func (r *ReadStreamSRTP) Read(buf []byte) (int, error) { - return r.buffer.Read(buf) -} - -// ReadRTP reads and decrypts full RTP packet and its header from the nextConn -func (r *ReadStreamSRTP) ReadRTP(buf []byte) (int, *rtp.Header, error) { - n, err := r.Read(buf) - if err != nil { - return 0, nil, err - } - - header := &rtp.Header{} - - _, err = header.Unmarshal(buf[:n]) - if err != nil { - return 0, nil, err - } - - return n, header, nil -} - -// SetReadDeadline sets the deadline for the Read operation. -// Setting to zero means no deadline. -func (r *ReadStreamSRTP) SetReadDeadline(t time.Time) error { - if b, ok := r.buffer.(interface { - SetReadDeadline(time.Time) error - }); ok { - return b.SetReadDeadline(t) - } - return nil -} - -// Close removes the ReadStream from the session and cleans up any associated state -func (r *ReadStreamSRTP) Close() error { - r.mu.Lock() - defer r.mu.Unlock() - - if !r.isInited { - return errStreamNotInited - } - - select { - case <-r.isClosed: - return errStreamAlreadyClosed - default: - err := r.buffer.Close() - if err != nil { - return err - } - - r.session.removeReadStream(r.ssrc) - return nil - } -} - -// GetSSRC returns the SSRC we are demuxing for -func (r *ReadStreamSRTP) GetSSRC() uint32 { - return r.ssrc -} - -// WriteStreamSRTP is stream for a single Session that is used to encrypt RTP -type WriteStreamSRTP struct { - session *SessionSRTP -} - -// WriteRTP encrypts a RTP packet and writes to the connection -func (w *WriteStreamSRTP) WriteRTP(header *rtp.Header, payload []byte) (int, error) { - return w.session.writeRTP(header, payload) -} - -// Write encrypts and writes a full RTP packets to the nextConn -func (w *WriteStreamSRTP) Write(b []byte) (int, error) { - return w.session.write(b) -} - -// SetWriteDeadline sets the deadline for the Write operation. -// Setting to zero means no deadline. -func (w *WriteStreamSRTP) SetWriteDeadline(t time.Time) error { - return w.session.setWriteDeadline(t) -} diff --git a/vendor/github.com/pion/srtp/v2/util.go b/vendor/github.com/pion/srtp/v2/util.go deleted file mode 100644 index 792175d9..00000000 --- a/vendor/github.com/pion/srtp/v2/util.go +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package srtp - -import "bytes" - -// Grow the buffer size to the given number of bytes. -func growBufferSize(buf []byte, size int) []byte { - if size <= cap(buf) { - return buf[:size] - } - - buf2 := make([]byte, size) - copy(buf2, buf) - return buf2 -} - -// Check if buffers match, if not allocate a new buffer and return it -func allocateIfMismatch(dst, src []byte) []byte { - if dst == nil { - dst = make([]byte, len(src)) - copy(dst, src) - } else if !bytes.Equal(dst, src) { // bytes.Equal returns on ref equality, no optimization needed - extraNeeded := len(src) - len(dst) - if extraNeeded > 0 { - dst = append(dst, make([]byte, extraNeeded)...) - } else if extraNeeded < 0 { - dst = dst[:len(dst)+extraNeeded] - } - - copy(dst, src) - } - - return dst -} diff --git a/vendor/github.com/pion/stun/.gitignore b/vendor/github.com/pion/stun/.gitignore deleted file mode 100644 index 6e2f206a..00000000 --- a/vendor/github.com/pion/stun/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/stun/.golangci.yml b/vendor/github.com/pion/stun/.golangci.yml deleted file mode 100644 index 4e3eddf4..00000000 --- a/vendor/github.com/pion/stun/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/stun/.goreleaser.yml b/vendor/github.com/pion/stun/.goreleaser.yml deleted file mode 100644 index 30093e9d..00000000 --- a/vendor/github.com/pion/stun/.goreleaser.yml +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -builds: -- skip: true diff --git a/vendor/github.com/pion/stun/AUTHORS.txt b/vendor/github.com/pion/stun/AUTHORS.txt deleted file mode 100644 index 3c3d9e00..00000000 --- a/vendor/github.com/pion/stun/AUTHORS.txt +++ /dev/null @@ -1,40 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Adam Kiss -Aleksandr Razumov -Aleksandr Razumov -Atsushi Watanabe -backkem -Cecylia Bocovich -Christian Muehlhaeuser -David-dp- -ernado -ernado -fossabot -Frank Dietrich -Hugo Arregui -Jerry Tao -jinleileiking -John Bradley -Juliusz Chroboczek -Maanas Royy -Moises Marangoni -Raphael Randschau -Sean DuBois -Sean DuBois -Sean DuBois -songjiayang -Steffen Vogel -Vladislav Yarmak -Will LE -Y.Horie -Yutaka Takeda -ZHENK - -# List of contributors not appearing in Git history -Aliaksandr Valialkin -The IETF Trust -The gortc project diff --git a/vendor/github.com/pion/stun/LICENSE b/vendor/github.com/pion/stun/LICENSE deleted file mode 100644 index 491caf6b..00000000 --- a/vendor/github.com/pion/stun/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2023 The Pion community - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/pion/stun/Makefile b/vendor/github.com/pion/stun/Makefile deleted file mode 100644 index ebfcd339..00000000 --- a/vendor/github.com/pion/stun/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -VERSION := $(shell git describe --tags | sed -e 's/^v//g' | awk -F "-" '{print $$1}') -ITERATION := $(shell git describe --tags --long | awk -F "-" '{print $$2}') -GO_VERSION=$(shell gobuild -v) -GO := $(or $(GOROOT),/usr/lib/go)/bin/go -PROCS := $(shell nproc) -cores: - @echo "cores: $(PROCS)" -bench: - go test -bench . -bench-record: - $(GO) test -bench . > "benchmarks/stun-go-$(GO_VERSION).txt" -lint: - @golangci-lint run ./... - @echo "ok" -escape: - @echo "Not escapes, except autogenerated:" - @go build -gcflags '-m -l' 2>&1 \ - | grep -v "" \ - | grep escapes -format: - goimports -w . -bench-compare: - go test -bench . > bench.go-16 - go-tip test -bench . > bench.go-tip - @benchcmp bench.go-16 bench.go-tip -install: - go get gortc.io/api - go get -u github.com/golangci/golangci-lint/cmd/golangci-lint -test-integration: - @cd e2e && bash ./test.sh -prepush: test lint test-integration -check-api: - @cd api && bash ./check.sh -test: - @./go.test.sh -clean: diff --git a/vendor/github.com/pion/stun/README.md b/vendor/github.com/pion/stun/README.md deleted file mode 100644 index fe1b28ff..00000000 --- a/vendor/github.com/pion/stun/README.md +++ /dev/null @@ -1,186 +0,0 @@ -

-
- Pion STUN -
-

-

A Go implementation of STUN

-

- Pion stun - Slack Widget -
- GitHub Workflow Status - Go Reference - Coverage Status - Go Report Card - License: MIT -

-
- -Package `stun` implements Session Traversal Utilities for NAT (STUN) ([RFC 5389][rfc5389]) -protocol and [client](https://pkg.go.dev/github.com/pion/stun#Client) with no external dependencies and zero allocations in hot paths. -Client [supports](https://pkg.go.dev/github.com/pion/stun#WithRTO) automatic request retransmissions. - -### Example -You can get your current IP address from any STUN server by sending -binding request. See more idiomatic example at `cmd/stun-client`. -```go -package main - -import ( - "fmt" - - "github.com/pion/stun" -) - -func main() { - // Parse a STUN URI - u, err := stun.ParseURI("stun:stun.l.google.com:19302") - if err != nil { - panic(err) - } - - // Creating a "connection" to STUN server. - c, err := stun.DialURI(u, &stun.DialConfig{}) - if err != nil { - panic(err) - } - // Building binding request with random transaction id. - message := stun.MustBuild(stun.TransactionID, stun.BindingRequest) - // Sending request to STUN server, waiting for response message. - if err := c.Do(message, func(res stun.Event) { - if res.Error != nil { - panic(res.Error) - } - // Decoding XOR-MAPPED-ADDRESS attribute from message. - var xorAddr stun.XORMappedAddress - if err := xorAddr.GetFrom(res.Message); err != nil { - panic(err) - } - fmt.Println("your IP is", xorAddr.IP) - }); err != nil { - panic(err) - } -} -``` - -### RFCs -#### Implemented -- **RFC 5389**: [Session Traversal Utilities for NAT (STUN)][rfc5389] -- **RFC 5769**: [Test Vectors for Session Traversal Utilities for NAT (STUN)][rfc5769] -- **RFC 6062**: [Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations][rfc6062] -- **RFC 7064**: [URI Scheme for the Session Traversal Utilities for NAT (STUN) Protocol][rfc7064] -- **RFC 7065**: [Traversal Using Relays around NAT (TURN) Uniform Resource Identifiers][rfc7065] -- **RFC 5780**: [NAT Behavior Discovery Using Session Traversal Utilities for NAT (STUN)][rfc5780] via [cmd/stun-nat-behaviour](cmd/stun-nat-behaviour) -- (TLS-over-)TCP client support - -#### Planned -- **RFC 5389**: [ALTERNATE-SERVER](https://tools.ietf.org/html/rfc5389#section-11) support [#48](https://github.com/pion/stun/issues/48) - -#### Compatability notes - -[RFC 5389][rfc5389] obsoletes [RFC 3489][rfc3489], so implementation was ignored by purpose, however, -[RFC 3489][rfc3489] can be easily implemented as separate package. - -[rfc3489]: https://tools.ietf.org/html/rfc3489 -[rfc5389]: https://tools.ietf.org/html/rfc5389 -[rfc5769]: https://tools.ietf.org/html/rfc5769 -[rfc5780]: https://tools.ietf.org/html/rfc5780 -[rfc6062]: https://tools.ietf.org/html/rfc6062 -[rfc7064]: https://tools.ietf.org/html/rfc7064 -[rfc7065]: https://tools.ietf.org/html/rfc7065 - -### Stability -Package is currently stable, no backward incompatible changes are expected -with exception of critical bugs or security fixes. - -Additional attributes are unlikely to be implemented in scope of stun package, -the only exception is constants for attribute or message types. - -### Requirements -Go 1.12 is currently supported and tested in CI. - -### Testing -Client behavior is tested and verified in many ways: - * End-To-End with long-term credentials - * **coturn**: The coturn [server](https://github.com/coturn/coturn/wiki/turnserver) (linux) - * Bunch of code static checkers (linters) - * Standard unit-tests with coverage reporting (linux {amd64, **arm**64}, windows and darwin) - * Explicit API backward compatibility [check](https://github.com/gortc/api), see `api` directory - -See [TeamCity project](https://tc.gortc.io/project.html?projectId=stun&guest=1) and `e2e` directory -for more information. Also the Wireshark `.pcap` files are available for e2e test in -artifacts for build. - -### Benchmarks -Intel(R) Core(TM) i7-8700K: - -``` -version: 1.22.2 -goos: linux -goarch: amd64 -pkg: github.com/pion/stun -PASS -benchmark iter time/iter throughput bytes alloc allocs ---------- ---- --------- ---------- ----------- ------ -BenchmarkMappedAddress_AddTo-12 32489450 38.30 ns/op 0 B/op 0 allocs/op -BenchmarkAlternateServer_AddTo-12 31230991 39.00 ns/op 0 B/op 0 allocs/op -BenchmarkAgent_GC-12 431390 2918.00 ns/op 0 B/op 0 allocs/op -BenchmarkAgent_Process-12 35901940 36.20 ns/op 0 B/op 0 allocs/op -BenchmarkMessage_GetNotFound-12 242004358 5.19 ns/op 0 B/op 0 allocs/op -BenchmarkMessage_Get-12 230520343 5.21 ns/op 0 B/op 0 allocs/op -BenchmarkClient_Do-12 1282231 943.00 ns/op 0 B/op 0 allocs/op -BenchmarkErrorCode_AddTo-12 16318916 75.50 ns/op 0 B/op 0 allocs/op -BenchmarkErrorCodeAttribute_AddTo-12 21584140 54.80 ns/op 0 B/op 0 allocs/op -BenchmarkErrorCodeAttribute_GetFrom-12 100000000 11.10 ns/op 0 B/op 0 allocs/op -BenchmarkFingerprint_AddTo-12 19368768 64.00 ns/op 687.81 MB/s 0 B/op 0 allocs/op -BenchmarkFingerprint_Check-12 24167007 49.10 ns/op 1057.99 MB/s 0 B/op 0 allocs/op -BenchmarkBuildOverhead/Build-12 5486252 224.00 ns/op 0 B/op 0 allocs/op -BenchmarkBuildOverhead/BuildNonPointer-12 2496544 517.00 ns/op 100 B/op 4 allocs/op -BenchmarkBuildOverhead/Raw-12 6652118 181.00 ns/op 0 B/op 0 allocs/op -BenchmarkMessage_ForEach-12 28254212 35.90 ns/op 0 B/op 0 allocs/op -BenchmarkMessageIntegrity_AddTo-12 1000000 1179.00 ns/op 16.96 MB/s 0 B/op 0 allocs/op -BenchmarkMessageIntegrity_Check-12 975954 1219.00 ns/op 26.24 MB/s 0 B/op 0 allocs/op -BenchmarkMessage_Write-12 41040598 30.40 ns/op 922.13 MB/s 0 B/op 0 allocs/op -BenchmarkMessageType_Value-12 1000000000 0.53 ns/op 0 B/op 0 allocs/op -BenchmarkMessage_WriteTo-12 94942935 11.30 ns/op 0 B/op 0 allocs/op -BenchmarkMessage_ReadFrom-12 43437718 29.30 ns/op 682.87 MB/s 0 B/op 0 allocs/op -BenchmarkMessage_ReadBytes-12 74693397 15.90 ns/op 1257.42 MB/s 0 B/op 0 allocs/op -BenchmarkIsMessage-12 1000000000 1.20 ns/op 16653.64 MB/s 0 B/op 0 allocs/op -BenchmarkMessage_NewTransactionID-12 521121 2450.00 ns/op 0 B/op 0 allocs/op -BenchmarkMessageFull-12 5389495 221.00 ns/op 0 B/op 0 allocs/op -BenchmarkMessageFullHardcore-12 12715876 94.40 ns/op 0 B/op 0 allocs/op -BenchmarkMessage_WriteHeader-12 100000000 11.60 ns/op 0 B/op 0 allocs/op -BenchmarkMessage_CloneTo-12 30199020 41.80 ns/op 1626.66 MB/s 0 B/op 0 allocs/op -BenchmarkMessage_AddTo-12 415257625 2.97 ns/op 0 B/op 0 allocs/op -BenchmarkDecode-12 49573747 23.60 ns/op 0 B/op 0 allocs/op -BenchmarkUsername_AddTo-12 56282674 22.50 ns/op 0 B/op 0 allocs/op -BenchmarkUsername_GetFrom-12 100000000 10.10 ns/op 0 B/op 0 allocs/op -BenchmarkNonce_AddTo-12 39419097 35.80 ns/op 0 B/op 0 allocs/op -BenchmarkNonce_AddTo_BadLength-12 196291666 6.04 ns/op 0 B/op 0 allocs/op -BenchmarkNonce_GetFrom-12 120857732 9.93 ns/op 0 B/op 0 allocs/op -BenchmarkUnknownAttributes/AddTo-12 28881430 37.20 ns/op 0 B/op 0 allocs/op -BenchmarkUnknownAttributes/GetFrom-12 64907534 19.80 ns/op 0 B/op 0 allocs/op -BenchmarkXOR-12 32868506 32.20 ns/op 31836.66 MB/s -BenchmarkXORSafe-12 5185776 234.00 ns/op 4378.74 MB/s -BenchmarkXORFast-12 30975679 32.50 ns/op 31525.28 MB/s -BenchmarkXORMappedAddress_AddTo-12 21518028 54.50 ns/op 0 B/op 0 allocs/op -BenchmarkXORMappedAddress_GetFrom-12 35597667 34.40 ns/op 0 B/op 0 allocs/op -ok github.com/pion/stun 60.973s -``` - -### Roadmap -The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones. - -### Community -Pion has an active community on the [Slack](https://pion.ly/slack). - -Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news. - -We are always looking to support **your projects**. Please reach out if you have something to build! -If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) - -### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) - -### License -MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/stun/addr.go b/vendor/github.com/pion/stun/addr.go deleted file mode 100644 index d15e2bbd..00000000 --- a/vendor/github.com/pion/stun/addr.go +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "fmt" - "io" - "net" - "strconv" -) - -// MappedAddress represents MAPPED-ADDRESS attribute. -// -// This attribute is used only by servers for achieving backwards -// compatibility with RFC 3489 clients. -// -// RFC 5389 Section 15.1 -type MappedAddress struct { - IP net.IP - Port int -} - -// AlternateServer represents ALTERNATE-SERVER attribute. -// -// RFC 5389 Section 15.11 -type AlternateServer struct { - IP net.IP - Port int -} - -// ResponseOrigin represents RESPONSE-ORIGIN attribute. -// -// RFC 5780 Section 7.3 -type ResponseOrigin struct { - IP net.IP - Port int -} - -// OtherAddress represents OTHER-ADDRESS attribute. -// -// RFC 5780 Section 7.4 -type OtherAddress struct { - IP net.IP - Port int -} - -// AddTo adds ALTERNATE-SERVER attribute to message. -func (s *AlternateServer) AddTo(m *Message) error { - a := (*MappedAddress)(s) - return a.AddToAs(m, AttrAlternateServer) -} - -// GetFrom decodes ALTERNATE-SERVER from message. -func (s *AlternateServer) GetFrom(m *Message) error { - a := (*MappedAddress)(s) - return a.GetFromAs(m, AttrAlternateServer) -} - -func (a MappedAddress) String() string { - return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port)) -} - -// GetFromAs decodes MAPPED-ADDRESS value in message m as an attribute of type t. -func (a *MappedAddress) GetFromAs(m *Message, t AttrType) error { - v, err := m.Get(t) - if err != nil { - return err - } - if len(v) <= 4 { - return io.ErrUnexpectedEOF - } - family := bin.Uint16(v[0:2]) - if family != familyIPv6 && family != familyIPv4 { - return newDecodeErr("xor-mapped address", "family", - fmt.Sprintf("bad value %d", family), - ) - } - ipLen := net.IPv4len - if family == familyIPv6 { - ipLen = net.IPv6len - } - // Ensuring len(a.IP) == ipLen and reusing a.IP. - if len(a.IP) < ipLen { - a.IP = a.IP[:cap(a.IP)] - for len(a.IP) < ipLen { - a.IP = append(a.IP, 0) - } - } - a.IP = a.IP[:ipLen] - for i := range a.IP { - a.IP[i] = 0 - } - a.Port = int(bin.Uint16(v[2:4])) - copy(a.IP, v[4:]) - return nil -} - -// AddToAs adds MAPPED-ADDRESS value to m as t attribute. -func (a *MappedAddress) AddToAs(m *Message, t AttrType) error { - var ( - family = familyIPv4 - ip = a.IP - ) - if len(a.IP) == net.IPv6len { - if isIPv4(ip) { - ip = ip[12:16] // like in ip.To4() - } else { - family = familyIPv6 - } - } else if len(ip) != net.IPv4len { - return ErrBadIPLength - } - value := make([]byte, 128) - value[0] = 0 // first 8 bits are zeroes - bin.PutUint16(value[0:2], family) - bin.PutUint16(value[2:4], uint16(a.Port)) - copy(value[4:], ip) - m.Add(t, value[:4+len(ip)]) - return nil -} - -// AddTo adds MAPPED-ADDRESS to message. -func (a *MappedAddress) AddTo(m *Message) error { - return a.AddToAs(m, AttrMappedAddress) -} - -// GetFrom decodes MAPPED-ADDRESS from message. -func (a *MappedAddress) GetFrom(m *Message) error { - return a.GetFromAs(m, AttrMappedAddress) -} - -// AddTo adds OTHER-ADDRESS attribute to message. -func (o *OtherAddress) AddTo(m *Message) error { - a := (*MappedAddress)(o) - return a.AddToAs(m, AttrOtherAddress) -} - -// GetFrom decodes OTHER-ADDRESS from message. -func (o *OtherAddress) GetFrom(m *Message) error { - a := (*MappedAddress)(o) - return a.GetFromAs(m, AttrOtherAddress) -} - -func (o OtherAddress) String() string { - return net.JoinHostPort(o.IP.String(), strconv.Itoa(o.Port)) -} - -// AddTo adds RESPONSE-ORIGIN attribute to message. -func (o *ResponseOrigin) AddTo(m *Message) error { - a := (*MappedAddress)(o) - return a.AddToAs(m, AttrResponseOrigin) -} - -// GetFrom decodes RESPONSE-ORIGIN from message. -func (o *ResponseOrigin) GetFrom(m *Message) error { - a := (*MappedAddress)(o) - return a.GetFromAs(m, AttrResponseOrigin) -} - -func (o ResponseOrigin) String() string { - return net.JoinHostPort(o.IP.String(), strconv.Itoa(o.Port)) -} diff --git a/vendor/github.com/pion/stun/agent.go b/vendor/github.com/pion/stun/agent.go deleted file mode 100644 index f03efa3c..00000000 --- a/vendor/github.com/pion/stun/agent.go +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "errors" - "sync" - "time" -) - -// NoopHandler just discards any event. -func NoopHandler() Handler { - return func(e Event) {} -} - -// NewAgent initializes and returns new Agent with provided handler. -// If h is nil, the NoopHandler will be used. -func NewAgent(h Handler) *Agent { - if h == nil { - h = NoopHandler() - } - a := &Agent{ - transactions: make(map[transactionID]agentTransaction), - handler: h, - } - return a -} - -// Agent is low-level abstraction over transaction list that -// handles concurrency (all calls are goroutine-safe) and -// time outs (via Collect call). -type Agent struct { - // transactions is map of transactions that are currently - // in progress. Event handling is done in such way when - // transaction is unregistered before agentTransaction access, - // minimizing mux lock and protecting agentTransaction from - // data races via unexpected concurrent access. - transactions map[transactionID]agentTransaction - closed bool // all calls are invalid if true - mux sync.Mutex // protects transactions and closed - handler Handler // handles transactions -} - -// Handler handles state changes of transaction. -// -// Handler is called on transaction state change. -// Usage of e is valid only during call, user must -// copy needed fields explicitly. -type Handler func(e Event) - -// Event is passed to Handler describing the transaction event. -// Do not reuse outside Handler. -type Event struct { - TransactionID [TransactionIDSize]byte - Message *Message - Error error -} - -// agentTransaction represents transaction in progress. -// Concurrent access is invalid. -type agentTransaction struct { - id transactionID - deadline time.Time -} - -var ( - // ErrTransactionStopped indicates that transaction was manually stopped. - ErrTransactionStopped = errors.New("transaction is stopped") - // ErrTransactionNotExists indicates that agent failed to find transaction. - ErrTransactionNotExists = errors.New("transaction not exists") - // ErrTransactionExists indicates that transaction with same id is already - // registered. - ErrTransactionExists = errors.New("transaction exists with same id") -) - -// StopWithError removes transaction from list and calls handler with -// provided error. Can return ErrTransactionNotExists and ErrAgentClosed. -func (a *Agent) StopWithError(id [TransactionIDSize]byte, err error) error { - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - t, exists := a.transactions[id] - delete(a.transactions, id) - h := a.handler - a.mux.Unlock() - if !exists { - return ErrTransactionNotExists - } - h(Event{ - TransactionID: t.id, - Error: err, - }) - return nil -} - -// Stop stops transaction by id with ErrTransactionStopped, blocking -// until handler returns. -func (a *Agent) Stop(id [TransactionIDSize]byte) error { - return a.StopWithError(id, ErrTransactionStopped) -} - -// ErrAgentClosed indicates that agent is in closed state and is unable -// to handle transactions. -var ErrAgentClosed = errors.New("agent is closed") - -// Start registers transaction with provided id and deadline. -// Could return ErrAgentClosed, ErrTransactionExists. -// -// Agent handler is guaranteed to be eventually called. -func (a *Agent) Start(id [TransactionIDSize]byte, deadline time.Time) error { - a.mux.Lock() - defer a.mux.Unlock() - if a.closed { - return ErrAgentClosed - } - _, exists := a.transactions[id] - if exists { - return ErrTransactionExists - } - a.transactions[id] = agentTransaction{ - id: id, - deadline: deadline, - } - return nil -} - -// agentCollectCap is initial capacity for Agent.Collect slices, -// sufficient to make function zero-alloc in most cases. -const agentCollectCap = 100 - -// ErrTransactionTimeOut indicates that transaction has reached deadline. -var ErrTransactionTimeOut = errors.New("transaction is timed out") - -// Collect terminates all transactions that have deadline before provided -// time, blocking until all handlers will process ErrTransactionTimeOut. -// Will return ErrAgentClosed if agent is already closed. -// -// It is safe to call Collect concurrently but makes no sense. -func (a *Agent) Collect(gcTime time.Time) error { - toRemove := make([]transactionID, 0, agentCollectCap) - a.mux.Lock() - if a.closed { - // Doing nothing if agent is closed. - // All transactions should be already closed - // during Close() call. - a.mux.Unlock() - return ErrAgentClosed - } - // Adding all transactions with deadline before gcTime - // to toCall and toRemove slices. - // No allocs if there are less than agentCollectCap - // timed out transactions. - for id, t := range a.transactions { - if t.deadline.Before(gcTime) { - toRemove = append(toRemove, id) - } - } - // Un-registering timed out transactions. - for _, id := range toRemove { - delete(a.transactions, id) - } - // Calling handler does not require locked mutex, - // reducing lock time. - h := a.handler - a.mux.Unlock() - // Sending ErrTransactionTimeOut to handler for all transactions, - // blocking until last one. - event := Event{ - Error: ErrTransactionTimeOut, - } - for _, id := range toRemove { - event.TransactionID = id - h(event) - } - return nil -} - -// Process incoming message, synchronously passing it to handler. -func (a *Agent) Process(m *Message) error { - e := Event{ - TransactionID: m.TransactionID, - Message: m, - } - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - h := a.handler - delete(a.transactions, m.TransactionID) - a.mux.Unlock() - h(e) - return nil -} - -// SetHandler sets agent handler to h. -func (a *Agent) SetHandler(h Handler) error { - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - a.handler = h - a.mux.Unlock() - return nil -} - -// Close terminates all transactions with ErrAgentClosed and renders Agent to -// closed state. -func (a *Agent) Close() error { - e := Event{ - Error: ErrAgentClosed, - } - a.mux.Lock() - if a.closed { - a.mux.Unlock() - return ErrAgentClosed - } - for _, t := range a.transactions { - e.TransactionID = t.id - a.handler(e) - } - a.transactions = nil - a.closed = true - a.handler = nil - a.mux.Unlock() - return nil -} - -type transactionID [TransactionIDSize]byte diff --git a/vendor/github.com/pion/stun/attributes.go b/vendor/github.com/pion/stun/attributes.go deleted file mode 100644 index 8a1aa214..00000000 --- a/vendor/github.com/pion/stun/attributes.go +++ /dev/null @@ -1,254 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "errors" - "fmt" -) - -// Attributes is list of message attributes. -type Attributes []RawAttribute - -// Get returns first attribute from list by the type. -// If attribute is present the RawAttribute is returned and the -// boolean is true. Otherwise the returned RawAttribute will be -// empty and boolean will be false. -func (a Attributes) Get(t AttrType) (RawAttribute, bool) { - for _, candidate := range a { - if candidate.Type == t { - return candidate, true - } - } - return RawAttribute{}, false -} - -// AttrType is attribute type. -type AttrType uint16 - -// Required returns true if type is from comprehension-required range (0x0000-0x7FFF). -func (t AttrType) Required() bool { - return t <= 0x7FFF -} - -// Optional returns true if type is from comprehension-optional range (0x8000-0xFFFF). -func (t AttrType) Optional() bool { - return t >= 0x8000 -} - -// Attributes from comprehension-required range (0x0000-0x7FFF). -const ( - AttrMappedAddress AttrType = 0x0001 // MAPPED-ADDRESS - AttrUsername AttrType = 0x0006 // USERNAME - AttrMessageIntegrity AttrType = 0x0008 // MESSAGE-INTEGRITY - AttrErrorCode AttrType = 0x0009 // ERROR-CODE - AttrUnknownAttributes AttrType = 0x000A // UNKNOWN-ATTRIBUTES - AttrRealm AttrType = 0x0014 // REALM - AttrNonce AttrType = 0x0015 // NONCE - AttrXORMappedAddress AttrType = 0x0020 // XOR-MAPPED-ADDRESS -) - -// Attributes from comprehension-optional range (0x8000-0xFFFF). -const ( - AttrSoftware AttrType = 0x8022 // SOFTWARE - AttrAlternateServer AttrType = 0x8023 // ALTERNATE-SERVER - AttrFingerprint AttrType = 0x8028 // FINGERPRINT -) - -// Attributes from RFC 5245 ICE. -const ( - AttrPriority AttrType = 0x0024 // PRIORITY - AttrUseCandidate AttrType = 0x0025 // USE-CANDIDATE - AttrICEControlled AttrType = 0x8029 // ICE-CONTROLLED - AttrICEControlling AttrType = 0x802A // ICE-CONTROLLING -) - -// Attributes from RFC 5766 TURN. -const ( - AttrChannelNumber AttrType = 0x000C // CHANNEL-NUMBER - AttrLifetime AttrType = 0x000D // LIFETIME - AttrXORPeerAddress AttrType = 0x0012 // XOR-PEER-ADDRESS - AttrData AttrType = 0x0013 // DATA - AttrXORRelayedAddress AttrType = 0x0016 // XOR-RELAYED-ADDRESS - AttrEvenPort AttrType = 0x0018 // EVEN-PORT - AttrRequestedTransport AttrType = 0x0019 // REQUESTED-TRANSPORT - AttrDontFragment AttrType = 0x001A // DONT-FRAGMENT - AttrReservationToken AttrType = 0x0022 // RESERVATION-TOKEN -) - -// Attributes from RFC 5780 NAT Behavior Discovery -const ( - AttrChangeRequest AttrType = 0x0003 // CHANGE-REQUEST - AttrPadding AttrType = 0x0026 // PADDING - AttrResponsePort AttrType = 0x0027 // RESPONSE-PORT - AttrCacheTimeout AttrType = 0x8027 // CACHE-TIMEOUT - AttrResponseOrigin AttrType = 0x802b // RESPONSE-ORIGIN - AttrOtherAddress AttrType = 0x802C // OTHER-ADDRESS -) - -// Attributes from RFC 3489, removed by RFC 5389, -// -// but still used by RFC5389-implementing software like Vovida.org, reTURNServer, etc. -const ( - AttrSourceAddress AttrType = 0x0004 // SOURCE-ADDRESS - AttrChangedAddress AttrType = 0x0005 // CHANGED-ADDRESS -) - -// Attributes from RFC 6062 TURN Extensions for TCP Allocations. -const ( - AttrConnectionID AttrType = 0x002a // CONNECTION-ID -) - -// Attributes from RFC 6156 TURN IPv6. -const ( - AttrRequestedAddressFamily AttrType = 0x0017 // REQUESTED-ADDRESS-FAMILY -) - -// Attributes from An Origin Attribute for the STUN Protocol. -const ( - AttrOrigin AttrType = 0x802F -) - -// Attributes from RFC 8489 STUN. -const ( - AttrMessageIntegritySHA256 AttrType = 0x001C // MESSAGE-INTEGRITY-SHA256 - AttrPasswordAlgorithm AttrType = 0x001D // PASSWORD-ALGORITHM - AttrUserhash AttrType = 0x001E // USERHASH - AttrPasswordAlgorithms AttrType = 0x8002 // PASSWORD-ALGORITHMS - AttrAlternateDomain AttrType = 0x8003 // ALTERNATE-DOMAIN -) - -// Value returns uint16 representation of attribute type. -func (t AttrType) Value() uint16 { - return uint16(t) -} - -func attrNames() map[AttrType]string { - return map[AttrType]string{ - AttrMappedAddress: "MAPPED-ADDRESS", - AttrUsername: "USERNAME", - AttrErrorCode: "ERROR-CODE", - AttrMessageIntegrity: "MESSAGE-INTEGRITY", - AttrUnknownAttributes: "UNKNOWN-ATTRIBUTES", - AttrRealm: "REALM", - AttrNonce: "NONCE", - AttrXORMappedAddress: "XOR-MAPPED-ADDRESS", - AttrSoftware: "SOFTWARE", - AttrAlternateServer: "ALTERNATE-SERVER", - AttrFingerprint: "FINGERPRINT", - AttrPriority: "PRIORITY", - AttrUseCandidate: "USE-CANDIDATE", - AttrICEControlled: "ICE-CONTROLLED", - AttrICEControlling: "ICE-CONTROLLING", - AttrChannelNumber: "CHANNEL-NUMBER", - AttrLifetime: "LIFETIME", - AttrXORPeerAddress: "XOR-PEER-ADDRESS", - AttrData: "DATA", - AttrXORRelayedAddress: "XOR-RELAYED-ADDRESS", - AttrEvenPort: "EVEN-PORT", - AttrRequestedTransport: "REQUESTED-TRANSPORT", - AttrDontFragment: "DONT-FRAGMENT", - AttrReservationToken: "RESERVATION-TOKEN", - AttrConnectionID: "CONNECTION-ID", - AttrRequestedAddressFamily: "REQUESTED-ADDRESS-FAMILY", - AttrMessageIntegritySHA256: "MESSAGE-INTEGRITY-SHA256", - AttrPasswordAlgorithm: "PASSWORD-ALGORITHM", - AttrUserhash: "USERHASH", - AttrPasswordAlgorithms: "PASSWORD-ALGORITHMS", - AttrAlternateDomain: "ALTERNATE-DOMAIN", - } -} - -func (t AttrType) String() string { - s, ok := attrNames()[t] - if !ok { - // Just return hex representation of unknown attribute type. - return fmt.Sprintf("0x%x", uint16(t)) - } - return s -} - -// RawAttribute is a Type-Length-Value (TLV) object that -// can be added to a STUN message. Attributes are divided into two -// types: comprehension-required and comprehension-optional. STUN -// agents can safely ignore comprehension-optional attributes they -// don't understand, but cannot successfully process a message if it -// contains comprehension-required attributes that are not -// understood. -type RawAttribute struct { - Type AttrType - Length uint16 // ignored while encoding - Value []byte -} - -// AddTo implements Setter, adding attribute as a.Type with a.Value and ignoring -// the Length field. -func (a RawAttribute) AddTo(m *Message) error { - m.Add(a.Type, a.Value) - return nil -} - -// Equal returns true if a == b. -func (a RawAttribute) Equal(b RawAttribute) bool { - if a.Type != b.Type { - return false - } - if a.Length != b.Length { - return false - } - if len(b.Value) != len(a.Value) { - return false - } - for i, v := range a.Value { - if b.Value[i] != v { - return false - } - } - return true -} - -func (a RawAttribute) String() string { - return fmt.Sprintf("%s: 0x%x", a.Type, a.Value) -} - -// ErrAttributeNotFound means that attribute with provided attribute -// type does not exist in message. -var ErrAttributeNotFound = errors.New("attribute not found") - -// Get returns byte slice that represents attribute value, -// if there is no attribute with such type, -// ErrAttributeNotFound is returned. -func (m *Message) Get(t AttrType) ([]byte, error) { - v, ok := m.Attributes.Get(t) - if !ok { - return nil, ErrAttributeNotFound - } - return v.Value, nil -} - -// STUN aligns attributes on 32-bit boundaries, attributes whose content -// is not a multiple of 4 bytes are padded with 1, 2, or 3 bytes of -// padding so that its value contains a multiple of 4 bytes. The -// padding bits are ignored, and may be any value. -// -// https://tools.ietf.org/html/rfc5389#section-15 -const padding = 4 - -func nearestPaddedValueLength(l int) int { - n := padding * (l / padding) - if n < l { - n += padding - } - return n -} - -// This method converts uint16 vlue to AttrType. If it finds an old attribute -// type value, it also translates it to the new value to enable backward -// compatibility. (See: https://github.com/pion/stun/issues/21) -func compatAttrType(val uint16) AttrType { - if val == 0x8020 { // draft-ietf-behave-rfc3489bis-02, MS-TURN - return AttrXORMappedAddress // new: 0x0020 (from draft-ietf-behave-rfc3489bis-03 on) - } - return AttrType(val) -} diff --git a/vendor/github.com/pion/stun/attributes_debug.go b/vendor/github.com/pion/stun/attributes_debug.go deleted file mode 100644 index 836d79f1..00000000 --- a/vendor/github.com/pion/stun/attributes_debug.go +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build debug -// +build debug - -package stun - -import "fmt" - -// AttrOverflowErr occurs when len(v) > Max. -type AttrOverflowErr struct { - Type AttrType - Max int - Got int -} - -func (e AttrOverflowErr) Error() string { - return fmt.Sprintf("incorrect length of %s attribute: %d exceeds maximum %d", - e.Type, e.Got, e.Max, - ) -} - -// AttrLengthErr means that length for attribute is invalid. -type AttrLengthErr struct { - Attr AttrType - Got int - Expected int -} - -func (e AttrLengthErr) Error() string { - return fmt.Sprintf("incorrect length of %s attribute: got %d, expected %d", - e.Attr, - e.Got, - e.Expected, - ) -} diff --git a/vendor/github.com/pion/stun/checks.go b/vendor/github.com/pion/stun/checks.go deleted file mode 100644 index 6b678a06..00000000 --- a/vendor/github.com/pion/stun/checks.go +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !debug -// +build !debug - -package stun - -import ( - "errors" - - "github.com/pion/stun/internal/hmac" -) - -// CheckSize returns ErrAttrSizeInvalid if got is not equal to expected. -func CheckSize(_ AttrType, got, expected int) error { - if got == expected { - return nil - } - return ErrAttributeSizeInvalid -} - -func checkHMAC(got, expected []byte) error { - if hmac.Equal(got, expected) { - return nil - } - return ErrIntegrityMismatch -} - -func checkFingerprint(got, expected uint32) error { - if got == expected { - return nil - } - return ErrFingerprintMismatch -} - -// IsAttrSizeInvalid returns true if error means that attribute size is invalid. -func IsAttrSizeInvalid(err error) bool { - return errors.Is(err, ErrAttributeSizeInvalid) -} - -// CheckOverflow returns ErrAttributeSizeOverflow if got is bigger that max. -func CheckOverflow(_ AttrType, got, max int) error { - if got <= max { - return nil - } - return ErrAttributeSizeOverflow -} - -// IsAttrSizeOverflow returns true if error means that attribute size is too big. -func IsAttrSizeOverflow(err error) bool { - return errors.Is(err, ErrAttributeSizeOverflow) -} diff --git a/vendor/github.com/pion/stun/checks_debug.go b/vendor/github.com/pion/stun/checks_debug.go deleted file mode 100644 index 0b5c67c8..00000000 --- a/vendor/github.com/pion/stun/checks_debug.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build debug -// +build debug - -package stun - -import "github.com/pion/stun/internal/hmac" - -// CheckSize returns *AttrLengthError if got is not equal to expected. -func CheckSize(a AttrType, got, expected int) error { - if got == expected { - return nil - } - return &AttrLengthErr{ - Got: got, - Expected: expected, - Attr: a, - } -} - -func checkHMAC(got, expected []byte) error { - if hmac.Equal(got, expected) { - return nil - } - return &IntegrityErr{ - Expected: expected, - Actual: got, - } -} - -func checkFingerprint(got, expected uint32) error { - if got == expected { - return nil - } - return &CRCMismatch{ - Actual: got, - Expected: expected, - } -} - -// IsAttrSizeInvalid returns true if error means that attribute size is invalid. -func IsAttrSizeInvalid(err error) bool { - _, ok := err.(*AttrLengthErr) - return ok -} - -// CheckOverflow returns *AttrOverflowErr if got is bigger that max. -func CheckOverflow(t AttrType, got, max int) error { - if got <= max { - return nil - } - return &AttrOverflowErr{ - Type: t, - Got: got, - Max: max, - } -} - -// IsAttrSizeOverflow returns true if error means that attribute size is too big. -func IsAttrSizeOverflow(err error) bool { - _, ok := err.(*AttrOverflowErr) - return ok -} diff --git a/vendor/github.com/pion/stun/client.go b/vendor/github.com/pion/stun/client.go deleted file mode 100644 index 5d02e51d..00000000 --- a/vendor/github.com/pion/stun/client.go +++ /dev/null @@ -1,722 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "crypto/tls" - "errors" - "fmt" - "io" - "log" - "net" - "runtime" - "strconv" - "sync" - "sync/atomic" - "time" - - "github.com/pion/dtls/v2" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" -) - -// ErrUnsupportedURI is an error thrown if the user passes an unsupported STUN or TURN URI -var ErrUnsupportedURI = fmt.Errorf("invalid schema or transport") - -// Dial connects to the address on the named network and then -// initializes Client on that connection, returning error if any. -func Dial(network, address string) (*Client, error) { - conn, err := net.Dial(network, address) - if err != nil { - return nil, err - } - return NewClient(conn) -} - -// DialConfig is used to pass configuration to DialURI() -type DialConfig struct { - DTLSConfig dtls.Config - TLSConfig tls.Config - - Net transport.Net -} - -// DialURI connect to the STUN/TURN URI and then -// initializes Client on that connection, returning error if any. -func DialURI(uri *URI, cfg *DialConfig) (*Client, error) { - var conn Connection - var err error - - nw := cfg.Net - if nw == nil { - nw, err = stdnet.NewNet() - if err != nil { - return nil, fmt.Errorf("failed to create net: %w", err) - } - } - - addr := net.JoinHostPort(uri.Host, strconv.Itoa(uri.Port)) - - switch { - case uri.Scheme == SchemeTypeSTUN: - if conn, err = nw.Dial("udp", addr); err != nil { - return nil, fmt.Errorf("failed to listen: %w", err) - } - - case uri.Scheme == SchemeTypeTURN: - network := "udp" //nolint:goconst - if uri.Proto == ProtoTypeTCP { - network = "tcp" //nolint:goconst - } - - if conn, err = nw.Dial(network, addr); err != nil { - return nil, fmt.Errorf("failed to dial: %w", err) - } - - case uri.Scheme == SchemeTypeTURNS && uri.Proto == ProtoTypeUDP: - dtlsCfg := cfg.DTLSConfig // Copy - dtlsCfg.ServerName = uri.Host - - udpConn, err := nw.Dial("udp", addr) - if err != nil { - return nil, fmt.Errorf("failed to dial: %w", err) - } - - if conn, err = dtls.Client(udpConn, &dtlsCfg); err != nil { - return nil, fmt.Errorf("failed to connect to '%s': %w", addr, err) - } - - case (uri.Scheme == SchemeTypeTURNS || uri.Scheme == SchemeTypeSTUNS) && uri.Proto == ProtoTypeTCP: - tlsCfg := cfg.TLSConfig //nolint:govet - tlsCfg.ServerName = uri.Host - - tcpConn, err := nw.Dial("tcp", addr) - if err != nil { - return nil, fmt.Errorf("failed to dial: %w", err) - } - - conn = tls.Client(tcpConn, &tlsCfg) - - default: - return nil, ErrUnsupportedURI - } - - return NewClient(conn) -} - -// ErrNoConnection means that ClientOptions.Connection is nil. -var ErrNoConnection = errors.New("no connection provided") - -// ClientOption sets some client option. -type ClientOption func(c *Client) - -// WithHandler sets client handler which is called if Agent emits the Event -// with TransactionID that is not currently registered by Client. -// Useful for handling Data indications from TURN server. -func WithHandler(h Handler) ClientOption { - return func(c *Client) { - c.handler = h - } -} - -// WithRTO sets client RTO as defined in STUN RFC. -func WithRTO(rto time.Duration) ClientOption { - return func(c *Client) { - c.rto = int64(rto) - } -} - -// WithClock sets Clock of client, the source of current time. -// Also clock is passed to default collector if set. -func WithClock(clock Clock) ClientOption { - return func(c *Client) { - c.clock = clock - } -} - -// WithTimeoutRate sets RTO timer minimum resolution. -func WithTimeoutRate(d time.Duration) ClientOption { - return func(c *Client) { - c.rtoRate = d - } -} - -// WithAgent sets client STUN agent. -// -// Defaults to agent implementation in current package, -// see agent.go. -func WithAgent(a ClientAgent) ClientOption { - return func(c *Client) { - c.a = a - } -} - -// WithCollector rests client timeout collector, the implementation -// of ticker which calls function on each tick. -func WithCollector(coll Collector) ClientOption { - return func(c *Client) { - c.collector = coll - } -} - -// WithNoConnClose prevents client from closing underlying connection when -// the Close() method is called. -func WithNoConnClose() ClientOption { - return func(c *Client) { - c.closeConn = false - } -} - -// WithNoRetransmit disables retransmissions and sets RTO to -// defaultMaxAttempts * defaultRTO which will be effectively time out -// if not set. -// -// Useful for TCP connections where transport handles RTO. -func WithNoRetransmit(c *Client) { - c.maxAttempts = 0 - if c.rto == 0 { - c.rto = defaultMaxAttempts * int64(defaultRTO) - } -} - -const ( - defaultTimeoutRate = time.Millisecond * 5 - defaultRTO = time.Millisecond * 300 - defaultMaxAttempts = 7 -) - -// NewClient initializes new Client from provided options, -// starting internal goroutines and using default options fields -// if necessary. Call Close method after using Client to close conn and -// release resources. -// -// The conn will be closed on Close call. Use WithNoConnClose option to -// prevent that. -// -// Note that user should handle the protocol multiplexing, client does not -// provide any API for it, so if you need to read application data, wrap the -// connection with your (de-)multiplexer and pass the wrapper as conn. -func NewClient(conn Connection, options ...ClientOption) (*Client, error) { - c := &Client{ - close: make(chan struct{}), - c: conn, - clock: systemClock(), - rto: int64(defaultRTO), - rtoRate: defaultTimeoutRate, - t: make(map[transactionID]*clientTransaction, 100), - maxAttempts: defaultMaxAttempts, - closeConn: true, - } - for _, o := range options { - o(c) - } - if c.c == nil { - return nil, ErrNoConnection - } - if c.a == nil { - c.a = NewAgent(nil) - } - if err := c.a.SetHandler(c.handleAgentCallback); err != nil { - return nil, err - } - if c.collector == nil { - c.collector = &tickerCollector{ - close: make(chan struct{}), - clock: c.clock, - } - } - if err := c.collector.Start(c.rtoRate, func(t time.Time) { - closedOrPanic(c.a.Collect(t)) - }); err != nil { - return nil, err - } - c.wg.Add(1) - go c.readUntilClosed() - runtime.SetFinalizer(c, clientFinalizer) - return c, nil -} - -func clientFinalizer(c *Client) { - if c == nil { - return - } - err := c.Close() - if errors.Is(err, ErrClientClosed) { - return - } - if err == nil { - log.Println("client: called finalizer on non-closed client") // nolint - return - } - log.Println("client: called finalizer on non-closed client:", err) // nolint -} - -// Connection wraps Reader, Writer and Closer interfaces. -type Connection interface { - io.Reader - io.Writer - io.Closer -} - -// ClientAgent is Agent implementation that is used by Client to -// process transactions. -type ClientAgent interface { - Process(*Message) error - Close() error - Start(id [TransactionIDSize]byte, deadline time.Time) error - Stop(id [TransactionIDSize]byte) error - Collect(time.Time) error - SetHandler(h Handler) error -} - -// Client simulates "connection" to STUN server. -type Client struct { - rto int64 // time.Duration - a ClientAgent - c Connection - close chan struct{} - rtoRate time.Duration - maxAttempts int32 - closed bool - closeConn bool // should call c.Close() while closing - wg sync.WaitGroup - clock Clock - handler Handler - collector Collector - t map[transactionID]*clientTransaction - - // mux guards closed and t - mux sync.RWMutex -} - -// clientTransaction represents transaction in progress. -// If transaction is succeed or failed, f will be called -// provided by event. -// Concurrent access is invalid. -type clientTransaction struct { - id transactionID - attempt int32 - calls int32 - h Handler - start time.Time - rto time.Duration - raw []byte -} - -func (t *clientTransaction) handle(e Event) { - if atomic.AddInt32(&t.calls, 1) == 1 { - t.h(e) - } -} - -var clientTransactionPool = &sync.Pool{ //nolint:gochecknoglobals - New: func() interface{} { - return &clientTransaction{ - raw: make([]byte, 1500), - } - }, -} - -func acquireClientTransaction() *clientTransaction { - return clientTransactionPool.Get().(*clientTransaction) //nolint:forcetypeassert -} - -func putClientTransaction(t *clientTransaction) { - t.raw = t.raw[:0] - t.start = time.Time{} - t.attempt = 0 - t.id = transactionID{} - clientTransactionPool.Put(t) -} - -func (t *clientTransaction) nextTimeout(now time.Time) time.Time { - return now.Add(time.Duration(t.attempt+1) * t.rto) -} - -// start registers transaction. -// -// Could return ErrClientClosed, ErrTransactionExists. -func (c *Client) start(t *clientTransaction) error { - c.mux.Lock() - defer c.mux.Unlock() - if c.closed { - return ErrClientClosed - } - _, exists := c.t[t.id] - if exists { - return ErrTransactionExists - } - c.t[t.id] = t - return nil -} - -// Clock abstracts the source of current time. -type Clock interface { - Now() time.Time -} - -type systemClockService struct{} - -func (systemClockService) Now() time.Time { return time.Now() } - -func systemClock() systemClockService { - return systemClockService{} -} - -// SetRTO sets current RTO value. -func (c *Client) SetRTO(rto time.Duration) { - atomic.StoreInt64(&c.rto, int64(rto)) -} - -// StopErr occurs when Client fails to stop transaction while -// processing error. -// -//nolint:errname -type StopErr struct { - Err error // value returned by Stop() - Cause error // error that caused Stop() call -} - -func (e StopErr) Error() string { - return fmt.Sprintf("error while stopping due to %s: %s", sprintErr(e.Cause), sprintErr(e.Err)) -} - -// CloseErr indicates client close failure. -// -//nolint:errname -type CloseErr struct { - AgentErr error - ConnectionErr error -} - -func sprintErr(err error) string { - if err == nil { - return "" //nolint:goconst - } - return err.Error() -} - -func (c CloseErr) Error() string { - return fmt.Sprintf("failed to close: %s (connection), %s (agent)", sprintErr(c.ConnectionErr), sprintErr(c.AgentErr)) -} - -func (c *Client) readUntilClosed() { - defer c.wg.Done() - m := new(Message) - m.Raw = make([]byte, 1024) - for { - select { - case <-c.close: - return - default: - } - _, err := m.ReadFrom(c.c) - if err == nil { - if pErr := c.a.Process(m); errors.Is(pErr, ErrAgentClosed) { - return - } - } - } -} - -func closedOrPanic(err error) { - if err == nil || errors.Is(err, ErrAgentClosed) { - return - } - panic(err) //nolint -} - -type tickerCollector struct { - close chan struct{} - wg sync.WaitGroup - clock Clock -} - -// Collector calls function f with constant rate. -// -// The simple Collector is ticker which calls function on each tick. -type Collector interface { - Start(rate time.Duration, f func(now time.Time)) error - Close() error -} - -func (a *tickerCollector) Start(rate time.Duration, f func(now time.Time)) error { - t := time.NewTicker(rate) - a.wg.Add(1) - go func() { - defer a.wg.Done() - for { - select { - case <-a.close: - t.Stop() - return - case <-t.C: - f(a.clock.Now()) - } - } - }() - return nil -} - -func (a *tickerCollector) Close() error { - close(a.close) - a.wg.Wait() - return nil -} - -// ErrClientClosed indicates that client is closed. -var ErrClientClosed = errors.New("client is closed") - -// Close stops internal connection and agent, returning CloseErr on error. -func (c *Client) Close() error { - if err := c.checkInit(); err != nil { - return err - } - c.mux.Lock() - if c.closed { - c.mux.Unlock() - return ErrClientClosed - } - c.closed = true - c.mux.Unlock() - if closeErr := c.collector.Close(); closeErr != nil { - return closeErr - } - var connErr error - agentErr := c.a.Close() - if c.closeConn { - connErr = c.c.Close() - } - close(c.close) - c.wg.Wait() - if agentErr == nil && connErr == nil { - return nil - } - return CloseErr{ - AgentErr: agentErr, - ConnectionErr: connErr, - } -} - -// Indicate sends indication m to server. Shorthand to Start call -// with zero deadline and callback. -func (c *Client) Indicate(m *Message) error { - return c.Start(m, nil) -} - -// callbackWaitHandler blocks on wait() call until callback is called. -type callbackWaitHandler struct { - handler Handler - callback func(event Event) - cond *sync.Cond - processed bool -} - -func (s *callbackWaitHandler) HandleEvent(e Event) { - s.cond.L.Lock() - if s.callback == nil { - panic("s.callback is nil") //nolint - } - s.callback(e) - s.processed = true - s.cond.Broadcast() - s.cond.L.Unlock() -} - -func (s *callbackWaitHandler) wait() { - s.cond.L.Lock() - for !s.processed { - s.cond.Wait() - } - s.processed = false - s.callback = nil - s.cond.L.Unlock() -} - -func (s *callbackWaitHandler) setCallback(f func(event Event)) { - if f == nil { - panic("f is nil") //nolint - } - s.cond.L.Lock() - s.callback = f - if s.handler == nil { - s.handler = s.HandleEvent - } - s.cond.L.Unlock() -} - -var callbackWaitHandlerPool = sync.Pool{ //nolint:gochecknoglobals - New: func() interface{} { - return &callbackWaitHandler{ - cond: sync.NewCond(new(sync.Mutex)), - } - }, -} - -// ErrClientNotInitialized means that client connection or agent is nil. -var ErrClientNotInitialized = errors.New("client not initialized") - -func (c *Client) checkInit() error { - if c == nil || c.c == nil || c.a == nil || c.close == nil { - return ErrClientNotInitialized - } - return nil -} - -// Do is Start wrapper that waits until callback is called. If no callback -// provided, Indicate is called instead. -// -// Do has cpu overhead due to blocking, see BenchmarkClient_Do. -// Use Start method for less overhead. -func (c *Client) Do(m *Message, f func(Event)) error { - if err := c.checkInit(); err != nil { - return err - } - if f == nil { - return c.Indicate(m) - } - h := callbackWaitHandlerPool.Get().(*callbackWaitHandler) //nolint:forcetypeassert - h.setCallback(f) - defer func() { - callbackWaitHandlerPool.Put(h) - }() - if err := c.Start(m, h.handler); err != nil { - return err - } - h.wait() - return nil -} - -func (c *Client) delete(id transactionID) { - c.mux.Lock() - if c.t != nil { - delete(c.t, id) - } - c.mux.Unlock() -} - -type buffer struct { - buf []byte -} - -var bufferPool = &sync.Pool{ //nolint:gochecknoglobals - New: func() interface{} { - return &buffer{buf: make([]byte, 2048)} - }, -} - -func (c *Client) handleAgentCallback(e Event) { - c.mux.Lock() - if c.closed { - c.mux.Unlock() - return - } - t, found := c.t[e.TransactionID] - if found { - delete(c.t, t.id) - } - c.mux.Unlock() - if !found { - if c.handler != nil && !errors.Is(e.Error, ErrTransactionStopped) { - c.handler(e) - } - // Ignoring. - return - } - if atomic.LoadInt32(&c.maxAttempts) <= t.attempt || e.Error == nil { - // Transaction completed. - t.handle(e) - putClientTransaction(t) - return - } - // Doing re-transmission. - t.attempt++ - b := bufferPool.Get().(*buffer) //nolint:forcetypeassert - b.buf = b.buf[:copy(b.buf[:cap(b.buf)], t.raw)] - defer bufferPool.Put(b) - var ( - now = c.clock.Now() - timeOut = t.nextTimeout(now) - id = t.id - ) - // Starting client transaction. - if startErr := c.start(t); startErr != nil { - c.delete(id) - e.Error = startErr - t.handle(e) - putClientTransaction(t) - return - } - // Starting agent transaction. - if startErr := c.a.Start(id, timeOut); startErr != nil { - c.delete(id) - e.Error = startErr - t.handle(e) - putClientTransaction(t) - return - } - // Writing message to connection again. - _, writeErr := c.c.Write(b.buf) - if writeErr != nil { - c.delete(id) - e.Error = writeErr - // Stopping agent transaction instead of waiting until it's deadline. - // This will call handleAgentCallback with "ErrTransactionStopped" error - // which will be ignored. - if stopErr := c.a.Stop(id); stopErr != nil { - // Failed to stop agent transaction. Wrapping the error in StopError. - e.Error = StopErr{ - Err: stopErr, - Cause: writeErr, - } - } - t.handle(e) - putClientTransaction(t) - return - } -} - -// Start starts transaction (if h set) and writes message to server, handler -// is called asynchronously. -func (c *Client) Start(m *Message, h Handler) error { - if err := c.checkInit(); err != nil { - return err - } - c.mux.RLock() - closed := c.closed - c.mux.RUnlock() - if closed { - return ErrClientClosed - } - if h != nil { - // Starting transaction only if h is set. Useful for indications. - t := acquireClientTransaction() - t.id = m.TransactionID - t.start = c.clock.Now() - t.h = h - t.rto = time.Duration(atomic.LoadInt64(&c.rto)) - t.attempt = 0 - t.raw = append(t.raw[:0], m.Raw...) - t.calls = 0 - d := t.nextTimeout(t.start) - if err := c.start(t); err != nil { - return err - } - if err := c.a.Start(m.TransactionID, d); err != nil { - return err - } - } - _, err := m.WriteTo(c.c) - if err != nil && h != nil { - c.delete(m.TransactionID) - // Stopping transaction instead of waiting until deadline. - if stopErr := c.a.Stop(m.TransactionID); stopErr != nil { - return StopErr{ - Err: stopErr, - Cause: err, - } - } - } - return err -} diff --git a/vendor/github.com/pion/stun/codecov.yml b/vendor/github.com/pion/stun/codecov.yml deleted file mode 100644 index 263e4d45..00000000 --- a/vendor/github.com/pion/stun/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/stun/errorcode.go b/vendor/github.com/pion/stun/errorcode.go deleted file mode 100644 index c852eed6..00000000 --- a/vendor/github.com/pion/stun/errorcode.go +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "errors" - "fmt" - "io" -) - -// ErrorCodeAttribute represents ERROR-CODE attribute. -// -// RFC 5389 Section 15.6 -type ErrorCodeAttribute struct { - Code ErrorCode - Reason []byte -} - -func (c ErrorCodeAttribute) String() string { - return fmt.Sprintf("%d: %s", c.Code, c.Reason) -} - -// constants for ERROR-CODE encoding. -const ( - errorCodeReasonStart = 4 - errorCodeClassByte = 2 - errorCodeNumberByte = 3 - errorCodeReasonMaxB = 763 - errorCodeModulo = 100 -) - -// AddTo adds ERROR-CODE to m. -func (c ErrorCodeAttribute) AddTo(m *Message) error { - value := make([]byte, 0, errorCodeReasonStart+errorCodeReasonMaxB) - if err := CheckOverflow(AttrErrorCode, - len(c.Reason)+errorCodeReasonStart, - errorCodeReasonMaxB+errorCodeReasonStart, - ); err != nil { - return err - } - value = value[:errorCodeReasonStart+len(c.Reason)] - number := byte(c.Code % errorCodeModulo) // error code modulo 100 - class := byte(c.Code / errorCodeModulo) // hundred digit - value[errorCodeClassByte] = class - value[errorCodeNumberByte] = number - copy(value[errorCodeReasonStart:], c.Reason) - m.Add(AttrErrorCode, value) - return nil -} - -// GetFrom decodes ERROR-CODE from m. Reason is valid until m.Raw is valid. -func (c *ErrorCodeAttribute) GetFrom(m *Message) error { - v, err := m.Get(AttrErrorCode) - if err != nil { - return err - } - if len(v) < errorCodeReasonStart { - return io.ErrUnexpectedEOF - } - var ( - class = uint16(v[errorCodeClassByte]) - number = uint16(v[errorCodeNumberByte]) - code = int(class*errorCodeModulo + number) - ) - c.Code = ErrorCode(code) - c.Reason = v[errorCodeReasonStart:] - return nil -} - -// ErrorCode is code for ERROR-CODE attribute. -type ErrorCode int - -// ErrNoDefaultReason means that default reason for provided error code -// is not defined in RFC. -var ErrNoDefaultReason = errors.New("no default reason for ErrorCode") - -// AddTo adds ERROR-CODE with default reason to m. If there -// is no default reason, returns ErrNoDefaultReason. -func (c ErrorCode) AddTo(m *Message) error { - reason := errorReasons[c] - if reason == nil { - return ErrNoDefaultReason - } - a := &ErrorCodeAttribute{ - Code: c, - Reason: reason, - } - return a.AddTo(m) -} - -// Possible error codes. -const ( - CodeTryAlternate ErrorCode = 300 - CodeBadRequest ErrorCode = 400 - CodeUnauthorized ErrorCode = 401 - CodeUnknownAttribute ErrorCode = 420 - CodeStaleNonce ErrorCode = 438 - CodeRoleConflict ErrorCode = 487 - CodeServerError ErrorCode = 500 -) - -// DEPRECATED constants. -const ( - // DEPRECATED, use CodeUnauthorized. - CodeUnauthorised = CodeUnauthorized -) - -// Error codes from RFC 5766. -// -// RFC 5766 Section 15 -const ( - CodeForbidden ErrorCode = 403 // Forbidden - CodeAllocMismatch ErrorCode = 437 // Allocation Mismatch - CodeWrongCredentials ErrorCode = 441 // Wrong Credentials - CodeUnsupportedTransProto ErrorCode = 442 // Unsupported Transport Protocol - CodeAllocQuotaReached ErrorCode = 486 // Allocation Quota Reached - CodeInsufficientCapacity ErrorCode = 508 // Insufficient Capacity -) - -// Error codes from RFC 6062. -// -// RFC 6062 Section 6.3 -const ( - CodeConnAlreadyExists ErrorCode = 446 - CodeConnTimeoutOrFailure ErrorCode = 447 -) - -// Error codes from RFC 6156. -// -// RFC 6156 Section 10.2 -const ( - CodeAddrFamilyNotSupported ErrorCode = 440 // Address Family not Supported - CodePeerAddrFamilyMismatch ErrorCode = 443 // Peer Address Family Mismatch -) - -//nolint:gochecknoglobals -var errorReasons = map[ErrorCode][]byte{ - CodeTryAlternate: []byte("Try Alternate"), - CodeBadRequest: []byte("Bad Request"), - CodeUnauthorized: []byte("Unauthorized"), - CodeUnknownAttribute: []byte("Unknown Attribute"), - CodeStaleNonce: []byte("Stale Nonce"), - CodeServerError: []byte("Server Error"), - CodeRoleConflict: []byte("Role Conflict"), - - // RFC 5766. - CodeForbidden: []byte("Forbidden"), - CodeAllocMismatch: []byte("Allocation Mismatch"), - CodeWrongCredentials: []byte("Wrong Credentials"), - CodeUnsupportedTransProto: []byte("Unsupported Transport Protocol"), - CodeAllocQuotaReached: []byte("Allocation Quota Reached"), - CodeInsufficientCapacity: []byte("Insufficient Capacity"), - - // RFC 6062. - CodeConnAlreadyExists: []byte("Connection Already Exists"), - CodeConnTimeoutOrFailure: []byte("Connection Timeout or Failure"), - - // RFC 6156. - CodeAddrFamilyNotSupported: []byte("Address Family not Supported"), - CodePeerAddrFamilyMismatch: []byte("Peer Address Family Mismatch"), -} diff --git a/vendor/github.com/pion/stun/errors.go b/vendor/github.com/pion/stun/errors.go deleted file mode 100644 index d5f59edd..00000000 --- a/vendor/github.com/pion/stun/errors.go +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import "errors" - -// DecodeErr records an error and place when it is occurred. -// -//nolint:errname -type DecodeErr struct { - Place DecodeErrPlace - Message string -} - -// IsInvalidCookie returns true if error means that magic cookie -// value is invalid. -func (e DecodeErr) IsInvalidCookie() bool { - return e.Place == DecodeErrPlace{"message", "cookie"} -} - -// IsPlaceParent reports if error place parent is p. -func (e DecodeErr) IsPlaceParent(p string) bool { - return e.Place.Parent == p -} - -// IsPlaceChildren reports if error place children is c. -func (e DecodeErr) IsPlaceChildren(c string) bool { - return e.Place.Children == c -} - -// IsPlace reports if error place is p. -func (e DecodeErr) IsPlace(p DecodeErrPlace) bool { - return e.Place == p -} - -// DecodeErrPlace records a place where error is occurred. -type DecodeErrPlace struct { - Parent string - Children string -} - -func (p DecodeErrPlace) String() string { - return p.Parent + "/" + p.Children -} - -func (e DecodeErr) Error() string { - return "BadFormat for " + e.Place.String() + ": " + e.Message -} - -func newDecodeErr(parent, children, message string) *DecodeErr { - return &DecodeErr{ - Place: DecodeErrPlace{Parent: parent, Children: children}, - Message: message, - } -} - -func newAttrDecodeErr(children, message string) *DecodeErr { - return newDecodeErr("attribute", children, message) -} - -// ErrAttributeSizeInvalid means that decoded attribute size is invalid. -var ErrAttributeSizeInvalid = errors.New("attribute size is invalid") - -// ErrAttributeSizeOverflow means that decoded attribute size is too big. -var ErrAttributeSizeOverflow = errors.New("attribute size overflow") diff --git a/vendor/github.com/pion/stun/fingerprint.go b/vendor/github.com/pion/stun/fingerprint.go deleted file mode 100644 index b4126d26..00000000 --- a/vendor/github.com/pion/stun/fingerprint.go +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "errors" - "hash/crc32" -) - -// FingerprintAttr represents FINGERPRINT attribute. -// -// RFC 5389 Section 15.5 -type FingerprintAttr struct{} - -// ErrFingerprintMismatch means that computed fingerprint differs from expected. -var ErrFingerprintMismatch = errors.New("fingerprint check failed") - -// Fingerprint is shorthand for FingerprintAttr. -// -// Example: -// -// m := New() -// Fingerprint.AddTo(m) -var Fingerprint FingerprintAttr //nolint:gochecknoglobals - -const ( - fingerprintXORValue uint32 = 0x5354554e //nolint:staticcheck - fingerprintSize = 4 // 32 bit -) - -// FingerprintValue returns CRC-32 of b XOR-ed by 0x5354554e. -// -// The value of the attribute is computed as the CRC-32 of the STUN message -// up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with -// the 32-bit value 0x5354554e (the XOR helps in cases where an -// application packet is also using CRC-32 in it). -func FingerprintValue(b []byte) uint32 { - return crc32.ChecksumIEEE(b) ^ fingerprintXORValue // XOR -} - -// AddTo adds fingerprint to message. -func (FingerprintAttr) AddTo(m *Message) error { - l := m.Length - // length in header should include size of fingerprint attribute - m.Length += fingerprintSize + attributeHeaderSize // increasing length - m.WriteLength() // writing Length to Raw - b := make([]byte, fingerprintSize) - val := FingerprintValue(m.Raw) - bin.PutUint32(b, val) - m.Length = l - m.Add(AttrFingerprint, b) - return nil -} - -// Check reads fingerprint value from m and checks it, returning error if any. -// Can return *AttrLengthErr, ErrAttributeNotFound, and *CRCMismatch. -func (FingerprintAttr) Check(m *Message) error { - b, err := m.Get(AttrFingerprint) - if err != nil { - return err - } - if err = CheckSize(AttrFingerprint, len(b), fingerprintSize); err != nil { - return err - } - val := bin.Uint32(b) - attrStart := len(m.Raw) - (fingerprintSize + attributeHeaderSize) - expected := FingerprintValue(m.Raw[:attrStart]) - return checkFingerprint(val, expected) -} diff --git a/vendor/github.com/pion/stun/fingerprint_debug.go b/vendor/github.com/pion/stun/fingerprint_debug.go deleted file mode 100644 index 0e3471db..00000000 --- a/vendor/github.com/pion/stun/fingerprint_debug.go +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build debug -// +build debug - -package stun - -import "fmt" - -// CRCMismatch represents CRC check error. -type CRCMismatch struct { - Expected uint32 - Actual uint32 -} - -func (m CRCMismatch) Error() string { - return fmt.Sprintf("CRC mismatch: %x (expected) != %x (actual)", - m.Expected, - m.Actual, - ) -} diff --git a/vendor/github.com/pion/stun/helpers.go b/vendor/github.com/pion/stun/helpers.go deleted file mode 100644 index d4056503..00000000 --- a/vendor/github.com/pion/stun/helpers.go +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -// Interfaces that are implemented by message attributes, shorthands for them, -// or helpers for message fields as type or transaction id. -type ( - // Setter sets *Message attribute. - Setter interface { - AddTo(m *Message) error - } - // Getter parses attribute from *Message. - Getter interface { - GetFrom(m *Message) error - } - // Checker checks *Message attribute. - Checker interface { - Check(m *Message) error - } -) - -// Build resets message and applies setters to it in batch, returning on -// first error. To prevent allocations, pass pointers to values. -// -// Example: -// -// var ( -// t = BindingRequest -// username = NewUsername("username") -// nonce = NewNonce("nonce") -// realm = NewRealm("example.org") -// ) -// m := new(Message) -// m.Build(t, username, nonce, realm) // 4 allocations -// m.Build(&t, &username, &nonce, &realm) // 0 allocations -// -// See BenchmarkBuildOverhead. -func (m *Message) Build(setters ...Setter) error { - m.Reset() - m.WriteHeader() - for _, s := range setters { - if err := s.AddTo(m); err != nil { - return err - } - } - return nil -} - -// Check applies checkers to message in batch, returning on first error. -func (m *Message) Check(checkers ...Checker) error { - for _, c := range checkers { - if err := c.Check(m); err != nil { - return err - } - } - return nil -} - -// Parse applies getters to message in batch, returning on first error. -func (m *Message) Parse(getters ...Getter) error { - for _, c := range getters { - if err := c.GetFrom(m); err != nil { - return err - } - } - return nil -} - -// MustBuild wraps Build call and panics on error. -func MustBuild(setters ...Setter) *Message { - m, err := Build(setters...) - if err != nil { - panic(err) //nolint - } - return m -} - -// Build wraps Message.Build method. -func Build(setters ...Setter) (*Message, error) { - m := new(Message) - if err := m.Build(setters...); err != nil { - return nil, err - } - return m, nil -} - -// ForEach is helper that iterates over message attributes allowing to call -// Getter in f callback to get all attributes of type t and returning on first -// f error. -// -// The m.Get method inside f will be returning next attribute on each f call. -// Does not error if there are no results. -func (m *Message) ForEach(t AttrType, f func(m *Message) error) error { - attrs := m.Attributes - defer func() { - m.Attributes = attrs - }() - for i, a := range attrs { - if a.Type != t { - continue - } - m.Attributes = attrs[i:] - if err := f(m); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/pion/stun/integrity.go b/vendor/github.com/pion/stun/integrity.go deleted file mode 100644 index 0fee0b07..00000000 --- a/vendor/github.com/pion/stun/integrity.go +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( //nolint:gci - "crypto/md5" //nolint:gosec - "crypto/sha1" //nolint:gosec - "errors" - "fmt" - "strings" - - "github.com/pion/stun/internal/hmac" -) - -// separator for credentials. -const credentialsSep = ":" - -// NewLongTermIntegrity returns new MessageIntegrity with key for long-term -// credentials. Password, username, and realm must be SASL-prepared. -func NewLongTermIntegrity(username, realm, password string) MessageIntegrity { - k := strings.Join([]string{username, realm, password}, credentialsSep) - h := md5.New() //nolint:gosec - fmt.Fprint(h, k) - return MessageIntegrity(h.Sum(nil)) -} - -// NewShortTermIntegrity returns new MessageIntegrity with key for short-term -// credentials. Password must be SASL-prepared. -func NewShortTermIntegrity(password string) MessageIntegrity { - return MessageIntegrity(password) -} - -// MessageIntegrity represents MESSAGE-INTEGRITY attribute. -// -// AddTo and Check methods are using zero-allocation version of hmac, see -// newHMAC function and internal/hmac/pool.go. -// -// RFC 5389 Section 15.4 -type MessageIntegrity []byte - -func newHMAC(key, message, buf []byte) []byte { - mac := hmac.AcquireSHA1(key) - writeOrPanic(mac, message) - defer hmac.PutSHA1(mac) - return mac.Sum(buf) -} - -func (i MessageIntegrity) String() string { - return fmt.Sprintf("KEY: 0x%x", []byte(i)) -} - -const messageIntegritySize = 20 - -// ErrFingerprintBeforeIntegrity means that FINGERPRINT attribute is already in -// message, so MESSAGE-INTEGRITY attribute cannot be added. -var ErrFingerprintBeforeIntegrity = errors.New("FINGERPRINT before MESSAGE-INTEGRITY attribute") - -// AddTo adds MESSAGE-INTEGRITY attribute to message. -// -// CPU costly, see BenchmarkMessageIntegrity_AddTo. -func (i MessageIntegrity) AddTo(m *Message) error { - for _, a := range m.Attributes { - // Message should not contain FINGERPRINT attribute - // before MESSAGE-INTEGRITY. - if a.Type == AttrFingerprint { - return ErrFingerprintBeforeIntegrity - } - } - // The text used as input to HMAC is the STUN message, - // including the header, up to and including the attribute preceding the - // MESSAGE-INTEGRITY attribute. - length := m.Length - // Adjusting m.Length to contain MESSAGE-INTEGRITY TLV. - m.Length += messageIntegritySize + attributeHeaderSize - m.WriteLength() // writing length to m.Raw - v := newHMAC(i, m.Raw, m.Raw[len(m.Raw):]) // calculating HMAC for adjusted m.Raw - m.Length = length // changing m.Length back - - // Copy hmac value to temporary variable to protect it from resetting - // while processing m.Add call. - vBuf := make([]byte, sha1.Size) - copy(vBuf, v) - - m.Add(AttrMessageIntegrity, vBuf) - return nil -} - -// ErrIntegrityMismatch means that computed HMAC differs from expected. -var ErrIntegrityMismatch = errors.New("integrity check failed") - -// Check checks MESSAGE-INTEGRITY attribute. -// -// CPU costly, see BenchmarkMessageIntegrity_Check. -func (i MessageIntegrity) Check(m *Message) error { - v, err := m.Get(AttrMessageIntegrity) - if err != nil { - return err - } - - // Adjusting length in header to match m.Raw that was - // used when computing HMAC. - var ( - length = m.Length - afterIntegrity = false - sizeReduced int - ) - for _, a := range m.Attributes { - if afterIntegrity { - sizeReduced += nearestPaddedValueLength(int(a.Length)) - sizeReduced += attributeHeaderSize - } - if a.Type == AttrMessageIntegrity { - afterIntegrity = true - } - } - m.Length -= uint32(sizeReduced) - m.WriteLength() - // startOfHMAC should be first byte of integrity attribute. - startOfHMAC := messageHeaderSize + m.Length - (attributeHeaderSize + messageIntegritySize) - b := m.Raw[:startOfHMAC] // data before integrity attribute - expected := newHMAC(i, b, m.Raw[len(m.Raw):]) - m.Length = length - m.WriteLength() // writing length back - return checkHMAC(v, expected) -} diff --git a/vendor/github.com/pion/stun/integrity_debug.go b/vendor/github.com/pion/stun/integrity_debug.go deleted file mode 100644 index 27fd0e27..00000000 --- a/vendor/github.com/pion/stun/integrity_debug.go +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build debug -// +build debug - -package stun - -import "fmt" - -// IntegrityErr occurs when computed HMAC differs from expected. -type IntegrityErr struct { - Expected []byte - Actual []byte -} - -func (i *IntegrityErr) Error() string { - return fmt.Sprintf( - "Integrity check failed: 0x%x (expected) !- 0x%x (actual)", - i.Expected, i.Actual, - ) -} diff --git a/vendor/github.com/pion/stun/internal/hmac/hmac.go b/vendor/github.com/pion/stun/internal/hmac/hmac.go deleted file mode 100644 index b4db5c99..00000000 --- a/vendor/github.com/pion/stun/internal/hmac/hmac.go +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-FileCopyrightText: 2009 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -/* -Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as -defined in U.S. Federal Information Processing Standards Publication 198. -An HMAC is a cryptographic hash that uses a key to sign a message. -The receiver verifies the hash by recomputing it using the same key. - -Receivers should be careful to use Equal to compare MACs in order to avoid -timing side-channels: - - // ValidMAC reports whether messageMAC is a valid HMAC tag for message. - func ValidMAC(message, messageMAC, key []byte) bool { - mac := hmac.New(sha256.New, key) - mac.Write(message) - expectedMAC := mac.Sum(nil) - return hmac.Equal(messageMAC, expectedMAC) - } -*/ -package hmac - -import ( - "crypto/subtle" - "hash" -) - -// FIPS 198-1: -// https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf - -// key is zero padded to the block size of the hash function -// ipad = 0x36 byte repeated for key length -// opad = 0x5c byte repeated for key length -// hmac = H([key ^ opad] H([key ^ ipad] text)) - -// Marshalable is the combination of encoding.BinaryMarshaler and -// encoding.BinaryUnmarshaler. Their method definitions are repeated here to -// avoid a dependency on the encoding package. -type marshalable interface { - MarshalBinary() ([]byte, error) - UnmarshalBinary([]byte) error -} - -type hmac struct { - opad, ipad []byte - outer, inner hash.Hash - - // If marshaled is true, then opad and ipad do not contain a padded - // copy of the key, but rather the marshaled state of outer/inner after - // opad/ipad has been fed into it. - marshaled bool -} - -func (h *hmac) Sum(in []byte) []byte { - origLen := len(in) - in = h.inner.Sum(in) - - if h.marshaled { - if err := h.outer.(marshalable).UnmarshalBinary(h.opad); err != nil { //nolint:forcetypeassert - panic(err) //nolint - } - } else { - h.outer.Reset() - h.outer.Write(h.opad) //nolint:errcheck,gosec - } - h.outer.Write(in[origLen:]) //nolint:errcheck,gosec - return h.outer.Sum(in[:origLen]) -} - -func (h *hmac) Write(p []byte) (n int, err error) { - return h.inner.Write(p) -} - -func (h *hmac) Size() int { return h.outer.Size() } -func (h *hmac) BlockSize() int { return h.inner.BlockSize() } - -func (h *hmac) Reset() { - if h.marshaled { - if err := h.inner.(marshalable).UnmarshalBinary(h.ipad); err != nil { //nolint:forcetypeassert - panic(err) //nolint - } - return - } - - h.inner.Reset() - h.inner.Write(h.ipad) //nolint:errcheck,gosec - - // If the underlying hash is marshalable, we can save some time by - // saving a copy of the hash state now, and restoring it on future - // calls to Reset and Sum instead of writing ipad/opad every time. - // - // If either hash is unmarshalable for whatever reason, - // it's safe to bail out here. - marshalableInner, innerOK := h.inner.(marshalable) - if !innerOK { - return - } - marshalableOuter, outerOK := h.outer.(marshalable) - if !outerOK { - return - } - - imarshal, err := marshalableInner.MarshalBinary() - if err != nil { - return - } - - h.outer.Reset() - h.outer.Write(h.opad) //nolint:errcheck,gosec - omarshal, err := marshalableOuter.MarshalBinary() - if err != nil { - return - } - - // Marshaling succeeded; save the marshaled state for later - h.ipad = imarshal - h.opad = omarshal - h.marshaled = true -} - -// New returns a new HMAC hash using the given hash.Hash type and key. -// Note that unlike other hash implementations in the standard library, -// the returned Hash does not implement encoding.BinaryMarshaler -// or encoding.BinaryUnmarshaler. -func New(h func() hash.Hash, key []byte) hash.Hash { - hm := new(hmac) - hm.outer = h() - hm.inner = h() - blocksize := hm.inner.BlockSize() - hm.ipad = make([]byte, blocksize) - hm.opad = make([]byte, blocksize) - if len(key) > blocksize { - // If key is too big, hash it. - hm.outer.Write(key) //nolint:errcheck,gosec - key = hm.outer.Sum(nil) - } - copy(hm.ipad, key) - copy(hm.opad, key) - for i := range hm.ipad { - hm.ipad[i] ^= 0x36 - } - for i := range hm.opad { - hm.opad[i] ^= 0x5c - } - hm.inner.Write(hm.ipad) //nolint:errcheck,gosec - - return hm -} - -// Equal compares two MACs for equality without leaking timing information. -func Equal(mac1, mac2 []byte) bool { - // We don't have to be constant time if the lengths of the MACs are - // different as that suggests that a completely different hash function - // was used. - return subtle.ConstantTimeCompare(mac1, mac2) == 1 -} diff --git a/vendor/github.com/pion/stun/internal/hmac/pool.go b/vendor/github.com/pion/stun/internal/hmac/pool.go deleted file mode 100644 index d2ac14af..00000000 --- a/vendor/github.com/pion/stun/internal/hmac/pool.go +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package hmac - -import ( //nolint:gci - "crypto/sha1" //nolint:gosec - "crypto/sha256" - "hash" - "sync" -) - -func (h *hmac) resetTo(key []byte) { - h.outer.Reset() - h.inner.Reset() - blocksize := h.inner.BlockSize() - - // Reset size and zero of ipad and opad. - h.ipad = append(h.ipad[:0], make([]byte, blocksize)...) - h.opad = append(h.opad[:0], make([]byte, blocksize)...) - - if len(key) > blocksize { - // If key is too big, hash it. - h.outer.Write(key) //nolint:errcheck,gosec - key = h.outer.Sum(nil) - } - copy(h.ipad, key) - copy(h.opad, key) - for i := range h.ipad { - h.ipad[i] ^= 0x36 - } - for i := range h.opad { - h.opad[i] ^= 0x5c - } - h.inner.Write(h.ipad) //nolint:errcheck,gosec - - h.marshaled = false -} - -var hmacSHA1Pool = &sync.Pool{ //nolint:gochecknoglobals - New: func() interface{} { - h := New(sha1.New, make([]byte, sha1.BlockSize)) - return h - }, -} - -// AcquireSHA1 returns new HMAC from pool. -func AcquireSHA1(key []byte) hash.Hash { - h := hmacSHA1Pool.Get().(*hmac) //nolint:forcetypeassert - assertHMACSize(h, sha1.Size, sha1.BlockSize) - h.resetTo(key) - return h -} - -// PutSHA1 puts h to pool. -func PutSHA1(h hash.Hash) { - hm := h.(*hmac) //nolint:forcetypeassert - assertHMACSize(hm, sha1.Size, sha1.BlockSize) - hmacSHA1Pool.Put(hm) -} - -var hmacSHA256Pool = &sync.Pool{ //nolint:gochecknoglobals - New: func() interface{} { - h := New(sha256.New, make([]byte, sha256.BlockSize)) - return h - }, -} - -// AcquireSHA256 returns new HMAC from SHA256 pool. -func AcquireSHA256(key []byte) hash.Hash { - h := hmacSHA256Pool.Get().(*hmac) //nolint:forcetypeassert - assertHMACSize(h, sha256.Size, sha256.BlockSize) - h.resetTo(key) - return h -} - -// PutSHA256 puts h to SHA256 pool. -func PutSHA256(h hash.Hash) { - hm := h.(*hmac) //nolint:forcetypeassert - assertHMACSize(hm, sha256.Size, sha256.BlockSize) - hmacSHA256Pool.Put(hm) -} - -// assertHMACSize panics if h.size != size or h.blocksize != blocksize. -// -// Put and Acquire functions are internal functions to project, so -// checking it via such assert is optimal. -func assertHMACSize(h *hmac, size, blocksize int) { //nolint:unparam - if h.Size() != size || h.BlockSize() != blocksize { - panic("BUG: hmac size invalid") //nolint - } -} diff --git a/vendor/github.com/pion/stun/internal/hmac/vendor.sh b/vendor/github.com/pion/stun/internal/hmac/vendor.sh deleted file mode 100644 index 190d2b9b..00000000 --- a/vendor/github.com/pion/stun/internal/hmac/vendor.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/env bash - -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -cp -v $GOROOT/src/crypto/hmac/{hmac,hmac_test}.go . -git diff {hmac,hmac_test}.go diff --git a/vendor/github.com/pion/stun/message.go b/vendor/github.com/pion/stun/message.go deleted file mode 100644 index 6a828d68..00000000 --- a/vendor/github.com/pion/stun/message.go +++ /dev/null @@ -1,622 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "crypto/rand" - "encoding/base64" - "errors" - "fmt" - "io" -) - -const ( - // magicCookie is fixed value that aids in distinguishing STUN packets - // from packets of other protocols when STUN is multiplexed with those - // other protocols on the same Port. - // - // The magic cookie field MUST contain the fixed value 0x2112A442 in - // network byte order. - // - // Defined in "STUN Message Structure", section 6. - magicCookie = 0x2112A442 - attributeHeaderSize = 4 - messageHeaderSize = 20 - - // TransactionIDSize is length of transaction id array (in bytes). - TransactionIDSize = 12 // 96 bit -) - -// NewTransactionID returns new random transaction ID using crypto/rand -// as source. -func NewTransactionID() (b [TransactionIDSize]byte) { - readFullOrPanic(rand.Reader, b[:]) - return b -} - -// IsMessage returns true if b looks like STUN message. -// Useful for multiplexing. IsMessage does not guarantee -// that decoding will be successful. -func IsMessage(b []byte) bool { - return len(b) >= messageHeaderSize && bin.Uint32(b[4:8]) == magicCookie -} - -// New returns *Message with pre-allocated Raw. -func New() *Message { - const defaultRawCapacity = 120 - return &Message{ - Raw: make([]byte, messageHeaderSize, defaultRawCapacity), - } -} - -// ErrDecodeToNil occurs on Decode(data, nil) call. -var ErrDecodeToNil = errors.New("attempt to decode to nil message") - -// Decode decodes Message from data to m, returning error if any. -func Decode(data []byte, m *Message) error { - if m == nil { - return ErrDecodeToNil - } - m.Raw = append(m.Raw[:0], data...) - return m.Decode() -} - -// Message represents a single STUN packet. It uses aggressive internal -// buffering to enable zero-allocation encoding and decoding, -// so there are some usage constraints: -// -// Message, its fields, results of m.Get or any attribute a.GetFrom -// are valid only until Message.Raw is not modified. -type Message struct { - Type MessageType - Length uint32 // len(Raw) not including header - TransactionID [TransactionIDSize]byte - Attributes Attributes - Raw []byte -} - -// MarshalBinary implements the encoding.BinaryMarshaler interface. -func (m Message) MarshalBinary() (data []byte, err error) { - // We can't return m.Raw, allocation is expected by implicit interface - // contract induced by other implementations. - b := make([]byte, len(m.Raw)) - copy(b, m.Raw) - return b, nil -} - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (m *Message) UnmarshalBinary(data []byte) error { - // We can't retain data, copy is expected by interface contract. - m.Raw = append(m.Raw[:0], data...) - return m.Decode() -} - -// GobEncode implements the gob.GobEncoder interface. -func (m Message) GobEncode() ([]byte, error) { - return m.MarshalBinary() -} - -// GobDecode implements the gob.GobDecoder interface. -func (m *Message) GobDecode(data []byte) error { - return m.UnmarshalBinary(data) -} - -// AddTo sets b.TransactionID to m.TransactionID. -// -// Implements Setter to aid in crafting responses. -func (m *Message) AddTo(b *Message) error { - b.TransactionID = m.TransactionID - b.WriteTransactionID() - return nil -} - -// NewTransactionID sets m.TransactionID to random value from crypto/rand -// and returns error if any. -func (m *Message) NewTransactionID() error { - _, err := io.ReadFull(rand.Reader, m.TransactionID[:]) - if err == nil { - m.WriteTransactionID() - } - return err -} - -func (m *Message) String() string { - tID := base64.StdEncoding.EncodeToString(m.TransactionID[:]) - aInfo := "" - for k, a := range m.Attributes { - aInfo += fmt.Sprintf("attr%d=%s ", k, a.Type) - } - return fmt.Sprintf("%s l=%d attrs=%d id=%s, %s", m.Type, m.Length, len(m.Attributes), tID, aInfo) -} - -// Reset resets Message, attributes and underlying buffer length. -func (m *Message) Reset() { - m.Raw = m.Raw[:0] - m.Length = 0 - m.Attributes = m.Attributes[:0] -} - -// grow ensures that internal buffer has n length. -func (m *Message) grow(n int) { - if len(m.Raw) >= n { - return - } - if cap(m.Raw) >= n { - m.Raw = m.Raw[:n] - return - } - m.Raw = append(m.Raw, make([]byte, n-len(m.Raw))...) -} - -// Add appends new attribute to message. Not goroutine-safe. -// -// Value of attribute is copied to internal buffer so -// it is safe to reuse v. -func (m *Message) Add(t AttrType, v []byte) { - // Allocating buffer for TLV (type-length-value). - // T = t, L = len(v), V = v. - // m.Raw will look like: - // [0:20] <- message header - // [20:20+m.Length] <- existing message attributes - // [20+m.Length:20+m.Length+len(v) + 4] <- allocated buffer for new TLV - // [first:last] <- same as previous - // [0 1|2 3|4 4 + len(v)] <- mapping for allocated buffer - // T L V - allocSize := attributeHeaderSize + len(v) // ~ len(TLV) = len(TL) + len(V) - first := messageHeaderSize + int(m.Length) // first byte number - last := first + allocSize // last byte number - m.grow(last) // growing cap(Raw) to fit TLV - m.Raw = m.Raw[:last] // now len(Raw) = last - m.Length += uint32(allocSize) // rendering length change - - // Sub-slicing internal buffer to simplify encoding. - buf := m.Raw[first:last] // slice for TLV - value := buf[attributeHeaderSize:] // slice for V - attr := RawAttribute{ - Type: t, // T - Length: uint16(len(v)), // L - Value: value, // V - } - - // Encoding attribute TLV to allocated buffer. - bin.PutUint16(buf[0:2], attr.Type.Value()) // T - bin.PutUint16(buf[2:4], attr.Length) // L - copy(value, v) // V - - // Checking that attribute value needs padding. - if attr.Length%padding != 0 { - // Performing padding. - bytesToAdd := nearestPaddedValueLength(len(v)) - len(v) - last += bytesToAdd - m.grow(last) - // setting all padding bytes to zero - // to prevent data leak from previous - // data in next bytesToAdd bytes - buf = m.Raw[last-bytesToAdd : last] - for i := range buf { - buf[i] = 0 - } - m.Raw = m.Raw[:last] // increasing buffer length - m.Length += uint32(bytesToAdd) // rendering length change - } - m.Attributes = append(m.Attributes, attr) - m.WriteLength() -} - -func attrSliceEqual(a, b Attributes) bool { - for _, attr := range a { - found := false - for _, attrB := range b { - if attrB.Type != attr.Type { - continue - } - if attrB.Equal(attr) { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func attrEqual(a, b Attributes) bool { - if a == nil && b == nil { - return true - } - if a == nil || b == nil { - return false - } - if len(a) != len(b) { - return false - } - if !attrSliceEqual(a, b) { - return false - } - if !attrSliceEqual(b, a) { - return false - } - return true -} - -// Equal returns true if Message b equals to m. -// Ignores m.Raw. -func (m *Message) Equal(b *Message) bool { - if m == nil && b == nil { - return true - } - if m == nil || b == nil { - return false - } - if m.Type != b.Type { - return false - } - if m.TransactionID != b.TransactionID { - return false - } - if m.Length != b.Length { - return false - } - if !attrEqual(m.Attributes, b.Attributes) { - return false - } - return true -} - -// WriteLength writes m.Length to m.Raw. -func (m *Message) WriteLength() { - m.grow(4) - bin.PutUint16(m.Raw[2:4], uint16(m.Length)) -} - -// WriteHeader writes header to underlying buffer. Not goroutine-safe. -func (m *Message) WriteHeader() { - m.grow(messageHeaderSize) - _ = m.Raw[:messageHeaderSize] // early bounds check to guarantee safety of writes below - - m.WriteType() - m.WriteLength() - bin.PutUint32(m.Raw[4:8], magicCookie) // magic cookie - copy(m.Raw[8:messageHeaderSize], m.TransactionID[:]) // transaction ID -} - -// WriteTransactionID writes m.TransactionID to m.Raw. -func (m *Message) WriteTransactionID() { - copy(m.Raw[8:messageHeaderSize], m.TransactionID[:]) // transaction ID -} - -// WriteAttributes encodes all m.Attributes to m. -func (m *Message) WriteAttributes() { - attributes := m.Attributes - m.Attributes = attributes[:0] - for _, a := range attributes { - m.Add(a.Type, a.Value) - } - m.Attributes = attributes -} - -// WriteType writes m.Type to m.Raw. -func (m *Message) WriteType() { - m.grow(2) - bin.PutUint16(m.Raw[0:2], m.Type.Value()) // message type -} - -// SetType sets m.Type and writes it to m.Raw. -func (m *Message) SetType(t MessageType) { - m.Type = t - m.WriteType() -} - -// Encode re-encodes message into m.Raw. -func (m *Message) Encode() { - m.Raw = m.Raw[:0] - m.WriteHeader() - m.Length = 0 - m.WriteAttributes() -} - -// WriteTo implements WriterTo via calling Write(m.Raw) on w and returning -// call result. -func (m *Message) WriteTo(w io.Writer) (int64, error) { - n, err := w.Write(m.Raw) - return int64(n), err -} - -// ReadFrom implements ReaderFrom. Reads message from r into m.Raw, -// Decodes it and return error if any. If m.Raw is too small, will return -// ErrUnexpectedEOF, ErrUnexpectedHeaderEOF or *DecodeErr. -// -// Can return *DecodeErr while decoding too. -func (m *Message) ReadFrom(r io.Reader) (int64, error) { - tBuf := m.Raw[:cap(m.Raw)] - var ( - n int - err error - ) - if n, err = r.Read(tBuf); err != nil { - return int64(n), err - } - m.Raw = tBuf[:n] - return int64(n), m.Decode() -} - -// ErrUnexpectedHeaderEOF means that there were not enough bytes in -// m.Raw to read header. -var ErrUnexpectedHeaderEOF = errors.New("unexpected EOF: not enough bytes to read header") - -// Decode decodes m.Raw into m. -func (m *Message) Decode() error { - // decoding message header - buf := m.Raw - if len(buf) < messageHeaderSize { - return ErrUnexpectedHeaderEOF - } - var ( - t = bin.Uint16(buf[0:2]) // first 2 bytes - size = int(bin.Uint16(buf[2:4])) // second 2 bytes - cookie = bin.Uint32(buf[4:8]) // last 4 bytes - fullSize = messageHeaderSize + size // len(m.Raw) - ) - if cookie != magicCookie { - msg := fmt.Sprintf("%x is invalid magic cookie (should be %x)", cookie, magicCookie) - return newDecodeErr("message", "cookie", msg) - } - if len(buf) < fullSize { - msg := fmt.Sprintf("buffer length %d is less than %d (expected message size)", len(buf), fullSize) - return newAttrDecodeErr("message", msg) - } - // saving header data - m.Type.ReadValue(t) - m.Length = uint32(size) - copy(m.TransactionID[:], buf[8:messageHeaderSize]) - - m.Attributes = m.Attributes[:0] - var ( - offset = 0 - b = buf[messageHeaderSize:fullSize] - ) - for offset < size { - // checking that we have enough bytes to read header - if len(b) < attributeHeaderSize { - msg := fmt.Sprintf("buffer length %d is less than %d (expected header size)", len(b), attributeHeaderSize) - return newAttrDecodeErr("header", msg) - } - var ( - a = RawAttribute{ - Type: compatAttrType(bin.Uint16(b[0:2])), // first 2 bytes - Length: bin.Uint16(b[2:4]), // second 2 bytes - } - aL = int(a.Length) // attribute length - aBuffL = nearestPaddedValueLength(aL) // expected buffer length (with padding) - ) - b = b[attributeHeaderSize:] // slicing again to simplify value read - offset += attributeHeaderSize - if len(b) < aBuffL { // checking size - msg := fmt.Sprintf("buffer length %d is less than %d (expected value size for %s)", len(b), aBuffL, a.Type) - return newAttrDecodeErr("value", msg) - } - a.Value = b[:aL] - offset += aBuffL - b = b[aBuffL:] - - m.Attributes = append(m.Attributes, a) - } - return nil -} - -// Write decodes message and return error if any. -// -// Any error is unrecoverable, but message could be partially decoded. -func (m *Message) Write(tBuf []byte) (int, error) { - m.Raw = append(m.Raw[:0], tBuf...) - return len(tBuf), m.Decode() -} - -// CloneTo clones m to b securing any further m mutations. -func (m *Message) CloneTo(b *Message) error { - b.Raw = append(b.Raw[:0], m.Raw...) - return b.Decode() -} - -// MessageClass is 8-bit representation of 2-bit class of STUN Message Class. -type MessageClass byte - -// Possible values for message class in STUN Message Type. -const ( - ClassRequest MessageClass = 0x00 // 0b00 - ClassIndication MessageClass = 0x01 // 0b01 - ClassSuccessResponse MessageClass = 0x02 // 0b10 - ClassErrorResponse MessageClass = 0x03 // 0b11 -) - -// Common STUN message types. -var ( - // Binding request message type. - BindingRequest = NewType(MethodBinding, ClassRequest) //nolint:gochecknoglobals - // Binding success response message type - BindingSuccess = NewType(MethodBinding, ClassSuccessResponse) //nolint:gochecknoglobals - // Binding error response message type. - BindingError = NewType(MethodBinding, ClassErrorResponse) //nolint:gochecknoglobals -) - -func (c MessageClass) String() string { - switch c { - case ClassRequest: - return "request" - case ClassIndication: - return "indication" - case ClassSuccessResponse: - return "success response" - case ClassErrorResponse: - return "error response" - default: - panic("unknown message class") //nolint - } -} - -// Method is uint16 representation of 12-bit STUN method. -type Method uint16 - -// Possible methods for STUN Message. -const ( - MethodBinding Method = 0x001 - MethodAllocate Method = 0x003 - MethodRefresh Method = 0x004 - MethodSend Method = 0x006 - MethodData Method = 0x007 - MethodCreatePermission Method = 0x008 - MethodChannelBind Method = 0x009 -) - -// Methods from RFC 6062. -const ( - MethodConnect Method = 0x000a - MethodConnectionBind Method = 0x000b - MethodConnectionAttempt Method = 0x000c -) - -func methodName() map[Method]string { - return map[Method]string{ - MethodBinding: "Binding", - MethodAllocate: "Allocate", - MethodRefresh: "Refresh", - MethodSend: "Send", - MethodData: "Data", - MethodCreatePermission: "CreatePermission", - MethodChannelBind: "ChannelBind", - - // RFC 6062. - MethodConnect: "Connect", - MethodConnectionBind: "ConnectionBind", - MethodConnectionAttempt: "ConnectionAttempt", - } -} - -func (m Method) String() string { - s, ok := methodName()[m] - if !ok { - // Falling back to hex representation. - s = fmt.Sprintf("0x%x", uint16(m)) - } - return s -} - -// MessageType is STUN Message Type Field. -type MessageType struct { - Method Method // e.g. binding - Class MessageClass // e.g. request -} - -// AddTo sets m type to t. -func (t MessageType) AddTo(m *Message) error { - m.SetType(t) - return nil -} - -// NewType returns new message type with provided method and class. -func NewType(method Method, class MessageClass) MessageType { - return MessageType{ - Method: method, - Class: class, - } -} - -const ( - methodABits = 0xf // 0b0000000000001111 - methodBBits = 0x70 // 0b0000000001110000 - methodDBits = 0xf80 // 0b0000111110000000 - - methodBShift = 1 - methodDShift = 2 - - firstBit = 0x1 - secondBit = 0x2 - - c0Bit = firstBit - c1Bit = secondBit - - classC0Shift = 4 - classC1Shift = 7 -) - -// Value returns bit representation of messageType. -func (t MessageType) Value() uint16 { - // 0 1 - // 2 3 4 5 6 7 8 9 0 1 2 3 4 5 - // +--+--+-+-+-+-+-+-+-+-+-+-+-+-+ - // |M |M |M|M|M|C|M|M|M|C|M|M|M|M| - // |11|10|9|8|7|1|6|5|4|0|3|2|1|0| - // +--+--+-+-+-+-+-+-+-+-+-+-+-+-+ - // Figure 3: Format of STUN Message Type Field - - // Warning: Abandon all hope ye who enter here. - // Splitting M into A(M0-M3), B(M4-M6), D(M7-M11). - m := uint16(t.Method) - a := m & methodABits // A = M * 0b0000000000001111 (right 4 bits) - b := m & methodBBits // B = M * 0b0000000001110000 (3 bits after A) - d := m & methodDBits // D = M * 0b0000111110000000 (5 bits after B) - - // Shifting to add "holes" for C0 (at 4 bit) and C1 (8 bit). - m = a + (b << methodBShift) + (d << methodDShift) - - // C0 is zero bit of C, C1 is first bit. - // C0 = C * 0b01, C1 = (C * 0b10) >> 1 - // Ct = C0 << 4 + C1 << 8. - // Optimizations: "((C * 0b10) >> 1) << 8" as "(C * 0b10) << 7" - // We need C0 shifted by 4, and C1 by 8 to fit "11" and "7" positions - // (see figure 3). - c := uint16(t.Class) - c0 := (c & c0Bit) << classC0Shift - c1 := (c & c1Bit) << classC1Shift - class := c0 + c1 - - return m + class -} - -// ReadValue decodes uint16 into MessageType. -func (t *MessageType) ReadValue(v uint16) { - // Decoding class. - // We are taking first bit from v >> 4 and second from v >> 7. - c0 := (v >> classC0Shift) & c0Bit - c1 := (v >> classC1Shift) & c1Bit - class := c0 + c1 - t.Class = MessageClass(class) - - // Decoding method. - a := v & methodABits // A(M0-M3) - b := (v >> methodBShift) & methodBBits // B(M4-M6) - d := (v >> methodDShift) & methodDBits // D(M7-M11) - m := a + b + d - t.Method = Method(m) -} - -func (t MessageType) String() string { - return fmt.Sprintf("%s %s", t.Method, t.Class) -} - -// Contains return true if message contain t attribute. -func (m *Message) Contains(t AttrType) bool { - for _, a := range m.Attributes { - if a.Type == t { - return true - } - } - return false -} - -type transactionIDValueSetter [TransactionIDSize]byte - -// NewTransactionIDSetter returns new Setter that sets message transaction id -// to provided value. -func NewTransactionIDSetter(value [TransactionIDSize]byte) Setter { - return transactionIDValueSetter(value) -} - -func (t transactionIDValueSetter) AddTo(m *Message) error { - m.TransactionID = t - m.WriteTransactionID() - return nil -} diff --git a/vendor/github.com/pion/stun/renovate.json b/vendor/github.com/pion/stun/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/stun/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/stun/stun.go b/vendor/github.com/pion/stun/stun.go deleted file mode 100644 index 3a7954fd..00000000 --- a/vendor/github.com/pion/stun/stun.go +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package stun implements Session Traversal Utilities for NAT (STUN) RFC 5389. -// -// The stun package is intended to use by package that implements extension -// to STUN (e.g. TURN) or client/server applications. -// -// Most methods are designed to be zero allocations. If it is not enough, -// low-level methods are available. On other hand, there are helpers that -// reduce code repeat. -// -// See examples for Message for basic usage, or https://github.com/pion/turn -// package for example of stun extension implementation. -package stun - -import ( - "encoding/binary" - "io" -) - -// bin is shorthand to binary.BigEndian. -var bin = binary.BigEndian //nolint:gochecknoglobals - -func readFullOrPanic(r io.Reader, v []byte) int { - n, err := io.ReadFull(r, v) - if err != nil { - panic(err) //nolint - } - return n -} - -func writeOrPanic(w io.Writer, v []byte) int { - n, err := w.Write(v) - if err != nil { - panic(err) //nolint - } - return n -} - -// IANA assigned ports for "stun" protocol. -const ( - DefaultPort = 3478 - DefaultTLSPort = 5349 -) - -type transactionIDSetter struct{} - -func (transactionIDSetter) AddTo(m *Message) error { - return m.NewTransactionID() -} - -// TransactionID is Setter for m.TransactionID. -var TransactionID Setter = transactionIDSetter{} //nolint:gochecknoglobals diff --git a/vendor/github.com/pion/stun/textattrs.go b/vendor/github.com/pion/stun/textattrs.go deleted file mode 100644 index a98915a6..00000000 --- a/vendor/github.com/pion/stun/textattrs.go +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -// NewUsername returns Username with provided value. -func NewUsername(username string) Username { - return Username(username) -} - -// Username represents USERNAME attribute. -// -// RFC 5389 Section 15.3 -type Username []byte - -func (u Username) String() string { - return string(u) -} - -const maxUsernameB = 513 - -// AddTo adds USERNAME attribute to message. -func (u Username) AddTo(m *Message) error { - return TextAttribute(u).AddToAs(m, AttrUsername, maxUsernameB) -} - -// GetFrom gets USERNAME from message. -func (u *Username) GetFrom(m *Message) error { - return (*TextAttribute)(u).GetFromAs(m, AttrUsername) -} - -// NewRealm returns Realm with provided value. -// Must be SASL-prepared. -func NewRealm(realm string) Realm { - return Realm(realm) -} - -// Realm represents REALM attribute. -// -// RFC 5389 Section 15.7 -type Realm []byte - -func (n Realm) String() string { - return string(n) -} - -const maxRealmB = 763 - -// AddTo adds NONCE to message. -func (n Realm) AddTo(m *Message) error { - return TextAttribute(n).AddToAs(m, AttrRealm, maxRealmB) -} - -// GetFrom gets REALM from message. -func (n *Realm) GetFrom(m *Message) error { - return (*TextAttribute)(n).GetFromAs(m, AttrRealm) -} - -const softwareRawMaxB = 763 - -// Software is SOFTWARE attribute. -// -// RFC 5389 Section 15.10 -type Software []byte - -func (s Software) String() string { - return string(s) -} - -// NewSoftware returns *Software from string. -func NewSoftware(software string) Software { - return Software(software) -} - -// AddTo adds Software attribute to m. -func (s Software) AddTo(m *Message) error { - return TextAttribute(s).AddToAs(m, AttrSoftware, softwareRawMaxB) -} - -// GetFrom decodes Software from m. -func (s *Software) GetFrom(m *Message) error { - return (*TextAttribute)(s).GetFromAs(m, AttrSoftware) -} - -// Nonce represents NONCE attribute. -// -// RFC 5389 Section 15.8 -type Nonce []byte - -// NewNonce returns new Nonce from string. -func NewNonce(nonce string) Nonce { - return Nonce(nonce) -} - -func (n Nonce) String() string { - return string(n) -} - -const maxNonceB = 763 - -// AddTo adds NONCE to message. -func (n Nonce) AddTo(m *Message) error { - return TextAttribute(n).AddToAs(m, AttrNonce, maxNonceB) -} - -// GetFrom gets NONCE from message. -func (n *Nonce) GetFrom(m *Message) error { - return (*TextAttribute)(n).GetFromAs(m, AttrNonce) -} - -// TextAttribute is helper for adding and getting text attributes. -type TextAttribute []byte - -// AddToAs adds attribute with type t to m, checking maximum length. If maxLen -// is less than 0, no check is performed. -func (v TextAttribute) AddToAs(m *Message, t AttrType, maxLen int) error { - if err := CheckOverflow(t, len(v), maxLen); err != nil { - return err - } - m.Add(t, v) - return nil -} - -// GetFromAs gets t attribute from m and appends its value to reseted v. -func (v *TextAttribute) GetFromAs(m *Message, t AttrType) error { - a, err := m.Get(t) - if err != nil { - return err - } - *v = a - return nil -} diff --git a/vendor/github.com/pion/stun/uattrs.go b/vendor/github.com/pion/stun/uattrs.go deleted file mode 100644 index 8b85d8a7..00000000 --- a/vendor/github.com/pion/stun/uattrs.go +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import "errors" - -// UnknownAttributes represents UNKNOWN-ATTRIBUTES attribute. -// -// RFC 5389 Section 15.9 -type UnknownAttributes []AttrType - -func (a UnknownAttributes) String() string { - s := "" - if len(a) == 0 { - return "" - } - last := len(a) - 1 - for i, t := range a { - s += t.String() - if i != last { - s += ", " - } - } - return s -} - -// type size is 16 bit. -const attrTypeSize = 4 - -// AddTo adds UNKNOWN-ATTRIBUTES attribute to message. -func (a UnknownAttributes) AddTo(m *Message) error { - v := make([]byte, 0, attrTypeSize*20) // 20 should be enough - // If len(a.Types) > 20, there will be allocations. - for i, t := range a { - v = append(v, 0, 0, 0, 0) // 4 times by 0 (16 bits) - first := attrTypeSize * i - last := first + attrTypeSize - bin.PutUint16(v[first:last], t.Value()) - } - m.Add(AttrUnknownAttributes, v) - return nil -} - -// ErrBadUnknownAttrsSize means that UNKNOWN-ATTRIBUTES attribute value -// has invalid length. -var ErrBadUnknownAttrsSize = errors.New("bad UNKNOWN-ATTRIBUTES size") - -// GetFrom parses UNKNOWN-ATTRIBUTES from message. -func (a *UnknownAttributes) GetFrom(m *Message) error { - v, err := m.Get(AttrUnknownAttributes) - if err != nil { - return err - } - if len(v)%attrTypeSize != 0 { - return ErrBadUnknownAttrsSize - } - *a = (*a)[:0] - first := 0 - for first < len(v) { - last := first + attrTypeSize - *a = append(*a, AttrType(bin.Uint16(v[first:last]))) - first = last - } - return nil -} diff --git a/vendor/github.com/pion/stun/uri.go b/vendor/github.com/pion/stun/uri.go deleted file mode 100644 index b9dab691..00000000 --- a/vendor/github.com/pion/stun/uri.go +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "errors" - "net" - "net/url" - "strconv" -) - -var ( - // ErrUnknownType indicates an error with Unknown info. - ErrUnknownType = errors.New("Unknown") - - // ErrSchemeType indicates the scheme type could not be parsed. - ErrSchemeType = errors.New("unknown scheme type") - - // ErrSTUNQuery indicates query arguments are provided in a STUN URL. - ErrSTUNQuery = errors.New("queries not supported in stun address") - - // ErrInvalidQuery indicates an malformed query is provided. - ErrInvalidQuery = errors.New("invalid query") - - // ErrHost indicates malformed hostname is provided. - ErrHost = errors.New("invalid hostname") - - // ErrPort indicates malformed port is provided. - ErrPort = errors.New("invalid port") - - // ErrProtoType indicates an unsupported transport type was provided. - ErrProtoType = errors.New("invalid transport protocol type") -) - -// SchemeType indicates the type of server used in the ice.URL structure. -type SchemeType int - -const ( - // SchemeTypeUnknown indicates an unknown or unsupported scheme. - SchemeTypeUnknown SchemeType = iota - - // SchemeTypeSTUN indicates the URL represents a STUN server. - SchemeTypeSTUN - - // SchemeTypeSTUNS indicates the URL represents a STUNS (secure) server. - SchemeTypeSTUNS - - // SchemeTypeTURN indicates the URL represents a TURN server. - SchemeTypeTURN - - // SchemeTypeTURNS indicates the URL represents a TURNS (secure) server. - SchemeTypeTURNS -) - -// NewSchemeType defines a procedure for creating a new SchemeType from a raw -// string naming the scheme type. -func NewSchemeType(raw string) SchemeType { - switch raw { - case "stun": - return SchemeTypeSTUN - case "stuns": - return SchemeTypeSTUNS - case "turn": - return SchemeTypeTURN - case "turns": - return SchemeTypeTURNS - default: - return SchemeTypeUnknown - } -} - -func (t SchemeType) String() string { - switch t { - case SchemeTypeSTUN: - return "stun" - case SchemeTypeSTUNS: - return "stuns" - case SchemeTypeTURN: - return "turn" - case SchemeTypeTURNS: - return "turns" - default: - return ErrUnknownType.Error() - } -} - -// ProtoType indicates the transport protocol type that is used in the ice.URL -// structure. -type ProtoType int - -const ( - // ProtoTypeUnknown indicates an unknown or unsupported protocol. - ProtoTypeUnknown ProtoType = iota - - // ProtoTypeUDP indicates the URL uses a UDP transport. - ProtoTypeUDP - - // ProtoTypeTCP indicates the URL uses a TCP transport. - ProtoTypeTCP -) - -// NewProtoType defines a procedure for creating a new ProtoType from a raw -// string naming the transport protocol type. -func NewProtoType(raw string) ProtoType { - switch raw { - case "udp": - return ProtoTypeUDP - case "tcp": - return ProtoTypeTCP - default: - return ProtoTypeUnknown - } -} - -func (t ProtoType) String() string { - switch t { - case ProtoTypeUDP: - return "udp" - case ProtoTypeTCP: - return "tcp" - default: - return ErrUnknownType.Error() - } -} - -// URI represents a STUN (rfc7064) or TURN (rfc7065) URI -type URI struct { - Scheme SchemeType - Host string - Port int - Username string - Password string - Proto ProtoType -} - -// ParseURI parses a STUN or TURN urls following the ABNF syntax described in -// https://tools.ietf.org/html/rfc7064 and https://tools.ietf.org/html/rfc7065 -// respectively. -func ParseURI(raw string) (*URI, error) { //nolint:gocognit - rawParts, err := url.Parse(raw) - if err != nil { - return nil, err - } - - var u URI - u.Scheme = NewSchemeType(rawParts.Scheme) - if u.Scheme == SchemeTypeUnknown { - return nil, ErrSchemeType - } - - var rawPort string - if u.Host, rawPort, err = net.SplitHostPort(rawParts.Opaque); err != nil { - var e *net.AddrError - if errors.As(err, &e) { - if e.Err == "missing port in address" { - nextRawURL := u.Scheme.String() + ":" + rawParts.Opaque - switch { - case u.Scheme == SchemeTypeSTUN || u.Scheme == SchemeTypeTURN: - nextRawURL += ":3478" - if rawParts.RawQuery != "" { - nextRawURL += "?" + rawParts.RawQuery - } - return ParseURI(nextRawURL) - case u.Scheme == SchemeTypeSTUNS || u.Scheme == SchemeTypeTURNS: - nextRawURL += ":5349" - if rawParts.RawQuery != "" { - nextRawURL += "?" + rawParts.RawQuery - } - return ParseURI(nextRawURL) - } - } - } - return nil, err - } - - if u.Host == "" { - return nil, ErrHost - } - - if u.Port, err = strconv.Atoi(rawPort); err != nil { - return nil, ErrPort - } - - switch u.Scheme { - case SchemeTypeSTUN: - qArgs, err := url.ParseQuery(rawParts.RawQuery) - if err != nil || len(qArgs) > 0 { - return nil, ErrSTUNQuery - } - u.Proto = ProtoTypeUDP - case SchemeTypeSTUNS: - qArgs, err := url.ParseQuery(rawParts.RawQuery) - if err != nil || len(qArgs) > 0 { - return nil, ErrSTUNQuery - } - u.Proto = ProtoTypeTCP - case SchemeTypeTURN: - proto, err := parseProto(rawParts.RawQuery) - if err != nil { - return nil, err - } - - u.Proto = proto - if u.Proto == ProtoTypeUnknown { - u.Proto = ProtoTypeUDP - } - case SchemeTypeTURNS: - proto, err := parseProto(rawParts.RawQuery) - if err != nil { - return nil, err - } - - u.Proto = proto - if u.Proto == ProtoTypeUnknown { - u.Proto = ProtoTypeTCP - } - - case SchemeTypeUnknown: - } - - return &u, nil -} - -func parseProto(raw string) (ProtoType, error) { - qArgs, err := url.ParseQuery(raw) - if err != nil || len(qArgs) > 1 { - return ProtoTypeUnknown, ErrInvalidQuery - } - - var proto ProtoType - if rawProto := qArgs.Get("transport"); rawProto != "" { - if proto = NewProtoType(rawProto); proto == ProtoType(0) { - return ProtoTypeUnknown, ErrProtoType - } - return proto, nil - } - - if len(qArgs) > 0 { - return ProtoTypeUnknown, ErrInvalidQuery - } - - return proto, nil -} - -func (u URI) String() string { - rawURL := u.Scheme.String() + ":" + net.JoinHostPort(u.Host, strconv.Itoa(u.Port)) - if u.Scheme == SchemeTypeTURN || u.Scheme == SchemeTypeTURNS { - rawURL += "?transport=" + u.Proto.String() - } - return rawURL -} - -// IsSecure returns whether the this URL's scheme describes secure scheme or not. -func (u URI) IsSecure() bool { - return u.Scheme == SchemeTypeSTUNS || u.Scheme == SchemeTypeTURNS -} diff --git a/vendor/github.com/pion/stun/xoraddr.go b/vendor/github.com/pion/stun/xoraddr.go deleted file mode 100644 index fc423be8..00000000 --- a/vendor/github.com/pion/stun/xoraddr.go +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package stun - -import ( - "errors" - "fmt" - "io" - "net" - "strconv" - - "github.com/pion/transport/v2/utils/xor" -) - -const ( - familyIPv4 uint16 = 0x01 - familyIPv6 uint16 = 0x02 -) - -// XORMappedAddress implements XOR-MAPPED-ADDRESS attribute. -// -// RFC 5389 Section 15.2 -type XORMappedAddress struct { - IP net.IP - Port int -} - -func (a XORMappedAddress) String() string { - return net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port)) -} - -// isIPv4 returns true if ip with len of net.IPv6Len seems to be ipv4. -func isIPv4(ip net.IP) bool { - // Optimized for performance. Copied from net.IP.To4. - return isZeros(ip[0:10]) && ip[10] == 0xff && ip[11] == 0xff -} - -// Is p all zeros? -func isZeros(p net.IP) bool { - for i := 0; i < len(p); i++ { - if p[i] != 0 { - return false - } - } - return true -} - -// ErrBadIPLength means that len(IP) is not net.{IPv6len,IPv4len}. -var ErrBadIPLength = errors.New("invalid length of IP value") - -// AddToAs adds XOR-MAPPED-ADDRESS value to m as t attribute. -func (a XORMappedAddress) AddToAs(m *Message, t AttrType) error { - var ( - family = familyIPv4 - ip = a.IP - ) - if len(a.IP) == net.IPv6len { - if isIPv4(ip) { - ip = ip[12:16] // like in ip.To4() - } else { - family = familyIPv6 - } - } else if len(ip) != net.IPv4len { - return ErrBadIPLength - } - value := make([]byte, 32+128) - value[0] = 0 // first 8 bits are zeroes - xorValue := make([]byte, net.IPv6len) - copy(xorValue[4:], m.TransactionID[:]) - bin.PutUint32(xorValue[0:4], magicCookie) - bin.PutUint16(value[0:2], family) - bin.PutUint16(value[2:4], uint16(a.Port^magicCookie>>16)) - xor.XorBytes(value[4:4+len(ip)], ip, xorValue) - m.Add(t, value[:4+len(ip)]) - return nil -} - -// AddTo adds XOR-MAPPED-ADDRESS to m. Can return ErrBadIPLength -// if len(a.IP) is invalid. -func (a XORMappedAddress) AddTo(m *Message) error { - return a.AddToAs(m, AttrXORMappedAddress) -} - -// GetFromAs decodes XOR-MAPPED-ADDRESS attribute value in message -// getting it as for t type. -func (a *XORMappedAddress) GetFromAs(m *Message, t AttrType) error { - v, err := m.Get(t) - if err != nil { - return err - } - family := bin.Uint16(v[0:2]) - if family != familyIPv6 && family != familyIPv4 { - return newDecodeErr("xor-mapped address", "family", - fmt.Sprintf("bad value %d", family), - ) - } - ipLen := net.IPv4len - if family == familyIPv6 { - ipLen = net.IPv6len - } - // Ensuring len(a.IP) == ipLen and reusing a.IP. - if len(a.IP) < ipLen { - a.IP = a.IP[:cap(a.IP)] - for len(a.IP) < ipLen { - a.IP = append(a.IP, 0) - } - } - a.IP = a.IP[:ipLen] - for i := range a.IP { - a.IP[i] = 0 - } - if len(v) <= 4 { - return io.ErrUnexpectedEOF - } - if err := CheckOverflow(t, len(v[4:]), len(a.IP)); err != nil { - return err - } - a.Port = int(bin.Uint16(v[2:4])) ^ (magicCookie >> 16) - xorValue := make([]byte, 4+TransactionIDSize) - bin.PutUint32(xorValue[0:4], magicCookie) - copy(xorValue[4:], m.TransactionID[:]) - xor.XorBytes(a.IP, v[4:], xorValue) - return nil -} - -// GetFrom decodes XOR-MAPPED-ADDRESS attribute in message and returns -// error if any. While decoding, a.IP is reused if possible and can be -// rendered to invalid state (e.g. if a.IP was set to IPv6 and then -// IPv4 value were decoded into it), be careful. -// -// Example: -// -// expectedIP := net.ParseIP("213.141.156.236") -// expectedIP.String() // 213.141.156.236, 16 bytes, first 12 of them are zeroes -// expectedPort := 21254 -// addr := &XORMappedAddress{ -// IP: expectedIP, -// Port: expectedPort, -// } -// // addr were added to message that is decoded as newMessage -// // ... -// -// addr.GetFrom(newMessage) -// addr.IP.String() // 213.141.156.236, net.IPv4Len -// expectedIP.String() // d58d:9cec::ffff:d58d:9cec, 16 bytes, first 4 are IPv4 -// // now we have len(expectedIP) = 16 and len(addr.IP) = 4. -func (a *XORMappedAddress) GetFrom(m *Message) error { - return a.GetFromAs(m, AttrXORMappedAddress) -} diff --git a/vendor/github.com/pion/transport/v2/.gitignore b/vendor/github.com/pion/transport/v2/.gitignore deleted file mode 100644 index 6e2f206a..00000000 --- a/vendor/github.com/pion/transport/v2/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/transport/v2/.golangci.yml b/vendor/github.com/pion/transport/v2/.golangci.yml deleted file mode 100644 index 4e3eddf4..00000000 --- a/vendor/github.com/pion/transport/v2/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/transport/v2/.goreleaser.yml b/vendor/github.com/pion/transport/v2/.goreleaser.yml deleted file mode 100644 index 30093e9d..00000000 --- a/vendor/github.com/pion/transport/v2/.goreleaser.yml +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -builds: -- skip: true diff --git a/vendor/github.com/pion/transport/v2/AUTHORS.txt b/vendor/github.com/pion/transport/v2/AUTHORS.txt deleted file mode 100644 index 35bbec39..00000000 --- a/vendor/github.com/pion/transport/v2/AUTHORS.txt +++ /dev/null @@ -1,28 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Adrian Cable -Atsushi Watanabe -backkem -cnderrauber -Hugo Arregui -Jeremiah Millay -Jozef Kralik -Juliusz Chroboczek -Luke Curley -Mathis Engelbart -OrlandoCo -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -Steffen Vogel -Winlin -Woodrow Douglass -Yutaka Takeda -ZHENK - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/transport/v2/LICENSE b/vendor/github.com/pion/transport/v2/LICENSE deleted file mode 100644 index 491caf6b..00000000 --- a/vendor/github.com/pion/transport/v2/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2023 The Pion community - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/pion/transport/v2/README.md b/vendor/github.com/pion/transport/v2/README.md deleted file mode 100644 index b604b104..00000000 --- a/vendor/github.com/pion/transport/v2/README.md +++ /dev/null @@ -1,34 +0,0 @@ -

-
- Pion Transport -
-

-

Transport testing for Pion

-

- Pion transport - Slack Widget -
- GitHub Workflow Status - Go Reference - Coverage Status - Go Report Card - License: MIT -

-
- -### Roadmap -The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones. - -### Community -Pion has an active community on the [Slack](https://pion.ly/slack). - -Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news. - -We are always looking to support **your projects**. Please reach out if you have something to build! -If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) - -### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) - -### License -MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/transport/v2/codecov.yml b/vendor/github.com/pion/transport/v2/codecov.yml deleted file mode 100644 index 263e4d45..00000000 --- a/vendor/github.com/pion/transport/v2/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/transport/v2/connctx/connctx.go b/vendor/github.com/pion/transport/v2/connctx/connctx.go deleted file mode 100644 index 0bdd5950..00000000 --- a/vendor/github.com/pion/transport/v2/connctx/connctx.go +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package connctx wraps net.Conn using context.Context. -package connctx - -import ( - "context" - "errors" - "io" - "net" - "sync" - "sync/atomic" - "time" -) - -// ErrClosing is returned on Write to closed connection. -var ErrClosing = errors.New("use of closed network connection") - -// Reader is an interface for context controlled reader. -type Reader interface { - ReadContext(context.Context, []byte) (int, error) -} - -// Writer is an interface for context controlled writer. -type Writer interface { - WriteContext(context.Context, []byte) (int, error) -} - -// ReadWriter is a composite of ReadWriter. -type ReadWriter interface { - Reader - Writer -} - -// ConnCtx is a wrapper of net.Conn using context.Context. -type ConnCtx interface { - Reader - Writer - io.Closer - LocalAddr() net.Addr - RemoteAddr() net.Addr - Conn() net.Conn -} - -type connCtx struct { - nextConn net.Conn - closed chan struct{} - closeOnce sync.Once - readMu sync.Mutex - writeMu sync.Mutex -} - -var veryOld = time.Unix(0, 1) //nolint:gochecknoglobals - -// New creates a new ConnCtx wrapping given net.Conn. -func New(conn net.Conn) ConnCtx { - c := &connCtx{ - nextConn: conn, - closed: make(chan struct{}), - } - return c -} - -func (c *connCtx) ReadContext(ctx context.Context, b []byte) (int, error) { - c.readMu.Lock() - defer c.readMu.Unlock() - - select { - case <-c.closed: - return 0, io.EOF - default: - } - - done := make(chan struct{}) - var wg sync.WaitGroup - var errSetDeadline atomic.Value - wg.Add(1) - go func() { - defer wg.Done() - select { - case <-ctx.Done(): - // context canceled - if err := c.nextConn.SetReadDeadline(veryOld); err != nil { - errSetDeadline.Store(err) - return - } - <-done - if err := c.nextConn.SetReadDeadline(time.Time{}); err != nil { - errSetDeadline.Store(err) - } - case <-done: - } - }() - - n, err := c.nextConn.Read(b) - - close(done) - wg.Wait() - if e := ctx.Err(); e != nil && n == 0 { - err = e - } - if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil { - err = err2 - } - return n, err -} - -func (c *connCtx) WriteContext(ctx context.Context, b []byte) (int, error) { - c.writeMu.Lock() - defer c.writeMu.Unlock() - - select { - case <-c.closed: - return 0, ErrClosing - default: - } - - done := make(chan struct{}) - var wg sync.WaitGroup - var errSetDeadline atomic.Value - wg.Add(1) - go func() { - defer wg.Done() - select { - case <-ctx.Done(): - // context canceled - if err := c.nextConn.SetWriteDeadline(veryOld); err != nil { - errSetDeadline.Store(err) - return - } - <-done - if err := c.nextConn.SetWriteDeadline(time.Time{}); err != nil { - errSetDeadline.Store(err) - } - case <-done: - } - }() - - n, err := c.nextConn.Write(b) - - close(done) - wg.Wait() - if e := ctx.Err(); e != nil && n == 0 { - err = e - } - if err2, ok := errSetDeadline.Load().(error); ok && err == nil && err2 != nil { - err = err2 - } - return n, err -} - -func (c *connCtx) Close() error { - err := c.nextConn.Close() - c.closeOnce.Do(func() { - c.writeMu.Lock() - c.readMu.Lock() - close(c.closed) - c.readMu.Unlock() - c.writeMu.Unlock() - }) - return err -} - -func (c *connCtx) LocalAddr() net.Addr { - return c.nextConn.LocalAddr() -} - -func (c *connCtx) RemoteAddr() net.Addr { - return c.nextConn.RemoteAddr() -} - -func (c *connCtx) Conn() net.Conn { - return c.nextConn -} diff --git a/vendor/github.com/pion/transport/v2/connctx/pipe.go b/vendor/github.com/pion/transport/v2/connctx/pipe.go deleted file mode 100644 index 96b802e4..00000000 --- a/vendor/github.com/pion/transport/v2/connctx/pipe.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package connctx - -import ( - "net" -) - -// Pipe creates piped pair of ConnCtx. -func Pipe() (ConnCtx, ConnCtx) { - ca, cb := net.Pipe() - return New(ca), New(cb) -} diff --git a/vendor/github.com/pion/transport/v2/deadline/deadline.go b/vendor/github.com/pion/transport/v2/deadline/deadline.go deleted file mode 100644 index abd39f06..00000000 --- a/vendor/github.com/pion/transport/v2/deadline/deadline.go +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package deadline provides deadline timer used to implement -// net.Conn compatible connection -package deadline - -import ( - "context" - "sync" - "time" -) - -// Deadline signals updatable deadline timer. -// Also, it implements context.Context. -type Deadline struct { - exceeded chan struct{} - stop chan struct{} - stopped chan bool - deadline time.Time - mu sync.RWMutex -} - -// New creates new deadline timer. -func New() *Deadline { - d := &Deadline{ - exceeded: make(chan struct{}), - stop: make(chan struct{}), - stopped: make(chan bool, 1), - } - d.stopped <- true - return d -} - -// Set new deadline. Zero value means no deadline. -func (d *Deadline) Set(t time.Time) { - d.mu.Lock() - defer d.mu.Unlock() - - d.deadline = t - - close(d.stop) - - select { - case <-d.exceeded: - d.exceeded = make(chan struct{}) - default: - stopped := <-d.stopped - if !stopped { - d.exceeded = make(chan struct{}) - } - } - d.stop = make(chan struct{}) - d.stopped = make(chan bool, 1) - - if t.IsZero() { - d.stopped <- true - return - } - - if dur := time.Until(t); dur > 0 { - exceeded := d.exceeded - stopped := d.stopped - go func() { - timer := time.NewTimer(dur) - select { - case <-timer.C: - close(exceeded) - stopped <- false - case <-d.stop: - if !timer.Stop() { - <-timer.C - } - stopped <- true - } - }() - return - } - - close(d.exceeded) - d.stopped <- false -} - -// Done receives deadline signal. -func (d *Deadline) Done() <-chan struct{} { - d.mu.RLock() - defer d.mu.RUnlock() - return d.exceeded -} - -// Err returns context.DeadlineExceeded if the deadline is exceeded. -// Otherwise, it returns nil. -func (d *Deadline) Err() error { - d.mu.RLock() - defer d.mu.RUnlock() - select { - case <-d.exceeded: - return context.DeadlineExceeded - default: - return nil - } -} - -// Deadline returns current deadline. -func (d *Deadline) Deadline() (time.Time, bool) { - d.mu.RLock() - defer d.mu.RUnlock() - if d.deadline.IsZero() { - return d.deadline, false - } - return d.deadline, true -} - -// Value returns nil. -func (d *Deadline) Value(interface{}) interface{} { - return nil -} diff --git a/vendor/github.com/pion/transport/v2/net.go b/vendor/github.com/pion/transport/v2/net.go deleted file mode 100644 index 86d3468f..00000000 --- a/vendor/github.com/pion/transport/v2/net.go +++ /dev/null @@ -1,418 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package transport implements various networking related -// functions used throughout the Pion modules. -package transport - -import ( - "errors" - "io" - "net" - "time" -) - -var ( - // ErrNoAddressAssigned ... - ErrNoAddressAssigned = errors.New("no address assigned") - // ErrNotSupported ... - ErrNotSupported = errors.New("not supported yey") - // ErrInterfaceNotFound ... - ErrInterfaceNotFound = errors.New("interface not found") - // ErrNotUDPAddress ... - ErrNotUDPAddress = errors.New("not a UDP address") -) - -// Net is an interface providing common networking functions which are -// similar to the functions provided by standard net package. -type Net interface { - // ListenPacket announces on the local network address. - // - // The network must be "udp", "udp4", "udp6", "unixgram", or an IP - // transport. The IP transports are "ip", "ip4", or "ip6" followed by - // a colon and a literal protocol number or a protocol name, as in - // "ip:1" or "ip:icmp". - // - // For UDP and IP networks, if the host in the address parameter is - // empty or a literal unspecified IP address, ListenPacket listens on - // all available IP addresses of the local system except multicast IP - // addresses. - // To only use IPv4, use network "udp4" or "ip4:proto". - // The address can use a host name, but this is not recommended, - // because it will create a listener for at most one of the host's IP - // addresses. - // If the port in the address parameter is empty or "0", as in - // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen. - // The LocalAddr method of PacketConn can be used to discover the - // chosen port. - // - // See func Dial for a description of the network and address - // parameters. - // - // ListenPacket uses context.Background internally; to specify the context, use - // ListenConfig.ListenPacket. - ListenPacket(network string, address string) (net.PacketConn, error) - - // ListenUDP acts like ListenPacket for UDP networks. - // - // The network must be a UDP network name; see func Dial for details. - // - // If the IP field of laddr is nil or an unspecified IP address, - // ListenUDP listens on all available IP addresses of the local system - // except multicast IP addresses. - // If the Port field of laddr is 0, a port number is automatically - // chosen. - ListenUDP(network string, locAddr *net.UDPAddr) (UDPConn, error) - - // ListenTCP acts like Listen for TCP networks. - // - // The network must be a TCP network name; see func Dial for details. - // - // If the IP field of laddr is nil or an unspecified IP address, - // ListenTCP listens on all available unicast and anycast IP addresses - // of the local system. - // If the Port field of laddr is 0, a port number is automatically - // chosen. - ListenTCP(network string, laddr *net.TCPAddr) (TCPListener, error) - - // Dial connects to the address on the named network. - // - // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), - // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4" - // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and - // "unixpacket". - // - // For TCP and UDP networks, the address has the form "host:port". - // The host must be a literal IP address, or a host name that can be - // resolved to IP addresses. - // The port must be a literal port number or a service name. - // If the host is a literal IPv6 address it must be enclosed in square - // brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80". - // The zone specifies the scope of the literal IPv6 address as defined - // in RFC 4007. - // The functions JoinHostPort and SplitHostPort manipulate a pair of - // host and port in this form. - // When using TCP, and the host resolves to multiple IP addresses, - // Dial will try each IP address in order until one succeeds. - // - // Examples: - // - // Dial("tcp", "golang.org:http") - // Dial("tcp", "192.0.2.1:http") - // Dial("tcp", "198.51.100.1:80") - // Dial("udp", "[2001:db8::1]:domain") - // Dial("udp", "[fe80::1%lo0]:53") - // Dial("tcp", ":80") - // - // For IP networks, the network must be "ip", "ip4" or "ip6" followed - // by a colon and a literal protocol number or a protocol name, and - // the address has the form "host". The host must be a literal IP - // address or a literal IPv6 address with zone. - // It depends on each operating system how the operating system - // behaves with a non-well known protocol number such as "0" or "255". - // - // Examples: - // - // Dial("ip4:1", "192.0.2.1") - // Dial("ip6:ipv6-icmp", "2001:db8::1") - // Dial("ip6:58", "fe80::1%lo0") - // - // For TCP, UDP and IP networks, if the host is empty or a literal - // unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for - // TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is - // assumed. - // - // For Unix networks, the address must be a file system path. - Dial(network, address string) (net.Conn, error) - - // DialUDP acts like Dial for UDP networks. - // - // The network must be a UDP network name; see func Dial for details. - // - // If laddr is nil, a local address is automatically chosen. - // If the IP field of raddr is nil or an unspecified IP address, the - // local system is assumed. - DialUDP(network string, laddr, raddr *net.UDPAddr) (UDPConn, error) - - // DialTCP acts like Dial for TCP networks. - // - // The network must be a TCP network name; see func Dial for details. - // - // If laddr is nil, a local address is automatically chosen. - // If the IP field of raddr is nil or an unspecified IP address, the - // local system is assumed. - DialTCP(network string, laddr, raddr *net.TCPAddr) (TCPConn, error) - - // ResolveIPAddr returns an address of IP end point. - // - // The network must be an IP network name. - // - // If the host in the address parameter is not a literal IP address, - // ResolveIPAddr resolves the address to an address of IP end point. - // Otherwise, it parses the address as a literal IP address. - // The address parameter can use a host name, but this is not - // recommended, because it will return at most one of the host name's - // IP addresses. - // - // See func Dial for a description of the network and address - // parameters. - ResolveIPAddr(network, address string) (*net.IPAddr, error) - - // ResolveUDPAddr returns an address of UDP end point. - // - // The network must be a UDP network name. - // - // If the host in the address parameter is not a literal IP address or - // the port is not a literal port number, ResolveUDPAddr resolves the - // address to an address of UDP end point. - // Otherwise, it parses the address as a pair of literal IP address - // and port number. - // The address parameter can use a host name, but this is not - // recommended, because it will return at most one of the host name's - // IP addresses. - // - // See func Dial for a description of the network and address - // parameters. - ResolveUDPAddr(network, address string) (*net.UDPAddr, error) - - // ResolveTCPAddr returns an address of TCP end point. - // - // The network must be a TCP network name. - // - // If the host in the address parameter is not a literal IP address or - // the port is not a literal port number, ResolveTCPAddr resolves the - // address to an address of TCP end point. - // Otherwise, it parses the address as a pair of literal IP address - // and port number. - // The address parameter can use a host name, but this is not - // recommended, because it will return at most one of the host name's - // IP addresses. - // - // See func Dial for a description of the network and address - // parameters. - ResolveTCPAddr(network, address string) (*net.TCPAddr, error) - - // Interfaces returns a list of the system's network interfaces. - Interfaces() ([]*Interface, error) - - // InterfaceByIndex returns the interface specified by index. - // - // On Solaris, it returns one of the logical network interfaces - // sharing the logical data link; for more precision use - // InterfaceByName. - InterfaceByIndex(index int) (*Interface, error) - - // InterfaceByName returns the interface specified by name. - InterfaceByName(name string) (*Interface, error) - - // The following functions are extensions to Go's standard net package - - CreateDialer(dialer *net.Dialer) Dialer -} - -// Dialer is identical to net.Dialer excepts that its methods -// (Dial, DialContext) are overridden to use the Net interface. -// Use vnet.CreateDialer() to create an instance of this Dialer. -type Dialer interface { - Dial(network, address string) (net.Conn, error) -} - -// UDPConn is packet-oriented connection for UDP. -type UDPConn interface { - // Close closes the connection. - // Any blocked Read or Write operations will be unblocked and return errors. - Close() error - - // LocalAddr returns the local network address, if known. - LocalAddr() net.Addr - - // RemoteAddr returns the remote network address, if known. - RemoteAddr() net.Addr - - // SetDeadline sets the read and write deadlines associated - // with the connection. It is equivalent to calling both - // SetReadDeadline and SetWriteDeadline. - // - // A deadline is an absolute time after which I/O operations - // fail instead of blocking. The deadline applies to all future - // and pending I/O, not just the immediately following call to - // Read or Write. After a deadline has been exceeded, the - // connection can be refreshed by setting a deadline in the future. - // - // If the deadline is exceeded a call to Read or Write or to other - // I/O methods will return an error that wraps os.ErrDeadlineExceeded. - // This can be tested using errors.Is(err, os.ErrDeadlineExceeded). - // The error's Timeout method will return true, but note that there - // are other possible errors for which the Timeout method will - // return true even if the deadline has not been exceeded. - // - // An idle timeout can be implemented by repeatedly extending - // the deadline after successful Read or Write calls. - // - // A zero value for t means I/O operations will not time out. - SetDeadline(t time.Time) error - - // SetReadDeadline sets the deadline for future Read calls - // and any currently-blocked Read call. - // A zero value for t means Read will not time out. - SetReadDeadline(t time.Time) error - - // SetWriteDeadline sets the deadline for future Write calls - // and any currently-blocked Write call. - // Even if write times out, it may return n > 0, indicating that - // some of the data was successfully written. - // A zero value for t means Write will not time out. - SetWriteDeadline(t time.Time) error - - // SetReadBuffer sets the size of the operating system's - // receive buffer associated with the connection. - SetReadBuffer(bytes int) error - - // SetWriteBuffer sets the size of the operating system's - // transmit buffer associated with the connection. - SetWriteBuffer(bytes int) error - - // Read reads data from the connection. - // Read can be made to time out and return an error after a fixed - // time limit; see SetDeadline and SetReadDeadline. - Read(b []byte) (n int, err error) - - // ReadFrom reads a packet from the connection, - // copying the payload into p. It returns the number of - // bytes copied into p and the return address that - // was on the packet. - // It returns the number of bytes read (0 <= n <= len(p)) - // and any error encountered. Callers should always process - // the n > 0 bytes returned before considering the error err. - // ReadFrom can be made to time out and return an error after a - // fixed time limit; see SetDeadline and SetReadDeadline. - ReadFrom(p []byte) (n int, addr net.Addr, err error) - - // ReadFromUDP acts like ReadFrom but returns a UDPAddr. - ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) - - // ReadMsgUDP reads a message from c, copying the payload into b and - // the associated out-of-band data into oob. It returns the number of - // bytes copied into b, the number of bytes copied into oob, the flags - // that were set on the message and the source address of the message. - // - // The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be - // used to manipulate IP-level socket options in oob. - ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) - - // Write writes data to the connection. - // Write can be made to time out and return an error after a fixed - // time limit; see SetDeadline and SetWriteDeadline. - Write(b []byte) (n int, err error) - - // WriteTo writes a packet with payload p to addr. - // WriteTo can be made to time out and return an Error after a - // fixed time limit; see SetDeadline and SetWriteDeadline. - // On packet-oriented connections, write timeouts are rare. - WriteTo(p []byte, addr net.Addr) (n int, err error) - - // WriteToUDP acts like WriteTo but takes a UDPAddr. - WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) - - // WriteMsgUDP writes a message to addr via c if c isn't connected, or - // to c's remote address if c is connected (in which case addr must be - // nil). The payload is copied from b and the associated out-of-band - // data is copied from oob. It returns the number of payload and - // out-of-band bytes written. - // - // The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be - // used to manipulate IP-level socket options in oob. - WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error) -} - -// TCPConn is an interface for TCP network connections. -type TCPConn interface { - net.Conn - - // CloseRead shuts down the reading side of the TCP connection. - // Most callers should just use Close. - CloseRead() error - - // CloseWrite shuts down the writing side of the TCP connection. - // Most callers should just use Close. - CloseWrite() error - - // ReadFrom implements the io.ReaderFrom ReadFrom method. - ReadFrom(r io.Reader) (int64, error) - - // SetLinger sets the behavior of Close on a connection which still - // has data waiting to be sent or to be acknowledged. - // - // If sec < 0 (the default), the operating system finishes sending the - // data in the background. - // - // If sec == 0, the operating system discards any unsent or - // unacknowledged data. - // - // If sec > 0, the data is sent in the background as with sec < 0. On - // some operating systems after sec seconds have elapsed any remaining - // unsent data may be discarded. - SetLinger(sec int) error - - // SetKeepAlive sets whether the operating system should send - // keep-alive messages on the connection. - SetKeepAlive(keepalive bool) error - - // SetKeepAlivePeriod sets period between keep-alives. - SetKeepAlivePeriod(d time.Duration) error - - // SetNoDelay controls whether the operating system should delay - // packet transmission in hopes of sending fewer packets (Nagle's - // algorithm). The default is true (no delay), meaning that data is - // sent as soon as possible after a Write. - SetNoDelay(noDelay bool) error - - // SetWriteBuffer sets the size of the operating system's - // transmit buffer associated with the connection. - SetWriteBuffer(bytes int) error - - // SetReadBuffer sets the size of the operating system's - // receive buffer associated with the connection. - SetReadBuffer(bytes int) error -} - -// TCPListener is a TCP network listener. Clients should typically -// use variables of type Listener instead of assuming TCP. -type TCPListener interface { - net.Listener - - // AcceptTCP accepts the next incoming call and returns the new - // connection. - AcceptTCP() (TCPConn, error) - - // SetDeadline sets the deadline associated with the listener. - // A zero time value disables the deadline. - SetDeadline(t time.Time) error -} - -// Interface wraps a standard net.Interfaces and its assigned addresses -type Interface struct { - net.Interface - addrs []net.Addr -} - -// NewInterface creates a new interface based of a standard net.Interface -func NewInterface(ifc net.Interface) *Interface { - return &Interface{ - Interface: ifc, - addrs: nil, - } -} - -// AddAddress adds a new address to the interface -func (ifc *Interface) AddAddress(addr net.Addr) { - ifc.addrs = append(ifc.addrs, addr) -} - -// Addrs returns a slice of configured addresses on the interface -func (ifc *Interface) Addrs() ([]net.Addr, error) { - if len(ifc.addrs) == 0 { - return nil, ErrNoAddressAssigned - } - return ifc.addrs, nil -} diff --git a/vendor/github.com/pion/transport/v2/packetio/buffer.go b/vendor/github.com/pion/transport/v2/packetio/buffer.go deleted file mode 100644 index 2d46d796..00000000 --- a/vendor/github.com/pion/transport/v2/packetio/buffer.go +++ /dev/null @@ -1,351 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package packetio provides packet buffer -package packetio - -import ( - "errors" - "io" - "sync" - "time" - - "github.com/pion/transport/v2/deadline" -) - -var errPacketTooBig = errors.New("packet too big") - -// BufferPacketType allow the Buffer to know which packet protocol is writing. -type BufferPacketType int - -const ( - // RTPBufferPacket indicates the Buffer that is handling RTP packets - RTPBufferPacket BufferPacketType = 1 - // RTCPBufferPacket indicates the Buffer that is handling RTCP packets - RTCPBufferPacket BufferPacketType = 2 -) - -// Buffer allows writing packets to an intermediate buffer, which can then be read form. -// This is verify similar to bytes.Buffer but avoids combining multiple writes into a single read. -type Buffer struct { - mutex sync.Mutex - - // this is a circular buffer. If head <= tail, then the useful - // data is in the interval [head, tail[. If tail < head, then - // the useful data is the union of [head, len[ and [0, tail[. - // In order to avoid ambiguity when head = tail, we always leave - // an unused byte in the buffer. - data []byte - head, tail int - - notify chan struct{} // non-nil when we have blocked readers - closed bool - - count int - limitCount, limitSize int - - readDeadline *deadline.Deadline -} - -const ( - minSize = 2048 - cutoffSize = 128 * 1024 - maxSize = 4 * 1024 * 1024 -) - -// NewBuffer creates a new Buffer. -func NewBuffer() *Buffer { - return &Buffer{ - readDeadline: deadline.New(), - } -} - -// available returns true if the buffer is large enough to fit a packet -// of the given size, taking overhead into account. -func (b *Buffer) available(size int) bool { - available := b.head - b.tail - if available <= 0 { - available += len(b.data) - } - // we interpret head=tail as empty, so always keep a byte free - if size+2+1 > available { - return false - } - - return true -} - -// grow increases the size of the buffer. If it returns nil, then the -// buffer has been grown. It returns ErrFull if hits a limit. -func (b *Buffer) grow() error { - var newSize int - if len(b.data) < cutoffSize { - newSize = 2 * len(b.data) - } else { - newSize = 5 * len(b.data) / 4 - } - if newSize < minSize { - newSize = minSize - } - if (b.limitSize <= 0 || sizeHardLimit) && newSize > maxSize { - newSize = maxSize - } - - // one byte slack - if b.limitSize > 0 && newSize > b.limitSize+1 { - newSize = b.limitSize + 1 - } - - if newSize <= len(b.data) { - return ErrFull - } - - newData := make([]byte, newSize) - - var n int - if b.head <= b.tail { - // data was contiguous - n = copy(newData, b.data[b.head:b.tail]) - } else { - // data was discontinuous - n = copy(newData, b.data[b.head:]) - n += copy(newData[n:], b.data[:b.tail]) - } - b.head = 0 - b.tail = n - b.data = newData - - return nil -} - -// Write appends a copy of the packet data to the buffer. -// Returns ErrFull if the packet doesn't fit. -// -// Note that the packet size is limited to 65536 bytes since v0.11.0 due to the internal data structure. -func (b *Buffer) Write(packet []byte) (int, error) { - if len(packet) >= 0x10000 { - return 0, errPacketTooBig - } - - b.mutex.Lock() - - if b.closed { - b.mutex.Unlock() - return 0, io.ErrClosedPipe - } - - if (b.limitCount > 0 && b.count >= b.limitCount) || - (b.limitSize > 0 && b.size()+2+len(packet) > b.limitSize) { - b.mutex.Unlock() - return 0, ErrFull - } - - // grow the buffer until the packet fits - for !b.available(len(packet)) { - err := b.grow() - if err != nil { - b.mutex.Unlock() - return 0, err - } - } - - var notify chan struct{} - if b.notify != nil { - // Prepare to notify readers, but only - // actually do it after we release the lock. - notify = b.notify - b.notify = nil - } - - // store the length of the packet - b.data[b.tail] = uint8(len(packet) >> 8) - b.tail++ - if b.tail >= len(b.data) { - b.tail = 0 - } - b.data[b.tail] = uint8(len(packet)) - b.tail++ - if b.tail >= len(b.data) { - b.tail = 0 - } - - // store the packet - n := copy(b.data[b.tail:], packet) - b.tail += n - if b.tail >= len(b.data) { - // we reached the end, wrap around - m := copy(b.data, packet[n:]) - b.tail = m - } - b.count++ - b.mutex.Unlock() - - if notify != nil { - close(notify) - } - - return len(packet), nil -} - -// Read populates the given byte slice, returning the number of bytes read. -// Blocks until data is available or the buffer is closed. -// Returns io.ErrShortBuffer is the packet is too small to copy the Write. -// Returns io.EOF if the buffer is closed. -func (b *Buffer) Read(packet []byte) (n int, err error) { //nolint:gocognit - // Return immediately if the deadline is already exceeded. - select { - case <-b.readDeadline.Done(): - return 0, &netError{ErrTimeout, true, true} - default: - } - - for { - b.mutex.Lock() - - if b.head != b.tail { - // decode the packet size - n1 := b.data[b.head] - b.head++ - if b.head >= len(b.data) { - b.head = 0 - } - n2 := b.data[b.head] - b.head++ - if b.head >= len(b.data) { - b.head = 0 - } - count := int((uint16(n1) << 8) | uint16(n2)) - - // determine the number of bytes we'll actually copy - copied := count - if copied > len(packet) { - copied = len(packet) - } - - // copy the data - if b.head+copied < len(b.data) { - copy(packet, b.data[b.head:b.head+copied]) - } else { - k := copy(packet, b.data[b.head:]) - copy(packet[k:], b.data[:copied-k]) - } - - // advance head, discarding any data that wasn't copied - b.head += count - if b.head >= len(b.data) { - b.head -= len(b.data) - } - - if b.head == b.tail { - // the buffer is empty, reset to beginning - // in order to improve cache locality. - b.head = 0 - b.tail = 0 - } - - b.count-- - - b.mutex.Unlock() - - if copied < count { - return copied, io.ErrShortBuffer - } - return copied, nil - } - - if b.closed { - b.mutex.Unlock() - return 0, io.EOF - } - - if b.notify == nil { - b.notify = make(chan struct{}) - } - notify := b.notify - b.mutex.Unlock() - - select { - case <-b.readDeadline.Done(): - return 0, &netError{ErrTimeout, true, true} - case <-notify: - } - } -} - -// Close the buffer, unblocking any pending reads. -// Data in the buffer can still be read, Read will return io.EOF only when empty. -func (b *Buffer) Close() (err error) { - b.mutex.Lock() - - if b.closed { - b.mutex.Unlock() - return nil - } - - notify := b.notify - b.notify = nil - b.closed = true - - b.mutex.Unlock() - - if notify != nil { - close(notify) - } - - return nil -} - -// Count returns the number of packets in the buffer. -func (b *Buffer) Count() int { - b.mutex.Lock() - defer b.mutex.Unlock() - return b.count -} - -// SetLimitCount controls the maximum number of packets that can be buffered. -// Causes Write to return ErrFull when this limit is reached. -// A zero value will disable this limit. -func (b *Buffer) SetLimitCount(limit int) { - b.mutex.Lock() - defer b.mutex.Unlock() - - b.limitCount = limit -} - -// Size returns the total byte size of packets in the buffer, including -// a small amount of administrative overhead. -func (b *Buffer) Size() int { - b.mutex.Lock() - defer b.mutex.Unlock() - - return b.size() -} - -func (b *Buffer) size() int { - size := b.tail - b.head - if size < 0 { - size += len(b.data) - } - return size -} - -// SetLimitSize controls the maximum number of bytes that can be buffered. -// Causes Write to return ErrFull when this limit is reached. -// A zero value means 4MB since v0.11.0. -// -// User can set packetioSizeHardLimit build tag to enable 4MB hard limit. -// When packetioSizeHardLimit build tag is set, SetLimitSize exceeding -// the hard limit will be silently discarded. -func (b *Buffer) SetLimitSize(limit int) { - b.mutex.Lock() - defer b.mutex.Unlock() - - b.limitSize = limit -} - -// SetReadDeadline sets the deadline for the Read operation. -// Setting to zero means no deadline. -func (b *Buffer) SetReadDeadline(t time.Time) error { - b.readDeadline.Set(t) - return nil -} diff --git a/vendor/github.com/pion/transport/v2/packetio/errors.go b/vendor/github.com/pion/transport/v2/packetio/errors.go deleted file mode 100644 index 4974a10b..00000000 --- a/vendor/github.com/pion/transport/v2/packetio/errors.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package packetio - -import ( - "errors" -) - -// netError implements net.Error -type netError struct { - error - timeout, temporary bool -} - -func (e *netError) Timeout() bool { - return e.timeout -} - -func (e *netError) Temporary() bool { - return e.temporary -} - -var ( - // ErrFull is returned when the buffer has hit the configured limits. - ErrFull = errors.New("packetio.Buffer is full, discarding write") - - // ErrTimeout is returned when a deadline has expired - ErrTimeout = errors.New("i/o timeout") -) diff --git a/vendor/github.com/pion/transport/v2/packetio/hardlimit.go b/vendor/github.com/pion/transport/v2/packetio/hardlimit.go deleted file mode 100644 index 8058e47f..00000000 --- a/vendor/github.com/pion/transport/v2/packetio/hardlimit.go +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build packetioSizeHardlimit -// +build packetioSizeHardlimit - -package packetio - -const sizeHardLimit = true diff --git a/vendor/github.com/pion/transport/v2/packetio/no_hardlimit.go b/vendor/github.com/pion/transport/v2/packetio/no_hardlimit.go deleted file mode 100644 index a59e2595..00000000 --- a/vendor/github.com/pion/transport/v2/packetio/no_hardlimit.go +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !packetioSizeHardlimit -// +build !packetioSizeHardlimit - -package packetio - -const sizeHardLimit = false diff --git a/vendor/github.com/pion/transport/v2/renovate.json b/vendor/github.com/pion/transport/v2/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/transport/v2/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/transport/v2/replaydetector/fixedbig.go b/vendor/github.com/pion/transport/v2/replaydetector/fixedbig.go deleted file mode 100644 index 80cb6b30..00000000 --- a/vendor/github.com/pion/transport/v2/replaydetector/fixedbig.go +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package replaydetector - -import ( - "fmt" -) - -// fixedBigInt is the fix-sized multi-word integer. -type fixedBigInt struct { - bits []uint64 - n uint - msbMask uint64 -} - -// newFixedBigInt creates a new fix-sized multi-word int. -func newFixedBigInt(n uint) *fixedBigInt { - chunkSize := (n + 63) / 64 - if chunkSize == 0 { - chunkSize = 1 - } - return &fixedBigInt{ - bits: make([]uint64, chunkSize), - n: n, - msbMask: (1 << (64 - n%64)) - 1, - } -} - -// Lsh is the left shift operation. -func (s *fixedBigInt) Lsh(n uint) { - if n == 0 { - return - } - nChunk := int(n / 64) - nN := n % 64 - - for i := len(s.bits) - 1; i >= 0; i-- { - var carry uint64 - if i-nChunk >= 0 { - carry = s.bits[i-nChunk] << nN - if i-nChunk-1 >= 0 { - carry |= s.bits[i-nChunk-1] >> (64 - nN) - } - } - s.bits[i] = (s.bits[i] << n) | carry - } - s.bits[len(s.bits)-1] &= s.msbMask -} - -// Bit returns i-th bit of the fixedBigInt. -func (s *fixedBigInt) Bit(i uint) uint { - if i >= s.n { - return 0 - } - chunk := i / 64 - pos := i % 64 - if s.bits[chunk]&(1<= s.n { - return - } - chunk := i / 64 - pos := i % 64 - s.bits[chunk] |= 1 << pos -} - -// String returns string representation of fixedBigInt. -func (s *fixedBigInt) String() string { - var out string - for i := len(s.bits) - 1; i >= 0; i-- { - out += fmt.Sprintf("%016X", s.bits[i]) - } - return out -} diff --git a/vendor/github.com/pion/transport/v2/replaydetector/replaydetector.go b/vendor/github.com/pion/transport/v2/replaydetector/replaydetector.go deleted file mode 100644 index 4358d8f3..00000000 --- a/vendor/github.com/pion/transport/v2/replaydetector/replaydetector.go +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package replaydetector provides packet replay detection algorithm. -package replaydetector - -// ReplayDetector is the interface of sequence replay detector. -type ReplayDetector interface { - // Check returns true if given sequence number is not replayed. - // Call accept() to mark the packet is received properly. - Check(seq uint64) (accept func(), ok bool) -} - -type slidingWindowDetector struct { - latestSeq uint64 - maxSeq uint64 - windowSize uint - mask *fixedBigInt -} - -// New creates ReplayDetector. -// Created ReplayDetector doesn't allow wrapping. -// It can handle monotonically increasing sequence number up to -// full 64bit number. It is suitable for DTLS replay protection. -func New(windowSize uint, maxSeq uint64) ReplayDetector { - return &slidingWindowDetector{ - maxSeq: maxSeq, - windowSize: windowSize, - mask: newFixedBigInt(windowSize), - } -} - -func (d *slidingWindowDetector) Check(seq uint64) (accept func(), ok bool) { - if seq > d.maxSeq { - // Exceeded upper limit. - return func() {}, false - } - - if seq <= d.latestSeq { - if d.latestSeq >= uint64(d.windowSize)+seq { - return func() {}, false - } - if d.mask.Bit(uint(d.latestSeq-seq)) != 0 { - // The sequence number is duplicated. - return func() {}, false - } - } - - return func() { - if seq > d.latestSeq { - // Update the head of the window. - d.mask.Lsh(uint(seq - d.latestSeq)) - d.latestSeq = seq - } - diff := (d.latestSeq - seq) % d.maxSeq - d.mask.SetBit(uint(diff)) - }, true -} - -// WithWrap creates ReplayDetector allowing sequence wrapping. -// This is suitable for short bit width counter like SRTP and SRTCP. -func WithWrap(windowSize uint, maxSeq uint64) ReplayDetector { - return &wrappedSlidingWindowDetector{ - maxSeq: maxSeq, - windowSize: windowSize, - mask: newFixedBigInt(windowSize), - } -} - -type wrappedSlidingWindowDetector struct { - latestSeq uint64 - maxSeq uint64 - windowSize uint - mask *fixedBigInt - init bool -} - -func (d *wrappedSlidingWindowDetector) Check(seq uint64) (accept func(), ok bool) { - if seq > d.maxSeq { - // Exceeded upper limit. - return func() {}, false - } - if !d.init { - if seq != 0 { - d.latestSeq = seq - 1 - } else { - d.latestSeq = d.maxSeq - } - d.init = true - } - - diff := int64(d.latestSeq) - int64(seq) - // Wrap the number. - if diff > int64(d.maxSeq)/2 { - diff -= int64(d.maxSeq + 1) - } else if diff <= -int64(d.maxSeq)/2 { - diff += int64(d.maxSeq + 1) - } - - if diff >= int64(d.windowSize) { - // Too old. - return func() {}, false - } - if diff >= 0 { - if d.mask.Bit(uint(diff)) != 0 { - // The sequence number is duplicated. - return func() {}, false - } - } - - return func() { - if diff < 0 { - // Update the head of the window. - d.mask.Lsh(uint(-diff)) - d.latestSeq = seq - } - d.mask.SetBit(uint(d.latestSeq - seq)) - }, true -} diff --git a/vendor/github.com/pion/transport/v2/stdnet/net.go b/vendor/github.com/pion/transport/v2/stdnet/net.go deleted file mode 100644 index fa4753b5..00000000 --- a/vendor/github.com/pion/transport/v2/stdnet/net.go +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package stdnet implements the transport.Net interface -// using methods from Go's standard net package. -package stdnet - -import ( - "fmt" - "net" - - "github.com/pion/transport/v2" -) - -const ( - lo0String = "lo0String" - udpString = "udp" -) - -// Net is an implementation of the net.Net interface -// based on functions of the standard net package. -type Net struct { - interfaces []*transport.Interface -} - -// NewNet creates a new StdNet instance. -func NewNet() (*Net, error) { - n := &Net{} - - return n, n.UpdateInterfaces() -} - -// Compile-time assertion -var _ transport.Net = &Net{} - -// UpdateInterfaces updates the internal list of network interfaces -// and associated addresses. -func (n *Net) UpdateInterfaces() error { - ifs := []*transport.Interface{} - - oifs, err := net.Interfaces() - if err != nil { - return err - } - - for _, oif := range oifs { - ifc := transport.NewInterface(oif) - - addrs, err := oif.Addrs() - if err != nil { - return err - } - - for _, addr := range addrs { - ifc.AddAddress(addr) - } - - ifs = append(ifs, ifc) - } - - n.interfaces = ifs - - return nil -} - -// Interfaces returns a slice of interfaces which are available on the -// system -func (n *Net) Interfaces() ([]*transport.Interface, error) { - return n.interfaces, nil -} - -// InterfaceByIndex returns the interface specified by index. -// -// On Solaris, it returns one of the logical network interfaces -// sharing the logical data link; for more precision use -// InterfaceByName. -func (n *Net) InterfaceByIndex(index int) (*transport.Interface, error) { - for _, ifc := range n.interfaces { - if ifc.Index == index { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: index=%d", transport.ErrInterfaceNotFound, index) -} - -// InterfaceByName returns the interface specified by name. -func (n *Net) InterfaceByName(name string) (*transport.Interface, error) { - for _, ifc := range n.interfaces { - if ifc.Name == name { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: %s", transport.ErrInterfaceNotFound, name) -} - -// ListenPacket announces on the local network address. -func (n *Net) ListenPacket(network string, address string) (net.PacketConn, error) { - return net.ListenPacket(network, address) -} - -// ListenUDP acts like ListenPacket for UDP networks. -func (n *Net) ListenUDP(network string, locAddr *net.UDPAddr) (transport.UDPConn, error) { - return net.ListenUDP(network, locAddr) -} - -// Dial connects to the address on the named network. -func (n *Net) Dial(network, address string) (net.Conn, error) { - return net.Dial(network, address) -} - -// DialUDP acts like Dial for UDP networks. -func (n *Net) DialUDP(network string, laddr, raddr *net.UDPAddr) (transport.UDPConn, error) { - return net.DialUDP(network, laddr, raddr) -} - -// ResolveIPAddr returns an address of IP end point. -func (n *Net) ResolveIPAddr(network, address string) (*net.IPAddr, error) { - return net.ResolveIPAddr(network, address) -} - -// ResolveUDPAddr returns an address of UDP end point. -func (n *Net) ResolveUDPAddr(network, address string) (*net.UDPAddr, error) { - return net.ResolveUDPAddr(network, address) -} - -// ResolveTCPAddr returns an address of TCP end point. -func (n *Net) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) { - return net.ResolveTCPAddr(network, address) -} - -// DialTCP acts like Dial for TCP networks. -func (n *Net) DialTCP(network string, laddr, raddr *net.TCPAddr) (transport.TCPConn, error) { - return net.DialTCP(network, laddr, raddr) -} - -// ListenTCP acts like Listen for TCP networks. -func (n *Net) ListenTCP(network string, laddr *net.TCPAddr) (transport.TCPListener, error) { - l, err := net.ListenTCP(network, laddr) - if err != nil { - return nil, err - } - - return tcpListener{l}, nil -} - -type tcpListener struct { - *net.TCPListener -} - -func (l tcpListener) AcceptTCP() (transport.TCPConn, error) { - return l.TCPListener.AcceptTCP() -} - -type stdDialer struct { - *net.Dialer -} - -func (d stdDialer) Dial(network, address string) (net.Conn, error) { - return d.Dialer.Dial(network, address) -} - -// CreateDialer creates an instance of vnet.Dialer -func (n *Net) CreateDialer(d *net.Dialer) transport.Dialer { - return stdDialer{d} -} diff --git a/vendor/github.com/pion/transport/v2/udp/conn.go b/vendor/github.com/pion/transport/v2/udp/conn.go deleted file mode 100644 index 2b57174a..00000000 --- a/vendor/github.com/pion/transport/v2/udp/conn.go +++ /dev/null @@ -1,327 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package udp provides a connection-oriented listener over a UDP PacketConn -package udp - -import ( - "context" - "errors" - "net" - "sync" - "sync/atomic" - "time" - - "github.com/pion/transport/v2/deadline" - "github.com/pion/transport/v2/packetio" -) - -const ( - receiveMTU = 8192 - defaultListenBacklog = 128 // same as Linux default -) - -// Typed errors -var ( - ErrClosedListener = errors.New("udp: listener closed") - ErrListenQueueExceeded = errors.New("udp: listen queue exceeded") - ErrReadBufferFailed = errors.New("udp: failed to get read buffer from pool") -) - -// listener augments a connection-oriented Listener over a UDP PacketConn -type listener struct { - pConn *net.UDPConn - - accepting atomic.Value // bool - acceptCh chan *Conn - doneCh chan struct{} - doneOnce sync.Once - acceptFilter func([]byte) bool - readBufferPool *sync.Pool - - connLock sync.Mutex - conns map[string]*Conn - connWG *sync.WaitGroup - - readWG sync.WaitGroup - errClose atomic.Value // error - - readDoneCh chan struct{} - errRead atomic.Value // error -} - -// Accept waits for and returns the next connection to the listener. -func (l *listener) Accept() (net.Conn, error) { - select { - case c := <-l.acceptCh: - l.connWG.Add(1) - return c, nil - - case <-l.readDoneCh: - err, _ := l.errRead.Load().(error) - return nil, err - - case <-l.doneCh: - return nil, ErrClosedListener - } -} - -// Close closes the listener. -// Any blocked Accept operations will be unblocked and return errors. -func (l *listener) Close() error { - var err error - l.doneOnce.Do(func() { - l.accepting.Store(false) - close(l.doneCh) - - l.connLock.Lock() - // Close unaccepted connections - lclose: - for { - select { - case c := <-l.acceptCh: - close(c.doneCh) - delete(l.conns, c.rAddr.String()) - - default: - break lclose - } - } - nConns := len(l.conns) - l.connLock.Unlock() - - l.connWG.Done() - - if nConns == 0 { - // Wait if this is the final connection - l.readWG.Wait() - if errClose, ok := l.errClose.Load().(error); ok { - err = errClose - } - } else { - err = nil - } - }) - - return err -} - -// Addr returns the listener's network address. -func (l *listener) Addr() net.Addr { - return l.pConn.LocalAddr() -} - -// ListenConfig stores options for listening to an address. -type ListenConfig struct { - // Backlog defines the maximum length of the queue of pending - // connections. It is equivalent of the backlog argument of - // POSIX listen function. - // If a connection request arrives when the queue is full, - // the request will be silently discarded, unlike TCP. - // Set zero to use default value 128 which is same as Linux default. - Backlog int - - // AcceptFilter determines whether the new conn should be made for - // the incoming packet. If not set, any packet creates new conn. - AcceptFilter func([]byte) bool -} - -// Listen creates a new listener based on the ListenConfig. -func (lc *ListenConfig) Listen(network string, laddr *net.UDPAddr) (net.Listener, error) { - if lc.Backlog == 0 { - lc.Backlog = defaultListenBacklog - } - - conn, err := net.ListenUDP(network, laddr) - if err != nil { - return nil, err - } - - l := &listener{ - pConn: conn, - acceptCh: make(chan *Conn, lc.Backlog), - conns: make(map[string]*Conn), - doneCh: make(chan struct{}), - acceptFilter: lc.AcceptFilter, - readBufferPool: &sync.Pool{ - New: func() interface{} { - buf := make([]byte, receiveMTU) - return &buf - }, - }, - connWG: &sync.WaitGroup{}, - readDoneCh: make(chan struct{}), - } - - l.accepting.Store(true) - l.connWG.Add(1) - l.readWG.Add(2) // wait readLoop and Close execution routine - - go l.readLoop() - go func() { - l.connWG.Wait() - if err := l.pConn.Close(); err != nil { - l.errClose.Store(err) - } - l.readWG.Done() - }() - - return l, nil -} - -// Listen creates a new listener using default ListenConfig. -func Listen(network string, laddr *net.UDPAddr) (net.Listener, error) { - return (&ListenConfig{}).Listen(network, laddr) -} - -// readLoop has to tasks: -// 1. Dispatching incoming packets to the correct Conn. -// It can therefore not be ended until all Conns are closed. -// 2. Creating a new Conn when receiving from a new remote. -func (l *listener) readLoop() { - defer l.readWG.Done() - defer close(l.readDoneCh) - - buf, ok := l.readBufferPool.Get().(*[]byte) - if !ok { - l.errRead.Store(ErrReadBufferFailed) - return - } - defer l.readBufferPool.Put(buf) - - for { - n, raddr, err := l.pConn.ReadFrom(*buf) - if err != nil { - l.errRead.Store(err) - return - } - conn, ok, err := l.getConn(raddr, (*buf)[:n]) - if err != nil { - continue - } - if ok { - _, _ = conn.buffer.Write((*buf)[:n]) - } - } -} - -func (l *listener) getConn(raddr net.Addr, buf []byte) (*Conn, bool, error) { - l.connLock.Lock() - defer l.connLock.Unlock() - conn, ok := l.conns[raddr.String()] - if !ok { - if isAccepting, ok := l.accepting.Load().(bool); !isAccepting || !ok { - return nil, false, ErrClosedListener - } - if l.acceptFilter != nil { - if !l.acceptFilter(buf) { - return nil, false, nil - } - } - conn = l.newConn(raddr) - select { - case l.acceptCh <- conn: - l.conns[raddr.String()] = conn - default: - return nil, false, ErrListenQueueExceeded - } - } - return conn, true, nil -} - -// Conn augments a connection-oriented connection over a UDP PacketConn -type Conn struct { - listener *listener - - rAddr net.Addr - - buffer *packetio.Buffer - - doneCh chan struct{} - doneOnce sync.Once - - writeDeadline *deadline.Deadline -} - -func (l *listener) newConn(rAddr net.Addr) *Conn { - return &Conn{ - listener: l, - rAddr: rAddr, - buffer: packetio.NewBuffer(), - doneCh: make(chan struct{}), - writeDeadline: deadline.New(), - } -} - -// Read reads from c into p -func (c *Conn) Read(p []byte) (int, error) { - return c.buffer.Read(p) -} - -// Write writes len(p) bytes from p to the DTLS connection -func (c *Conn) Write(p []byte) (n int, err error) { - select { - case <-c.writeDeadline.Done(): - return 0, context.DeadlineExceeded - default: - } - return c.listener.pConn.WriteTo(p, c.rAddr) -} - -// Close closes the conn and releases any Read calls -func (c *Conn) Close() error { - var err error - c.doneOnce.Do(func() { - c.listener.connWG.Done() - close(c.doneCh) - c.listener.connLock.Lock() - delete(c.listener.conns, c.rAddr.String()) - nConns := len(c.listener.conns) - c.listener.connLock.Unlock() - - if isAccepting, ok := c.listener.accepting.Load().(bool); nConns == 0 && !isAccepting && ok { - // Wait if this is the final connection - c.listener.readWG.Wait() - if errClose, ok := c.listener.errClose.Load().(error); ok { - err = errClose - } - } else { - err = nil - } - - if errBuf := c.buffer.Close(); errBuf != nil && err == nil { - err = errBuf - } - }) - - return err -} - -// LocalAddr implements net.Conn.LocalAddr -func (c *Conn) LocalAddr() net.Addr { - return c.listener.pConn.LocalAddr() -} - -// RemoteAddr implements net.Conn.RemoteAddr -func (c *Conn) RemoteAddr() net.Addr { - return c.rAddr -} - -// SetDeadline implements net.Conn.SetDeadline -func (c *Conn) SetDeadline(t time.Time) error { - c.writeDeadline.Set(t) - return c.SetReadDeadline(t) -} - -// SetReadDeadline implements net.Conn.SetDeadline -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.buffer.SetReadDeadline(t) -} - -// SetWriteDeadline implements net.Conn.SetDeadline -func (c *Conn) SetWriteDeadline(t time.Time) error { - c.writeDeadline.Set(t) - // Write deadline of underlying connection should not be changed - // since the connection can be shared. - return nil -} diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.go deleted file mode 100644 index ded8e0d3..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !gccgo -// +build !gccgo - -// Package xor provides utility functions used by other Pion -// packages. AMD64 arch. -package xor - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - _ = dst[n-1] - xorBytesSSE2(&dst[0], &a[0], &b[0], n) // amd64 must have SSE2 - return n -} - -//go:noescape -func xorBytesSSE2(dst, a, b *byte, n int) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.s b/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.s deleted file mode 100644 index f66ac95a..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_amd64.s +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -// go:build !gccgo -// +build !gccgo - -#include "textflag.h" - -// func xorBytesSSE2(dst, a, b *byte, n int) -TEXT ·xorBytesSSE2(SB), NOSPLIT, $0 - MOVQ dst+0(FP), BX - MOVQ a+8(FP), SI - MOVQ b+16(FP), CX - MOVQ n+24(FP), DX - TESTQ $15, DX // AND 15 & len, if not zero jump to not_aligned. - JNZ not_aligned - -aligned: - MOVQ $0, AX // position in slices - -loop16b: - MOVOU (SI)(AX*1), X0 // XOR 16byte forwards. - MOVOU (CX)(AX*1), X1 - PXOR X1, X0 - MOVOU X0, (BX)(AX*1) - ADDQ $16, AX - CMPQ DX, AX - JNE loop16b - RET - -loop_1b: - SUBQ $1, DX // XOR 1byte backwards. - MOVB (SI)(DX*1), DI - MOVB (CX)(DX*1), AX - XORB AX, DI - MOVB DI, (BX)(DX*1) - TESTQ $7, DX // AND 7 & len, if not zero jump to loop_1b. - JNZ loop_1b - CMPQ DX, $0 // if len is 0, ret. - JE ret - TESTQ $15, DX // AND 15 & len, if zero jump to aligned. - JZ aligned - -not_aligned: - TESTQ $7, DX // AND $7 & len, if not zero jump to loop_1b. - JNE loop_1b - SUBQ $8, DX // XOR 8bytes backwards. - MOVQ (SI)(DX*1), DI - MOVQ (CX)(DX*1), AX - XORQ AX, DI - MOVQ DI, (BX)(DX*1) - CMPQ DX, $16 // if len is greater or equal 16 here, it must be aligned. - JGE aligned - -ret: - RET diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.go deleted file mode 100644 index 25d6b72d..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.go +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !gccgo -// +build !gccgo - -// Package xor provides utility functions used by other Pion -// packages. ARM arch. -package xor - -import ( - "unsafe" - - "golang.org/x/sys/cpu" -) - -const wordSize = int(unsafe.Sizeof(uintptr(0))) // nolint:gosec -var hasNEON = cpu.ARM.HasNEON // nolint:gochecknoglobals - -func isAligned(a *byte) bool { - return uintptr(unsafe.Pointer(a))%uintptr(wordSize) == 0 -} - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - // make sure dst has enough space - _ = dst[n-1] - - if hasNEON { - xorBytesNEON32(&dst[0], &a[0], &b[0], n) - } else if isAligned(&dst[0]) && isAligned(&a[0]) && isAligned(&b[0]) { - xorBytesARM32(&dst[0], &a[0], &b[0], n) - } else { - safeXORBytes(dst, a, b, n) - } - return n -} - -// n needs to be smaller or equal than the length of a and b. -func safeXORBytes(dst, a, b []byte, n int) { - for i := 0; i < n; i++ { - dst[i] = a[i] ^ b[i] - } -} - -//go:noescape -func xorBytesARM32(dst, a, b *byte, n int) - -//go:noescape -func xorBytesNEON32(dst, a, b *byte, n int) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.s b/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.s deleted file mode 100644 index 5e52a2d6..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm.s +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-FileCopyrightText: 2022 The Pion community -// SPDX-License-Identifier: MIT - -// go:build !gccgo -// +build !gccgo - -#include "textflag.h" - -// func xorBytesARM32(dst, a, b *byte, n int) -TEXT ·xorBytesARM32(SB), NOSPLIT|NOFRAME, $0 - MOVW dst+0(FP), R0 - MOVW a+4(FP), R1 - MOVW b+8(FP), R2 - MOVW n+12(FP), R3 - CMP $4, R3 - BLT less_than4 - -loop_4: - MOVW.P 4(R1), R4 - MOVW.P 4(R2), R5 - EOR R4, R5, R5 - MOVW.P R5, 4(R0) - - SUB $4, R3 - CMP $4, R3 - BGE loop_4 - -less_than4: - CMP $2, R3 - BLT less_than2 - MOVH.P 2(R1), R4 - MOVH.P 2(R2), R5 - EOR R4, R5, R5 - MOVH.P R5, 2(R0) - - SUB $2, R3 - -less_than2: - CMP $0, R3 - BEQ end - MOVB (R1), R4 - MOVB (R2), R5 - EOR R4, R5, R5 - MOVB R5, (R0) -end: - RET - -// func xorBytesNEON32(dst, a, b *byte, n int) -TEXT ·xorBytesNEON32(SB), NOSPLIT|NOFRAME, $0 - MOVW dst+0(FP), R0 - MOVW a+4(FP), R1 - MOVW b+8(FP), R2 - MOVW n+12(FP), R3 - CMP $32, R3 - BLT less_than32 - -loop_32: - WORD $0xF421020D // vld1.u8 {q0, q1}, [r1]! - WORD $0xF422420D // vld1.u8 {q2, q3}, [r2]! - WORD $0xF3004154 // veor q2, q0, q2 - WORD $0xF3026156 // veor q3, q1, q3 - WORD $0xF400420D // vst1.u8 {q2, q3}, [r0]! - - SUB $32, R3 - CMP $32, R3 - BGE loop_32 - -less_than32: - CMP $16, R3 - BLT less_than16 - WORD $0xF4210A0D // vld1.u8 q0, [r1]! - WORD $0xF4222A0D // vld1.u8 q1, [r2]! - WORD $0xF3002152 // veor q1, q0, q1 - WORD $0xF4002A0D // vst1.u8 {q1}, [r0]! - - SUB $16, R3 - -less_than16: - CMP $8, R3 - BLT less_than8 - WORD $0xF421070D // vld1.u8 d0, [r1]! - WORD $0xF422170D // vld1.u8 d1, [r2]! - WORD $0xF3001111 // veor d1, d0, d1 - WORD $0xF400170D // vst1.u8 {d1}, [r0]! - - SUB $8, R3 - -less_than8: - CMP $4, R3 - BLT less_than4 - MOVW.P 4(R1), R4 - MOVW.P 4(R2), R5 - EOR R4, R5, R5 - MOVW.P R5, 4(R0) - - SUB $4, R3 - -less_than4: - CMP $2, R3 - BLT less_than2 - MOVH.P 2(R1), R4 - MOVH.P 2(R2), R5 - EOR R4, R5, R5 - MOVH.P R5, 2(R0) - - SUB $2, R3 - -less_than2: - CMP $0, R3 - BEQ end - MOVB (R1), R4 - MOVB (R2), R5 - EOR R4, R5, R5 - MOVB R5, (R0) -end: - RET diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.go deleted file mode 100644 index 7002ab7c..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.go +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2020 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !gccgo -// +build !gccgo - -// Package xor provides utility functions used by other Pion -// packages. ARM64 arch. -package xor - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - // make sure dst has enough space - _ = dst[n-1] - - xorBytesARM64(&dst[0], &a[0], &b[0], n) - return n -} - -//go:noescape -func xorBytesARM64(dst, a, b *byte, n int) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.s b/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.s deleted file mode 100644 index 0b82d099..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_arm64.s +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-FileCopyrightText: 2020 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build !gccgo -// +build !gccgo - -#include "textflag.h" - -// func xorBytesARM64(dst, a, b *byte, n int) -TEXT ·xorBytesARM64(SB), NOSPLIT|NOFRAME, $0 - MOVD dst+0(FP), R0 - MOVD a+8(FP), R1 - MOVD b+16(FP), R2 - MOVD n+24(FP), R3 - CMP $64, R3 - BLT tail -loop_64: - VLD1.P 64(R1), [V0.B16, V1.B16, V2.B16, V3.B16] - VLD1.P 64(R2), [V4.B16, V5.B16, V6.B16, V7.B16] - VEOR V0.B16, V4.B16, V4.B16 - VEOR V1.B16, V5.B16, V5.B16 - VEOR V2.B16, V6.B16, V6.B16 - VEOR V3.B16, V7.B16, V7.B16 - VST1.P [V4.B16, V5.B16, V6.B16, V7.B16], 64(R0) - SUBS $64, R3 - CMP $64, R3 - BGE loop_64 -tail: - // quick end - CBZ R3, end - TBZ $5, R3, less_than32 - VLD1.P 32(R1), [V0.B16, V1.B16] - VLD1.P 32(R2), [V2.B16, V3.B16] - VEOR V0.B16, V2.B16, V2.B16 - VEOR V1.B16, V3.B16, V3.B16 - VST1.P [V2.B16, V3.B16], 32(R0) -less_than32: - TBZ $4, R3, less_than16 - LDP.P 16(R1), (R11, R12) - LDP.P 16(R2), (R13, R14) - EOR R11, R13, R13 - EOR R12, R14, R14 - STP.P (R13, R14), 16(R0) -less_than16: - TBZ $3, R3, less_than8 - MOVD.P 8(R1), R11 - MOVD.P 8(R2), R12 - EOR R11, R12, R12 - MOVD.P R12, 8(R0) -less_than8: - TBZ $2, R3, less_than4 - MOVWU.P 4(R1), R13 - MOVWU.P 4(R2), R14 - EORW R13, R14, R14 - MOVWU.P R14, 4(R0) -less_than4: - TBZ $1, R3, less_than2 - MOVHU.P 2(R1), R15 - MOVHU.P 2(R2), R16 - EORW R15, R16, R16 - MOVHU.P R16, 2(R0) -less_than2: - TBZ $0, R3, end - MOVBU (R1), R17 - MOVBU (R2), R19 - EORW R17, R19, R19 - MOVBU R19, (R0) -end: - RET diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_generic.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_generic.go deleted file mode 100644 index 967fed33..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_generic.go +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-FileCopyrightText: 2013 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -// SPDX-FileCopyrightText: 2022 The Pion community -// SPDX-License-Identifier: MIT - -//go:build (!amd64 && !ppc64 && !ppc64le && !arm64 && !arm) || gccgo -// +build !amd64,!ppc64,!ppc64le,!arm64,!arm gccgo - -// Package xor provides utility functions used by other Pion -// packages. Generic arch. -package xor - -import ( - "runtime" - "unsafe" -) - -const ( - wordSize = int(unsafe.Sizeof(uintptr(0))) // nolint:gosec - supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x" // nolint:gochecknoglobals -) - -func isAligned(a *byte) bool { - return uintptr(unsafe.Pointer(a))%uintptr(wordSize) == 0 -} - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - - switch { - case supportsUnaligned: - fastXORBytes(dst, a, b, n) - case isAligned(&dst[0]) && isAligned(&a[0]) && isAligned(&b[0]): - fastXORBytes(dst, a, b, n) - default: - safeXORBytes(dst, a, b, n) - } - return n -} - -// fastXORBytes xors in bulk. It only works on architectures that -// support unaligned read/writes. -// n needs to be smaller or equal than the length of a and b. -func fastXORBytes(dst, a, b []byte, n int) { - // Assert dst has enough space - _ = dst[n-1] - - w := n / wordSize - if w > 0 { - dw := *(*[]uintptr)(unsafe.Pointer(&dst)) // nolint:gosec - aw := *(*[]uintptr)(unsafe.Pointer(&a)) // nolint:gosec - bw := *(*[]uintptr)(unsafe.Pointer(&b)) // nolint:gosec - for i := 0; i < w; i++ { - dw[i] = aw[i] ^ bw[i] - } - } - - for i := (n - n%wordSize); i < n; i++ { - dst[i] = a[i] ^ b[i] - } -} - -// n needs to be smaller or equal than the length of a and b. -func safeXORBytes(dst, a, b []byte, n int) { - for i := 0; i < n; i++ { - dst[i] = a[i] ^ b[i] - } -} diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.go b/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.go deleted file mode 100644 index bcc5926c..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build (ppc64 && !gccgo) || (ppc64le && !gccgo) -// +build ppc64,!gccgo ppc64le,!gccgo - -// Package xor provides utility functions used by other Pion -// packages. PPC64 arch. -package xor - -// XorBytes xors the bytes in a and b. The destination should have enough -// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. -// -//revive:disable-next-line -func XorBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - if n == 0 { - return 0 - } - _ = dst[n-1] - xorBytesVSX(&dst[0], &a[0], &b[0], n) - return n -} - -//go:noescape -func xorBytesVSX(dst, a, b *byte, n int) diff --git a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.s b/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.s deleted file mode 100644 index 22763535..00000000 --- a/vendor/github.com/pion/transport/v2/utils/xor/xor_ppc64x.s +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: 2018 The Go Authors. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause - -//go:build (ppc64 && !gccgo) || (ppc64le && !gccgo) -//+build ppc64,!gccgo ppc64le,!gccgo - -#include "textflag.h" - -// func xorBytesVSX(dst, a, b *byte, n int) -TEXT ·xorBytesVSX(SB), NOSPLIT, $0 - MOVD dst+0(FP), R3 // R3 = dst - MOVD a+8(FP), R4 // R4 = a - MOVD b+16(FP), R5 // R5 = b - MOVD n+24(FP), R6 // R6 = n - - CMPU R6, $32, CR7 // Check if n ≥ 32 bytes - MOVD R0, R8 // R8 = index - CMPU R6, $8, CR6 // Check if 8 ≤ n < 32 bytes - BLT CR6, small // Smaller than 8 - BLT CR7, xor16 // Case for 16 ≤ n < 32 bytes - - // Case for n ≥ 32 bytes -preloop32: - SRD $5, R6, R7 // Setup loop counter - MOVD R7, CTR - MOVD $16, R10 - ANDCC $31, R6, R9 // Check for tailing bytes for later -loop32: - LXVD2X (R4)(R8), VS32 // VS32 = a[i,...,i+15] - LXVD2X (R4)(R10), VS34 - LXVD2X (R5)(R8), VS33 // VS33 = b[i,...,i+15] - LXVD2X (R5)(R10), VS35 - XXLXOR VS32, VS33, VS32 // VS34 = a[] ^ b[] - XXLXOR VS34, VS35, VS34 - STXVD2X VS32, (R3)(R8) // Store to dst - STXVD2X VS34, (R3)(R10) - ADD $32, R8 // Update index - ADD $32, R10 - BC 16, 0, loop32 // bdnz loop16 - - BEQ CR0, done - - MOVD R9, R6 - CMP R6, $8 - BLT small -xor16: - CMP R6, $16 - BLT xor8 - LXVD2X (R4)(R8), VS32 - LXVD2X (R5)(R8), VS33 - XXLXOR VS32, VS33, VS32 - STXVD2X VS32, (R3)(R8) - ADD $16, R8 - ADD $-16, R6 - CMP R6, $8 - BLT small -xor8: - // Case for 8 ≤ n < 16 bytes - MOVD (R4)(R8), R14 // R14 = a[i,...,i+7] - MOVD (R5)(R8), R15 // R15 = b[i,...,i+7] - XOR R14, R15, R16 // R16 = a[] ^ b[] - SUB $8, R6 // n = n - 8 - MOVD R16, (R3)(R8) // Store to dst - ADD $8, R8 - - // Check if we're finished - CMP R6, R0 - BGT small - RET - - // Case for n < 8 bytes and tailing bytes from the - // previous cases. -small: - CMP R6, R0 - BEQ done - MOVD R6, CTR // Setup loop counter - -loop: - MOVBZ (R4)(R8), R14 // R14 = a[i] - MOVBZ (R5)(R8), R15 // R15 = b[i] - XOR R14, R15, R16 // R16 = a[i] ^ b[i] - MOVB R16, (R3)(R8) // Store to dst - ADD $1, R8 - BC 16, 0, loop // bdnz loop - -done: - RET diff --git a/vendor/github.com/pion/transport/v2/vnet/.gitignore b/vendor/github.com/pion/transport/v2/vnet/.gitignore deleted file mode 100644 index f2eef3e9..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -*.sw[poe] diff --git a/vendor/github.com/pion/transport/v2/vnet/README.md b/vendor/github.com/pion/transport/v2/vnet/README.md deleted file mode 100644 index bd0af250..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/README.md +++ /dev/null @@ -1,231 +0,0 @@ -# vnet -A virtual network layer for pion. - -## Overview - -### Goals -* To make NAT traversal tests easy. -* To emulate packet impairment at application level for testing. -* To monitor packets at specified arbitrary interfaces. - -### Features -* Configurable virtual LAN and WAN -* Virtually hosted ICE servers - -### Virtual network components - -#### Top View -``` - ...................................... - : Virtual Network (vnet) : - : : - +-------+ * 1 +----+ +--------+ : - | :App |------------>|:Net|--o<-----|:Router | : - +-------+ +----+ | | : - +-----------+ * 1 +----+ | | : - |:STUNServer|-------->|:Net|--o<-----| | : - +-----------+ +----+ | | : - +-----------+ * 1 +----+ | | : - |:TURNServer|-------->|:Net|--o<-----| | : - +-----------+ +----+ [1] | | : - : 1 | | 1 <> : - : +---<>| |<>----+ [2] : - : | +--------+ | : - To form | *| v 0..1 : - a subnet tree | o [3] +-----+ : - : | ^ |:NAT | : - : | | +-----+ : - : +-------+ : - ...................................... - Note: - o: NIC (Network Interface Controller) - [1]: Net implements NIC interface. - [2]: Root router has no NAT. All child routers have a NAT always. - [3]: Router implements NIC interface for accesses from the - parent router. -``` - -#### Net -Net provides 3 interfaces: -* Configuration API (direct) -* Network API via Net (equivalent to net.Xxx()) -* Router access via NIC interface -``` - (Pion module/app, ICE servers, etc.) - +-----------+ - | :App | - +-----------+ - * | - | <> - 1 v - +---------+ 1 * +-----------+ 1 * +-----------+ 1 * +------+ - ..| :Router |----+------>o--| :Net |<>------|:Interface |<>------|:Addr | - +---------+ | NIC +-----------+ +-----------+ +------+ - | <> (transport.Interface) (net.Addr) - | - | * +-----------+ 1 * +-----------+ 1 * +------+ - +------>o--| :Router |<>------|:Interface |<>------|:Addr | - NIC +-----------+ +-----------+ +------+ - <> (transport.Interface) (net.Addr) -``` - -> The instance of `Net` will be the one passed around the project. -> Net class has public methods for configuration and for application use. - - -## Implementation - -### Design Policy -* Each pion package should have config object which has `Net` (of type `transport.Net`) property. - - Just like how we distribute `LoggerFactory` throughout the pion project. -* DNS => a simple dictionary (global)? -* Each Net has routing capability (a goroutine) -* Use interface provided net package as much as possible -* Routers are connected in a tree structure (no loop is allowed) - - To simplify routing - - Easy to control / monitor (stats, etc) -* Root router has no NAT (== Internet / WAN) -* Non-root router has a NAT always -* When a Net is instantiated, it will automatically add `lo0` and `eth0` interface, and `lo0` will have one IP address, 127.0.0.1. (this is not used in pion/ice, however) -* When a Net is added to a router, the router automatically assign an IP address for `eth0` interface. - - For simplicity -* User data won't fragment, but optionally drop chunk larger than MTU -* IPv6 is not supported - -### Basic steps for setting up virtual network -1. Create a root router (WAN) -1. Create child routers and add to its parent (forms a tree, don't create a loop!) -1. Add instances of Net to each routers -1. Call Stop(), or Stop(), on the top router, which propagates all other routers - -#### Example: WAN with one endpoint (vnet) -```go -import ( - "net" - - "github.com/pion/transport" - "github.com/pion/transport/vnet" - "github.com/pion/logging" -) - -// Create WAN (a root router). -wan, err := vnet.NewRouter(&RouterConfig{ - CIDR: "0.0.0.0/0", - LoggerFactory: logging.NewDefaultLoggerFactory(), -}) - -// Create a network. -// You can specify a static IP for the instance of Net to use. If not specified, -// router will assign an IP address that is contained in the router's CIDR. -nw := vnet.NewNet(&vnet.NetConfig{ - StaticIP: "27.1.2.3", -}) - -// Add the network to the router. -// The router will assign an IP address to `nw`. -if err = wan.AddNet(nw); err != nil { - // handle error -} - -// Start router. -// This will start internal goroutine to route packets. -// If you set child routers (using AddRouter), the call on the root router -// will start the rest of routers for you. -if err = wan.Start(); err != nil { - // handle error -} - -// -// Your application runs here using `nw`. -// - -// Stop the router. -// This will stop all internal Go routines in the router tree. -// (No need to call Stop() on child routers) -if err = wan.Stop(); err != nil { - // handle error -} -``` - -#### Example of how to pass around the instance of vnet.Net -The instance of vnet.Net wraps a subset of net package to enable operations -on the virtual network. Your project must be able to pass the instance to -all your routines that do network operation with net package. A typical way -is to use a config param to create your instances with the virtual network -instance (`nw` in the above example) like this: - -```go -type AgentConfig struct { - : - Net: transport.Net, -} - -type Agent struct { - : - net: transport.Net, -} - -func NetAgent(config *AgentConfig) *Agent { - if config.Net == nil { - config.Net = vnet.NewNet() - } - - return &Agent { - : - net: config.Net, - } -} -``` - -```go -// a.net is the instance of vnet.Net class -func (a *Agent) listenUDP(...) error { - conn, err := a.net.ListenPacket(udpString, ...) - if err != nil { - return nil, err - } - : -} -``` - -### Compatibility and Support Status - -|`net`
(built-in) |`vnet` |Note | -|:--- |:--- |:--- | -| net.Interfaces() | a.net.Interfaces() | | -| net.InterfaceByName() | a.net.InterfaceByName() | | -| net.ResolveUDPAddr() | a.net.ResolveUDPAddr() | | -| net.ListenPacket() | a.net.ListenPacket() | | -| net.ListenUDP() | a.net.ListenUDP() | ListenPacket() is recommended | -| net.Listen() | a.net.Listen() | TODO) | -| net.ListenTCP() | (not supported) | Listen() would be recommended | -| net.Dial() | a.net.Dial() | | -| net.DialUDP() | a.net.DialUDP() | | -| net.DialTCP() | (not supported) | | -| net.Interface | transport.Interface | | -| net.PacketConn | (use it as-is) | | -| net.UDPConn | transport.UDPConn | | -| net.TCPConn | transport.TCPConn | TODO: Use net.Conn in your code | -| net.Dialer | transport.Dialer | Use a.net.CreateDialer() to create it.
The use of vnet.Dialer is currently experimental. | - -> `a.net` is an instance of Net class, and types are defined under the package name `vnet` - -> Most of other `interface` types in net package can be used as is. - -> Please post a github issue when other types/methods need to be added to vnet/vnet.Net. - -## TODO / Next Step -* Implement TCP (TCPConn, Listen) -* Support of IPv6 -* Write a bunch of examples for building virtual networks. -* Add network impairment features (on Router) - - Introduce latency / jitter - - Packet filtering handler (allow selectively drop packets, etc.) -* Add statistics data retrieval - - Total number of packets forward by each router - - Total number of packet loss - - Total number of connection failure (TCP) - -## References -* [Comparing Simulated Packet Loss and RealWorld Network Congestion](https://www.riverbed.com/document/fpo/WhitePaper-Riverbed-SimulatedPacketLoss.pdf) -* [wireguard-go using GVisor's netstack](https://github.com/WireGuard/wireguard-go/tree/master/tun/netstack) \ No newline at end of file diff --git a/vendor/github.com/pion/transport/v2/vnet/chunk.go b/vendor/github.com/pion/transport/v2/vnet/chunk.go deleted file mode 100644 index 9f59c9ce..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/chunk.go +++ /dev/null @@ -1,286 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "fmt" - "net" - "strconv" - "strings" - "sync/atomic" - "time" -) - -type tcpFlag uint8 - -const ( - tcpFIN tcpFlag = 0x01 - tcpSYN tcpFlag = 0x02 - tcpRST tcpFlag = 0x04 - tcpPSH tcpFlag = 0x08 - tcpACK tcpFlag = 0x10 -) - -func (f tcpFlag) String() string { - var sa []string - if f&tcpFIN != 0 { - sa = append(sa, "FIN") - } - if f&tcpSYN != 0 { - sa = append(sa, "SYN") - } - if f&tcpRST != 0 { - sa = append(sa, "RST") - } - if f&tcpPSH != 0 { - sa = append(sa, "PSH") - } - if f&tcpACK != 0 { - sa = append(sa, "ACK") - } - - return strings.Join(sa, "-") -} - -// Generate a base36-encoded unique tag -// See: https://play.golang.org/p/0ZaAID1q-HN -var assignChunkTag = func() func() string { //nolint:gochecknoglobals - var tagCtr uint64 - - return func() string { - n := atomic.AddUint64(&tagCtr, 1) - return strconv.FormatUint(n, 36) - } -}() - -// Chunk represents a packet passed around in the vnet -type Chunk interface { - setTimestamp() time.Time // used by router - getTimestamp() time.Time // used by router - getSourceIP() net.IP // used by router - getDestinationIP() net.IP // used by router - setSourceAddr(address string) error // used by nat - setDestinationAddr(address string) error // used by nat - - SourceAddr() net.Addr - DestinationAddr() net.Addr - UserData() []byte - Tag() string - Clone() Chunk - Network() string // returns "udp" or "tcp" - String() string -} - -type chunkIP struct { - timestamp time.Time - sourceIP net.IP - destinationIP net.IP - tag string -} - -func (c *chunkIP) setTimestamp() time.Time { - c.timestamp = time.Now() - return c.timestamp -} - -func (c *chunkIP) getTimestamp() time.Time { - return c.timestamp -} - -func (c *chunkIP) getDestinationIP() net.IP { - return c.destinationIP -} - -func (c *chunkIP) getSourceIP() net.IP { - return c.sourceIP -} - -func (c *chunkIP) Tag() string { - return c.tag -} - -type chunkUDP struct { - chunkIP - sourcePort int - destinationPort int - userData []byte -} - -func newChunkUDP(srcAddr, dstAddr *net.UDPAddr) *chunkUDP { - return &chunkUDP{ - chunkIP: chunkIP{ - sourceIP: srcAddr.IP, - destinationIP: dstAddr.IP, - tag: assignChunkTag(), - }, - sourcePort: srcAddr.Port, - destinationPort: dstAddr.Port, - } -} - -func (c *chunkUDP) SourceAddr() net.Addr { - return &net.UDPAddr{ - IP: c.sourceIP, - Port: c.sourcePort, - } -} - -func (c *chunkUDP) DestinationAddr() net.Addr { - return &net.UDPAddr{ - IP: c.destinationIP, - Port: c.destinationPort, - } -} - -func (c *chunkUDP) UserData() []byte { - return c.userData -} - -func (c *chunkUDP) Clone() Chunk { - var userData []byte - if c.userData != nil { - userData = make([]byte, len(c.userData)) - copy(userData, c.userData) - } - - return &chunkUDP{ - chunkIP: chunkIP{ - timestamp: c.timestamp, - sourceIP: c.sourceIP, - destinationIP: c.destinationIP, - tag: c.tag, - }, - sourcePort: c.sourcePort, - destinationPort: c.destinationPort, - userData: userData, - } -} - -func (c *chunkUDP) Network() string { - return udp -} - -func (c *chunkUDP) String() string { - src := c.SourceAddr() - dst := c.DestinationAddr() - return fmt.Sprintf("%s chunk %s %s => %s", - src.Network(), - c.tag, - src.String(), - dst.String(), - ) -} - -func (c *chunkUDP) setSourceAddr(address string) error { - addr, err := net.ResolveUDPAddr(udp, address) - if err != nil { - return err - } - c.sourceIP = addr.IP - c.sourcePort = addr.Port - return nil -} - -func (c *chunkUDP) setDestinationAddr(address string) error { - addr, err := net.ResolveUDPAddr(udp, address) - if err != nil { - return err - } - c.destinationIP = addr.IP - c.destinationPort = addr.Port - return nil -} - -type chunkTCP struct { - chunkIP - sourcePort int - destinationPort int - flags tcpFlag // control bits - userData []byte // only with PSH flag - // seq uint32 // always starts with 0 - // ack uint32 // always starts with 0 -} - -func newChunkTCP(srcAddr, dstAddr *net.TCPAddr, flags tcpFlag) *chunkTCP { - return &chunkTCP{ - chunkIP: chunkIP{ - sourceIP: srcAddr.IP, - destinationIP: dstAddr.IP, - tag: assignChunkTag(), - }, - sourcePort: srcAddr.Port, - destinationPort: dstAddr.Port, - flags: flags, - } -} - -func (c *chunkTCP) SourceAddr() net.Addr { - return &net.TCPAddr{ - IP: c.sourceIP, - Port: c.sourcePort, - } -} - -func (c *chunkTCP) DestinationAddr() net.Addr { - return &net.TCPAddr{ - IP: c.destinationIP, - Port: c.destinationPort, - } -} - -func (c *chunkTCP) UserData() []byte { - return c.userData -} - -func (c *chunkTCP) Clone() Chunk { - userData := make([]byte, len(c.userData)) - copy(userData, c.userData) - - return &chunkTCP{ - chunkIP: chunkIP{ - timestamp: c.timestamp, - sourceIP: c.sourceIP, - destinationIP: c.destinationIP, - }, - sourcePort: c.sourcePort, - destinationPort: c.destinationPort, - userData: userData, - } -} - -func (c *chunkTCP) Network() string { - return "tcp" -} - -func (c *chunkTCP) String() string { - src := c.SourceAddr() - dst := c.DestinationAddr() - return fmt.Sprintf("%s %s chunk %s %s => %s", - src.Network(), - c.flags.String(), - c.tag, - src.String(), - dst.String(), - ) -} - -func (c *chunkTCP) setSourceAddr(address string) error { - addr, err := net.ResolveTCPAddr("tcp", address) - if err != nil { - return err - } - c.sourceIP = addr.IP - c.sourcePort = addr.Port - return nil -} - -func (c *chunkTCP) setDestinationAddr(address string) error { - addr, err := net.ResolveTCPAddr("tcp", address) - if err != nil { - return err - } - c.destinationIP = addr.IP - c.destinationPort = addr.Port - return nil -} diff --git a/vendor/github.com/pion/transport/v2/vnet/chunk_queue.go b/vendor/github.com/pion/transport/v2/vnet/chunk_queue.go deleted file mode 100644 index 2393254a..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/chunk_queue.go +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "sync" -) - -type chunkQueue struct { - chunks []Chunk - maxSize int // 0 or negative value: unlimited - maxBytes int // 0 or negative value: unlimited - currentBytes int - mutex sync.RWMutex -} - -func newChunkQueue(maxSize int, maxBytes int) *chunkQueue { - return &chunkQueue{ - chunks: []Chunk{}, - maxSize: maxSize, - maxBytes: maxBytes, - currentBytes: 0, - mutex: sync.RWMutex{}, - } -} - -func (q *chunkQueue) push(c Chunk) bool { - q.mutex.Lock() - defer q.mutex.Unlock() - - if q.maxSize > 0 && len(q.chunks) >= q.maxSize { - return false // dropped - } - if q.maxBytes > 0 && q.currentBytes+len(c.UserData()) >= q.maxBytes { - return false - } - - q.currentBytes += len(c.UserData()) - q.chunks = append(q.chunks, c) - return true -} - -func (q *chunkQueue) pop() (Chunk, bool) { - q.mutex.Lock() - defer q.mutex.Unlock() - - if len(q.chunks) == 0 { - return nil, false - } - - c := q.chunks[0] - q.chunks = q.chunks[1:] - q.currentBytes -= len(c.UserData()) - - return c, true -} - -func (q *chunkQueue) peek() Chunk { - q.mutex.RLock() - defer q.mutex.RUnlock() - - if len(q.chunks) == 0 { - return nil - } - - return q.chunks[0] -} diff --git a/vendor/github.com/pion/transport/v2/vnet/conn.go b/vendor/github.com/pion/transport/v2/vnet/conn.go deleted file mode 100644 index 8f6f3426..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/conn.go +++ /dev/null @@ -1,298 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "errors" - "fmt" - "io" - "math" - "net" - "sync" - "time" - - "github.com/pion/transport/v2" -) - -const ( - maxReadQueueSize = 1024 -) - -var ( - errObsCannotBeNil = errors.New("obs cannot be nil") - errUseClosedNetworkConn = errors.New("use of closed network connection") - errAddrNotUDPAddr = errors.New("addr is not a net.UDPAddr") - errLocAddr = errors.New("something went wrong with locAddr") - errAlreadyClosed = errors.New("already closed") - errNoRemAddr = errors.New("no remAddr defined") -) - -// vNet implements this -type connObserver interface { - write(c Chunk) error - onClosed(addr net.Addr) - determineSourceIP(locIP, dstIP net.IP) net.IP -} - -// UDPConn is the implementation of the Conn and PacketConn interfaces for UDP network connections. -// compatible with net.PacketConn and net.Conn -type UDPConn struct { - locAddr *net.UDPAddr // read-only - remAddr *net.UDPAddr // read-only - obs connObserver // read-only - readCh chan Chunk // thread-safe - closed bool // requires mutex - mu sync.Mutex // to mutex closed flag - readTimer *time.Timer // thread-safe -} - -var _ transport.UDPConn = &UDPConn{} - -func newUDPConn(locAddr, remAddr *net.UDPAddr, obs connObserver) (*UDPConn, error) { - if obs == nil { - return nil, errObsCannotBeNil - } - - return &UDPConn{ - locAddr: locAddr, - remAddr: remAddr, - obs: obs, - readCh: make(chan Chunk, maxReadQueueSize), - readTimer: time.NewTimer(time.Duration(math.MaxInt64)), - }, nil -} - -// Close closes the connection. -// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. -func (c *UDPConn) Close() error { - c.mu.Lock() - defer c.mu.Unlock() - - if c.closed { - return errAlreadyClosed - } - c.closed = true - close(c.readCh) - - c.obs.onClosed(c.locAddr) - return nil -} - -// LocalAddr returns the local network address. -func (c *UDPConn) LocalAddr() net.Addr { - return c.locAddr -} - -// RemoteAddr returns the remote network address. -func (c *UDPConn) RemoteAddr() net.Addr { - return c.remAddr -} - -// SetDeadline sets the read and write deadlines associated -// with the connection. It is equivalent to calling both -// SetReadDeadline and SetWriteDeadline. -// -// A deadline is an absolute time after which I/O operations -// fail with a timeout (see type Error) instead of -// blocking. The deadline applies to all future and pending -// I/O, not just the immediately following call to ReadFrom or -// WriteTo. After a deadline has been exceeded, the connection -// can be refreshed by setting a deadline in the future. -// -// An idle timeout can be implemented by repeatedly extending -// the deadline after successful ReadFrom or WriteTo calls. -// -// A zero value for t means I/O operations will not time out. -func (c *UDPConn) SetDeadline(t time.Time) error { - return c.SetReadDeadline(t) -} - -// SetReadDeadline sets the deadline for future ReadFrom calls -// and any currently-blocked ReadFrom call. -// A zero value for t means ReadFrom will not time out. -func (c *UDPConn) SetReadDeadline(t time.Time) error { - var d time.Duration - var noDeadline time.Time - if t == noDeadline { - d = time.Duration(math.MaxInt64) - } else { - d = time.Until(t) - } - c.readTimer.Reset(d) - return nil -} - -// SetWriteDeadline sets the deadline for future WriteTo calls -// and any currently-blocked WriteTo call. -// Even if write times out, it may return n > 0, indicating that -// some of the data was successfully written. -// A zero value for t means WriteTo will not time out. -func (c *UDPConn) SetWriteDeadline(time.Time) error { - // Write never blocks. - return nil -} - -// Read reads data from the connection. -// Read can be made to time out and return an Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetReadDeadline. -func (c *UDPConn) Read(b []byte) (int, error) { - n, _, err := c.ReadFrom(b) - return n, err -} - -// ReadFrom reads a packet from the connection, -// copying the payload into p. It returns the number of -// bytes copied into p and the return address that -// was on the packet. -// It returns the number of bytes read (0 <= n <= len(p)) -// and any error encountered. Callers should always process -// the n > 0 bytes returned before considering the error err. -// ReadFrom can be made to time out and return -// an Error with Timeout() == true after a fixed time limit; -// see SetDeadline and SetReadDeadline. -func (c *UDPConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { -loop: - for { - select { - case chunk, ok := <-c.readCh: - if !ok { - break loop - } - var err error - n := copy(p, chunk.UserData()) - addr := chunk.SourceAddr() - if n < len(chunk.UserData()) { - err = io.ErrShortBuffer - } - - if c.remAddr != nil { - if addr.String() != c.remAddr.String() { - break // discard (shouldn't happen) - } - } - return n, addr, err - - case <-c.readTimer.C: - return 0, nil, &net.OpError{ - Op: "read", - Net: c.locAddr.Network(), - Addr: c.locAddr, - Err: newTimeoutError("i/o timeout"), - } - } - } - - return 0, nil, &net.OpError{ - Op: "read", - Net: c.locAddr.Network(), - Addr: c.locAddr, - Err: errUseClosedNetworkConn, - } -} - -// ReadFromUDP acts like ReadFrom but returns a UDPAddr. -func (c *UDPConn) ReadFromUDP(b []byte) (int, *net.UDPAddr, error) { - n, addr, err := c.ReadFrom(b) - - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - return -1, nil, fmt.Errorf("%w: %s", transport.ErrNotUDPAddress, addr) - } - - return n, udpAddr, err -} - -// ReadMsgUDP reads a message from c, copying the payload into b and -// the associated out-of-band data into oob. It returns the number of -// bytes copied into b, the number of bytes copied into oob, the flags -// that were set on the message and the source address of the message. -// -// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be -// used to manipulate IP-level socket options in oob. -func (c *UDPConn) ReadMsgUDP([]byte, []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) { - return -1, -1, -1, nil, transport.ErrNotSupported -} - -// Write writes data to the connection. -// Write can be made to time out and return an Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetWriteDeadline. -func (c *UDPConn) Write(b []byte) (int, error) { - if c.remAddr == nil { - return 0, errNoRemAddr - } - - return c.WriteTo(b, c.remAddr) -} - -// WriteTo writes a packet with payload p to addr. -// WriteTo can be made to time out and return -// an Error with Timeout() == true after a fixed time limit; -// see SetDeadline and SetWriteDeadline. -// On packet-oriented connections, write timeouts are rare. -func (c *UDPConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { - dstAddr, ok := addr.(*net.UDPAddr) - if !ok { - return 0, errAddrNotUDPAddr - } - - srcIP := c.obs.determineSourceIP(c.locAddr.IP, dstAddr.IP) - if srcIP == nil { - return 0, errLocAddr - } - srcAddr := &net.UDPAddr{ - IP: srcIP, - Port: c.locAddr.Port, - } - - chunk := newChunkUDP(srcAddr, dstAddr) - chunk.userData = make([]byte, len(p)) - copy(chunk.userData, p) - if err := c.obs.write(chunk); err != nil { - return 0, err - } - return len(p), nil -} - -// WriteToUDP acts like WriteTo but takes a UDPAddr. -func (c *UDPConn) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) { - return c.WriteTo(b, addr) -} - -// WriteMsgUDP writes a message to addr via c if c isn't connected, or -// to c's remote address if c is connected (in which case addr must be -// nil). The payload is copied from b and the associated out-of-band -// data is copied from oob. It returns the number of payload and -// out-of-band bytes written. -// -// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be -// used to manipulate IP-level socket options in oob. -func (c *UDPConn) WriteMsgUDP([]byte, []byte, *net.UDPAddr) (n, oobn int, err error) { - return -1, -1, transport.ErrNotSupported -} - -// SetReadBuffer sets the size of the operating system's -// receive buffer associated with the connection. -func (c *UDPConn) SetReadBuffer(int) error { - return transport.ErrNotSupported -} - -// SetWriteBuffer sets the size of the operating system's -// transmit buffer associated with the connection. -func (c *UDPConn) SetWriteBuffer(int) error { - return transport.ErrNotSupported -} - -func (c *UDPConn) onInboundChunk(chunk Chunk) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.closed { - return - } - - select { - case c.readCh <- chunk: - default: - } -} diff --git a/vendor/github.com/pion/transport/v2/vnet/conn_map.go b/vendor/github.com/pion/transport/v2/vnet/conn_map.go deleted file mode 100644 index da22483e..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/conn_map.go +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "errors" - "net" - "sync" -) - -var ( - errAddressAlreadyInUse = errors.New("address already in use") - errNoSuchUDPConn = errors.New("no such UDPConn") - errCannotRemoveUnspecifiedIP = errors.New("cannot remove unspecified IP by the specified IP") -) - -type udpConnMap struct { - portMap map[int][]*UDPConn - mutex sync.RWMutex -} - -func newUDPConnMap() *udpConnMap { - return &udpConnMap{ - portMap: map[int][]*UDPConn{}, - } -} - -func (m *udpConnMap) insert(conn *UDPConn) error { - m.mutex.Lock() - defer m.mutex.Unlock() - - udpAddr := conn.LocalAddr().(*net.UDPAddr) //nolint:forcetypeassert - - // check if the port has a listener - conns, ok := m.portMap[udpAddr.Port] - if ok { - if udpAddr.IP.IsUnspecified() { - return errAddressAlreadyInUse - } - - for _, conn := range conns { - laddr := conn.LocalAddr().(*net.UDPAddr) //nolint:forcetypeassert - if laddr.IP.IsUnspecified() || laddr.IP.Equal(udpAddr.IP) { - return errAddressAlreadyInUse - } - } - - conns = append(conns, conn) - } else { - conns = []*UDPConn{conn} - } - - m.portMap[udpAddr.Port] = conns - return nil -} - -func (m *udpConnMap) find(addr net.Addr) (*UDPConn, bool) { - m.mutex.Lock() // could be RLock, but we have delete() op - defer m.mutex.Unlock() - - udpAddr := addr.(*net.UDPAddr) //nolint:forcetypeassert - - if conns, ok := m.portMap[udpAddr.Port]; ok { - if udpAddr.IP.IsUnspecified() { - // pick the first one appears in the iteration - if len(conns) == 0 { - // This can't happen! - delete(m.portMap, udpAddr.Port) - return nil, false - } - return conns[0], true - } - - for _, conn := range conns { - laddr := conn.LocalAddr().(*net.UDPAddr) //nolint:forcetypeassert - if laddr.IP.IsUnspecified() || laddr.IP.Equal(udpAddr.IP) { - return conn, ok - } - } - } - - return nil, false -} - -func (m *udpConnMap) delete(addr net.Addr) error { - m.mutex.Lock() - defer m.mutex.Unlock() - - udpAddr := addr.(*net.UDPAddr) //nolint:forcetypeassert - - conns, ok := m.portMap[udpAddr.Port] - if !ok { - return errNoSuchUDPConn - } - - if udpAddr.IP.IsUnspecified() { - // remove all from this port - delete(m.portMap, udpAddr.Port) - return nil - } - - newConns := []*UDPConn{} - - for _, conn := range conns { - laddr := conn.LocalAddr().(*net.UDPAddr) //nolint:forcetypeassert - if laddr.IP.IsUnspecified() { - // This can't happen! - return errCannotRemoveUnspecifiedIP - } - - if laddr.IP.Equal(udpAddr.IP) { - continue - } - - newConns = append(newConns, conn) - } - - if len(newConns) == 0 { - delete(m.portMap, udpAddr.Port) - } else { - m.portMap[udpAddr.Port] = newConns - } - - return nil -} - -// size returns the number of UDPConns (UDP listeners) -func (m *udpConnMap) size() int { - m.mutex.RLock() - defer m.mutex.RUnlock() - - n := 0 - for _, conns := range m.portMap { - n += len(conns) - } - - return n -} diff --git a/vendor/github.com/pion/transport/v2/vnet/delay_filter.go b/vendor/github.com/pion/transport/v2/vnet/delay_filter.go deleted file mode 100644 index 119e34ea..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/delay_filter.go +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "context" - "time" -) - -// DelayFilter delays outgoing packets by the given delay. Run must be called -// before any packets will be forwarded. -type DelayFilter struct { - NIC - delay time.Duration - push chan struct{} - queue *chunkQueue -} - -type timedChunk struct { - Chunk - deadline time.Time -} - -// NewDelayFilter creates a new DelayFilter with the given nic and delay. -func NewDelayFilter(nic NIC, delay time.Duration) (*DelayFilter, error) { - return &DelayFilter{ - NIC: nic, - delay: delay, - push: make(chan struct{}), - queue: newChunkQueue(0, 0), - }, nil -} - -func (f *DelayFilter) onInboundChunk(c Chunk) { - f.queue.push(timedChunk{ - Chunk: c, - deadline: time.Now().Add(f.delay), - }) - f.push <- struct{}{} -} - -// Run starts forwarding of packets. Packets will be forwarded if they spent -// >delay time in the internal queue. Must be called before any packet will be -// forwarded. -func (f *DelayFilter) Run(ctx context.Context) { - timer := time.NewTimer(0) - for { - select { - case <-ctx.Done(): - return - case <-f.push: - next := f.queue.peek().(timedChunk) //nolint:forcetypeassert - if !timer.Stop() { - <-timer.C - } - timer.Reset(time.Until(next.deadline)) - case now := <-timer.C: - next := f.queue.peek() - if next == nil { - timer.Reset(time.Minute) - continue - } - if n, ok := next.(timedChunk); ok && n.deadline.Before(now) { - f.queue.pop() // ignore result because we already got and casted it from peek - f.NIC.onInboundChunk(n.Chunk) - } - next = f.queue.peek() - if next == nil { - timer.Reset(time.Minute) - continue - } - if n, ok := next.(timedChunk); ok { - timer.Reset(time.Until(n.deadline)) - } - } - } -} diff --git a/vendor/github.com/pion/transport/v2/vnet/errors.go b/vendor/github.com/pion/transport/v2/vnet/errors.go deleted file mode 100644 index 22c7c2d3..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/errors.go +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -type timeoutError struct { - msg string -} - -func newTimeoutError(msg string) error { - return &timeoutError{ - msg: msg, - } -} - -func (e *timeoutError) Error() string { - return e.msg -} - -func (e *timeoutError) Timeout() bool { - return true -} diff --git a/vendor/github.com/pion/transport/v2/vnet/loss_filter.go b/vendor/github.com/pion/transport/v2/vnet/loss_filter.go deleted file mode 100644 index 4b2d75f3..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/loss_filter.go +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "math/rand" - "time" -) - -// LossFilter is a wrapper around NICs, that drops some of the packets passed to -// onInboundChunk -type LossFilter struct { - NIC - chance int -} - -// NewLossFilter creates a new LossFilter that drops every packet with a -// probability of chance/100. Every packet that is not dropped is passed on to -// the given NIC. -func NewLossFilter(nic NIC, chance int) (*LossFilter, error) { - f := &LossFilter{ - NIC: nic, - chance: chance, - } - rand.Seed(time.Now().UTC().UnixNano()) - return f, nil -} - -func (f *LossFilter) onInboundChunk(c Chunk) { - if rand.Intn(100) < f.chance { //nolint:gosec - return - } - - f.NIC.onInboundChunk(c) -} diff --git a/vendor/github.com/pion/transport/v2/vnet/nat.go b/vendor/github.com/pion/transport/v2/vnet/nat.go deleted file mode 100644 index a4be36ec..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/nat.go +++ /dev/null @@ -1,342 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "errors" - "fmt" - "net" - "sync" - "time" - - "github.com/pion/logging" -) - -var ( - errNATRequriesMapping = errors.New("1:1 NAT requires more than one mapping") - errMismatchLengthIP = errors.New("length mismtach between mappedIPs and localIPs") - errNonUDPTranslationNotSupported = errors.New("non-udp translation is not supported yet") - errNoAssociatedLocalAddress = errors.New("no associated local address") - errNoNATBindingFound = errors.New("no NAT binding found") - errHasNoPermission = errors.New("has no permission") -) - -// EndpointDependencyType defines a type of behavioral dependendency on the -// remote endpoint's IP address or port number. This is used for the two -// kinds of behaviors: -// - Port mapping behavior -// - Filtering behavior -// -// See: https://tools.ietf.org/html/rfc4787 -type EndpointDependencyType uint8 - -const ( - // EndpointIndependent means the behavior is independent of the endpoint's address or port - EndpointIndependent EndpointDependencyType = iota - // EndpointAddrDependent means the behavior is dependent on the endpoint's address - EndpointAddrDependent - // EndpointAddrPortDependent means the behavior is dependent on the endpoint's address and port - EndpointAddrPortDependent -) - -// NATMode defines basic behavior of the NAT -type NATMode uint8 - -const ( - // NATModeNormal means the NAT behaves as a standard NAPT (RFC 2663). - NATModeNormal NATMode = iota - // NATModeNAT1To1 exhibits 1:1 DNAT where the external IP address is statically mapped to - // a specific local IP address with port number is preserved always between them. - // When this mode is selected, MappingBehavior, FilteringBehavior, PortPreservation and - // MappingLifeTime of NATType are ignored. - NATModeNAT1To1 -) - -const ( - defaultNATMappingLifeTime = 30 * time.Second -) - -// NATType has a set of parameters that define the behavior of NAT. -type NATType struct { - Mode NATMode - MappingBehavior EndpointDependencyType - FilteringBehavior EndpointDependencyType - Hairpinning bool // Not implemented yet - PortPreservation bool // Not implemented yet - MappingLifeTime time.Duration -} - -type natConfig struct { - name string - natType NATType - mappedIPs []net.IP // mapped IPv4 - localIPs []net.IP // local IPv4, required only when the mode is NATModeNAT1To1 - loggerFactory logging.LoggerFactory -} - -type mapping struct { - proto string // "udp" or "tcp" - local string // ":" - mapped string // ":" - bound string // key: "[[:]]" - filters map[string]struct{} // key: "[[:]]" - expires time.Time // time to expire -} - -type networkAddressTranslator struct { - name string - natType NATType - mappedIPs []net.IP // mapped IPv4 - localIPs []net.IP // local IPv4, required only when the mode is NATModeNAT1To1 - outboundMap map[string]*mapping // key: "::[:remote-ip[:remote-port]] - inboundMap map[string]*mapping // key: "::" - udpPortCounter int - mutex sync.RWMutex - log logging.LeveledLogger -} - -func newNAT(config *natConfig) (*networkAddressTranslator, error) { - natType := config.natType - - if natType.Mode == NATModeNAT1To1 { - // 1:1 NAT behavior - natType.MappingBehavior = EndpointIndependent - natType.FilteringBehavior = EndpointIndependent - natType.PortPreservation = true - natType.MappingLifeTime = 0 - - if len(config.mappedIPs) == 0 { - return nil, errNATRequriesMapping - } - if len(config.mappedIPs) != len(config.localIPs) { - return nil, errMismatchLengthIP - } - } else { - // Normal (NAPT) behavior - natType.Mode = NATModeNormal - if natType.MappingLifeTime == 0 { - natType.MappingLifeTime = defaultNATMappingLifeTime - } - } - - return &networkAddressTranslator{ - name: config.name, - natType: natType, - mappedIPs: config.mappedIPs, - localIPs: config.localIPs, - outboundMap: map[string]*mapping{}, - inboundMap: map[string]*mapping{}, - log: config.loggerFactory.NewLogger("vnet"), - }, nil -} - -func (n *networkAddressTranslator) getPairedMappedIP(locIP net.IP) net.IP { - for i, ip := range n.localIPs { - if ip.Equal(locIP) { - return n.mappedIPs[i] - } - } - return nil -} - -func (n *networkAddressTranslator) getPairedLocalIP(mappedIP net.IP) net.IP { - for i, ip := range n.mappedIPs { - if ip.Equal(mappedIP) { - return n.localIPs[i] - } - } - return nil -} - -func (n *networkAddressTranslator) translateOutbound(from Chunk) (Chunk, error) { - n.mutex.Lock() - defer n.mutex.Unlock() - - to := from.Clone() - - if from.Network() == udp { - if n.natType.Mode == NATModeNAT1To1 { - // 1:1 NAT behavior - srcAddr := from.SourceAddr().(*net.UDPAddr) //nolint:forcetypeassert - srcIP := n.getPairedMappedIP(srcAddr.IP) - if srcIP == nil { - n.log.Debugf("[%s] drop outbound chunk %s with not route", n.name, from.String()) - return nil, nil // nolint:nilnil - } - srcPort := srcAddr.Port - if err := to.setSourceAddr(fmt.Sprintf("%s:%d", srcIP.String(), srcPort)); err != nil { - return nil, err - } - } else { - // Normal (NAPT) behavior - var bound, filterKey string - switch n.natType.MappingBehavior { - case EndpointIndependent: - bound = "" - case EndpointAddrDependent: - bound = from.getDestinationIP().String() - case EndpointAddrPortDependent: - bound = from.DestinationAddr().String() - } - - switch n.natType.FilteringBehavior { - case EndpointIndependent: - filterKey = "" - case EndpointAddrDependent: - filterKey = from.getDestinationIP().String() - case EndpointAddrPortDependent: - filterKey = from.DestinationAddr().String() - } - - oKey := fmt.Sprintf("udp:%s:%s", from.SourceAddr().String(), bound) - - m := n.findOutboundMapping(oKey) - if m == nil { - // Create a new mapping - mappedPort := 0xC000 + n.udpPortCounter - n.udpPortCounter++ - - m = &mapping{ - proto: from.SourceAddr().Network(), - local: from.SourceAddr().String(), - bound: bound, - mapped: fmt.Sprintf("%s:%d", n.mappedIPs[0].String(), mappedPort), - filters: map[string]struct{}{}, - expires: time.Now().Add(n.natType.MappingLifeTime), - } - - n.outboundMap[oKey] = m - - iKey := fmt.Sprintf("udp:%s", m.mapped) - - n.log.Debugf("[%s] created a new NAT binding oKey=%s iKey=%s", - n.name, - oKey, - iKey) - - m.filters[filterKey] = struct{}{} - n.log.Debugf("[%s] permit access from %s to %s", n.name, filterKey, m.mapped) - n.inboundMap[iKey] = m - } else if _, ok := m.filters[filterKey]; !ok { - n.log.Debugf("[%s] permit access from %s to %s", n.name, filterKey, m.mapped) - m.filters[filterKey] = struct{}{} - } - - if err := to.setSourceAddr(m.mapped); err != nil { - return nil, err - } - } - - n.log.Debugf("[%s] translate outbound chunk from %s to %s", n.name, from.String(), to.String()) - - return to, nil - } - - return nil, errNonUDPTranslationNotSupported -} - -func (n *networkAddressTranslator) translateInbound(from Chunk) (Chunk, error) { - n.mutex.Lock() - defer n.mutex.Unlock() - - to := from.Clone() - - if from.Network() == udp { - if n.natType.Mode == NATModeNAT1To1 { - // 1:1 NAT behavior - dstAddr := from.DestinationAddr().(*net.UDPAddr) //nolint:forcetypeassert - dstIP := n.getPairedLocalIP(dstAddr.IP) - if dstIP == nil { - return nil, fmt.Errorf("drop %s as %w", from.String(), errNoAssociatedLocalAddress) - } - dstPort := from.DestinationAddr().(*net.UDPAddr).Port //nolint:forcetypeassert - if err := to.setDestinationAddr(fmt.Sprintf("%s:%d", dstIP, dstPort)); err != nil { - return nil, err - } - } else { - // Normal (NAPT) behavior - iKey := fmt.Sprintf("udp:%s", from.DestinationAddr().String()) - m := n.findInboundMapping(iKey) - if m == nil { - return nil, fmt.Errorf("drop %s as %w", from.String(), errNoNATBindingFound) - } - - var filterKey string - switch n.natType.FilteringBehavior { - case EndpointIndependent: - filterKey = "" - case EndpointAddrDependent: - filterKey = from.getSourceIP().String() - case EndpointAddrPortDependent: - filterKey = from.SourceAddr().String() - } - - if _, ok := m.filters[filterKey]; !ok { - return nil, fmt.Errorf("drop %s as the remote %s %w", from.String(), filterKey, errHasNoPermission) - } - - // See RFC 4847 Section 4.3. Mapping Refresh - // a) Inbound refresh may be useful for applications with no outgoing - // UDP traffic. However, allowing inbound refresh may allow an - // external attacker or misbehaving application to keep a mapping - // alive indefinitely. This may be a security risk. Also, if the - // process is repeated with different ports, over time, it could - // use up all the ports on the NAT. - - if err := to.setDestinationAddr(m.local); err != nil { - return nil, err - } - } - - n.log.Debugf("[%s] translate inbound chunk from %s to %s", n.name, from.String(), to.String()) - - return to, nil - } - - return nil, errNonUDPTranslationNotSupported -} - -// caller must hold the mutex -func (n *networkAddressTranslator) findOutboundMapping(oKey string) *mapping { - now := time.Now() - - m, ok := n.outboundMap[oKey] - if ok { - // check if this mapping is expired - if now.After(m.expires) { - n.removeMapping(m) - m = nil // expired - } else { - m.expires = time.Now().Add(n.natType.MappingLifeTime) - } - } - - return m -} - -// caller must hold the mutex -func (n *networkAddressTranslator) findInboundMapping(iKey string) *mapping { - now := time.Now() - m, ok := n.inboundMap[iKey] - if !ok { - return nil - } - - // check if this mapping is expired - if now.After(m.expires) { - n.removeMapping(m) - return nil - } - - return m -} - -// caller must hold the mutex -func (n *networkAddressTranslator) removeMapping(m *mapping) { - oKey := fmt.Sprintf("%s:%s:%s", m.proto, m.local, m.bound) - iKey := fmt.Sprintf("%s:%s", m.proto, m.mapped) - - delete(n.outboundMap, oKey) - delete(n.inboundMap, iKey) -} diff --git a/vendor/github.com/pion/transport/v2/vnet/net.go b/vendor/github.com/pion/transport/v2/vnet/net.go deleted file mode 100644 index 5d0938e6..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/net.go +++ /dev/null @@ -1,618 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "encoding/binary" - "errors" - "fmt" - "math/rand" - "net" - "strconv" - "strings" - "sync" - - "github.com/pion/transport/v2" -) - -const ( - lo0String = "lo0String" - udp = "udp" - udp4 = "udp4" -) - -var ( - macAddrCounter uint64 = 0xBEEFED910200 //nolint:gochecknoglobals - errNoInterface = errors.New("no interface is available") - errUnexpectedNetwork = errors.New("unexpected network") - errCantAssignRequestedAddr = errors.New("can't assign requested address") - errUnknownNetwork = errors.New("unknown network") - errNoRouterLinked = errors.New("no router linked") - errInvalidPortNumber = errors.New("invalid port number") - errUnexpectedTypeSwitchFailure = errors.New("unexpected type-switch failure") - errBindFailedFor = errors.New("bind failed for") - errEndPortLessThanStart = errors.New("end port is less than the start") - errPortSpaceExhausted = errors.New("port space exhausted") -) - -func newMACAddress() net.HardwareAddr { - b := make([]byte, 8) - binary.BigEndian.PutUint64(b, macAddrCounter) - macAddrCounter++ - return b[2:] -} - -// Net represents a local network stack equivalent to a set of layers from NIC -// up to the transport (UDP / TCP) layer. -type Net struct { - interfaces []*transport.Interface // read-only - staticIPs []net.IP // read-only - router *Router // read-only - udpConns *udpConnMap // read-only - mutex sync.RWMutex -} - -// Compile-time assertion -var _ transport.Net = &Net{} - -func (v *Net) _getInterfaces() ([]*transport.Interface, error) { - if len(v.interfaces) == 0 { - return nil, errNoInterface - } - - return v.interfaces, nil -} - -// Interfaces returns a list of the system's network interfaces. -func (v *Net) Interfaces() ([]*transport.Interface, error) { - v.mutex.RLock() - defer v.mutex.RUnlock() - - return v._getInterfaces() -} - -// caller must hold the mutex (read) -func (v *Net) _getInterface(ifName string) (*transport.Interface, error) { - ifs, err := v._getInterfaces() - if err != nil { - return nil, err - } - for _, ifc := range ifs { - if ifc.Name == ifName { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: %s", transport.ErrInterfaceNotFound, ifName) -} - -func (v *Net) getInterface(ifName string) (*transport.Interface, error) { - v.mutex.RLock() - defer v.mutex.RUnlock() - - return v._getInterface(ifName) -} - -// InterfaceByIndex returns the interface specified by index. -// -// On Solaris, it returns one of the logical network interfaces -// sharing the logical data link; for more precision use -// InterfaceByName. -func (v *Net) InterfaceByIndex(index int) (*transport.Interface, error) { - for _, ifc := range v.interfaces { - if ifc.Index == index { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: index=%d", transport.ErrInterfaceNotFound, index) -} - -// InterfaceByName returns the interface specified by name. -func (v *Net) InterfaceByName(ifName string) (*transport.Interface, error) { - return v.getInterface(ifName) -} - -// caller must hold the mutex -func (v *Net) getAllIPAddrs(ipv6 bool) []net.IP { - ips := []net.IP{} - - for _, ifc := range v.interfaces { - addrs, err := ifc.Addrs() - if err != nil { - continue - } - - for _, addr := range addrs { - var ip net.IP - if ipNet, ok := addr.(*net.IPNet); ok { - ip = ipNet.IP - } else if ipAddr, ok := addr.(*net.IPAddr); ok { - ip = ipAddr.IP - } else { - continue - } - - if !ipv6 { - if ip.To4() != nil { - ips = append(ips, ip) - } - } - } - } - - return ips -} - -func (v *Net) setRouter(r *Router) error { - v.mutex.Lock() - defer v.mutex.Unlock() - - v.router = r - return nil -} - -func (v *Net) onInboundChunk(c Chunk) { - v.mutex.Lock() - defer v.mutex.Unlock() - - if c.Network() == udp { - if conn, ok := v.udpConns.find(c.DestinationAddr()); ok { - conn.onInboundChunk(c) - } - } -} - -// caller must hold the mutex -func (v *Net) _dialUDP(network string, locAddr, remAddr *net.UDPAddr) (transport.UDPConn, error) { - // validate network - if network != udp && network != udp4 { - return nil, fmt.Errorf("%w: %s", errUnexpectedNetwork, network) - } - - if locAddr == nil { - locAddr = &net.UDPAddr{ - IP: net.IPv4zero, - } - } else if locAddr.IP == nil { - locAddr.IP = net.IPv4zero - } - - // validate address. do we have that address? - if !v.hasIPAddr(locAddr.IP) { - return nil, &net.OpError{ - Op: "listen", - Net: network, - Addr: locAddr, - Err: fmt.Errorf("bind: %w", errCantAssignRequestedAddr), - } - } - - if locAddr.Port == 0 { - // choose randomly from the range between 5000 and 5999 - port, err := v.assignPort(locAddr.IP, 5000, 5999) - if err != nil { - return nil, &net.OpError{ - Op: "listen", - Net: network, - Addr: locAddr, - Err: err, - } - } - locAddr.Port = port - } else if _, ok := v.udpConns.find(locAddr); ok { - return nil, &net.OpError{ - Op: "listen", - Net: network, - Addr: locAddr, - Err: fmt.Errorf("bind: %w", errAddressAlreadyInUse), - } - } - - conn, err := newUDPConn(locAddr, remAddr, v) - if err != nil { - return nil, err - } - - err = v.udpConns.insert(conn) - if err != nil { - return nil, err - } - - return conn, nil -} - -// ListenPacket announces on the local network address. -func (v *Net) ListenPacket(network string, address string) (net.PacketConn, error) { - v.mutex.Lock() - defer v.mutex.Unlock() - - locAddr, err := v.ResolveUDPAddr(network, address) - if err != nil { - return nil, err - } - - return v._dialUDP(network, locAddr, nil) -} - -// ListenUDP acts like ListenPacket for UDP networks. -func (v *Net) ListenUDP(network string, locAddr *net.UDPAddr) (transport.UDPConn, error) { - v.mutex.Lock() - defer v.mutex.Unlock() - - return v._dialUDP(network, locAddr, nil) -} - -// DialUDP acts like Dial for UDP networks. -func (v *Net) DialUDP(network string, locAddr, remAddr *net.UDPAddr) (transport.UDPConn, error) { - v.mutex.Lock() - defer v.mutex.Unlock() - - return v._dialUDP(network, locAddr, remAddr) -} - -// Dial connects to the address on the named network. -func (v *Net) Dial(network string, address string) (net.Conn, error) { - v.mutex.Lock() - defer v.mutex.Unlock() - - remAddr, err := v.ResolveUDPAddr(network, address) - if err != nil { - return nil, err - } - - // Determine source address - srcIP := v.determineSourceIP(nil, remAddr.IP) - - locAddr := &net.UDPAddr{IP: srcIP, Port: 0} - - return v._dialUDP(network, locAddr, remAddr) -} - -// ResolveIPAddr returns an address of IP end point. -func (v *Net) ResolveIPAddr(_, address string) (*net.IPAddr, error) { - var err error - - // Check if host is a domain name - ip := net.ParseIP(address) - if ip == nil { - address = strings.ToLower(address) - if address == "localhost" { - ip = net.IPv4(127, 0, 0, 1) - } else { - // host is a domain name. resolve IP address by the name - if v.router == nil { - return nil, errNoRouterLinked - } - - ip, err = v.router.resolver.lookUp(address) - if err != nil { - return nil, err - } - } - } - - return &net.IPAddr{ - IP: ip, - }, nil -} - -// ResolveUDPAddr returns an address of UDP end point. -func (v *Net) ResolveUDPAddr(network, address string) (*net.UDPAddr, error) { - if network != udp && network != udp4 { - return nil, fmt.Errorf("%w %s", errUnknownNetwork, network) - } - - host, sPort, err := net.SplitHostPort(address) - if err != nil { - return nil, err - } - - ipAddress, err := v.ResolveIPAddr("ip", host) - if err != nil { - return nil, err - } - - port, err := strconv.Atoi(sPort) - if err != nil { - return nil, errInvalidPortNumber - } - - udpAddr := &net.UDPAddr{ - IP: ipAddress.IP, - Zone: ipAddress.Zone, - Port: port, - } - - return udpAddr, nil -} - -// ResolveTCPAddr returns an address of TCP end point. -func (v *Net) ResolveTCPAddr(network, address string) (*net.TCPAddr, error) { - if network != udp && network != "udp4" { - return nil, fmt.Errorf("%w %s", errUnknownNetwork, network) - } - - host, sPort, err := net.SplitHostPort(address) - if err != nil { - return nil, err - } - - ipAddr, err := v.ResolveIPAddr("ip", host) - if err != nil { - return nil, err - } - - port, err := strconv.Atoi(sPort) - if err != nil { - return nil, errInvalidPortNumber - } - - udpAddr := &net.TCPAddr{ - IP: ipAddr.IP, - Zone: ipAddr.Zone, - Port: port, - } - - return udpAddr, nil -} - -func (v *Net) write(c Chunk) error { - if c.Network() == udp { - if udp, ok := c.(*chunkUDP); ok { - if c.getDestinationIP().IsLoopback() { - if conn, ok := v.udpConns.find(udp.DestinationAddr()); ok { - conn.onInboundChunk(udp) - } - return nil - } - } else { - return errUnexpectedTypeSwitchFailure - } - } - - if v.router == nil { - return errNoRouterLinked - } - - v.router.push(c) - return nil -} - -func (v *Net) onClosed(addr net.Addr) { - if addr.Network() == udp { - //nolint:errcheck - v.udpConns.delete(addr) // #nosec - } -} - -// This method determines the srcIP based on the dstIP when locIP -// is any IP address ("0.0.0.0" or "::"). If locIP is a non-any addr, -// this method simply returns locIP. -// caller must hold the mutex -func (v *Net) determineSourceIP(locIP, dstIP net.IP) net.IP { - if locIP != nil && !locIP.IsUnspecified() { - return locIP - } - - var srcIP net.IP - - if dstIP.IsLoopback() { - srcIP = net.ParseIP("127.0.0.1") - } else { - ifc, err2 := v._getInterface("eth0") - if err2 != nil { - return nil - } - - addrs, err2 := ifc.Addrs() - if err2 != nil { - return nil - } - - if len(addrs) == 0 { - return nil - } - - var findIPv4 bool - if locIP != nil { - findIPv4 = (locIP.To4() != nil) - } else { - findIPv4 = (dstIP.To4() != nil) - } - - for _, addr := range addrs { - ip := addr.(*net.IPNet).IP //nolint:forcetypeassert - if findIPv4 { - if ip.To4() != nil { - srcIP = ip - break - } - } else { - if ip.To4() == nil { - srcIP = ip - break - } - } - } - } - - return srcIP -} - -// caller must hold the mutex -func (v *Net) hasIPAddr(ip net.IP) bool { //nolint:gocognit - for _, ifc := range v.interfaces { - if addrs, err := ifc.Addrs(); err == nil { - for _, addr := range addrs { - var locIP net.IP - if ipNet, ok := addr.(*net.IPNet); ok { - locIP = ipNet.IP - } else if ipAddr, ok := addr.(*net.IPAddr); ok { - locIP = ipAddr.IP - } else { - continue - } - - switch ip.String() { - case "0.0.0.0": - if locIP.To4() != nil { - return true - } - case "::": - if locIP.To4() == nil { - return true - } - default: - if locIP.Equal(ip) { - return true - } - } - } - } - } - - return false -} - -// caller must hold the mutex -func (v *Net) allocateLocalAddr(ip net.IP, port int) error { - // gather local IP addresses to bind - var ips []net.IP - if ip.IsUnspecified() { - ips = v.getAllIPAddrs(ip.To4() == nil) - } else if v.hasIPAddr(ip) { - ips = []net.IP{ip} - } - - if len(ips) == 0 { - return fmt.Errorf("%w %s", errBindFailedFor, ip.String()) - } - - // check if all these transport addresses are not in use - for _, ip2 := range ips { - addr := &net.UDPAddr{ - IP: ip2, - Port: port, - } - if _, ok := v.udpConns.find(addr); ok { - return &net.OpError{ - Op: "bind", - Net: udp, - Addr: addr, - Err: fmt.Errorf("bind: %w", errAddressAlreadyInUse), - } - } - } - - return nil -} - -// caller must hold the mutex -func (v *Net) assignPort(ip net.IP, start, end int) (int, error) { - // choose randomly from the range between start and end (inclusive) - if end < start { - return -1, errEndPortLessThanStart - } - - space := end + 1 - start - offset := rand.Intn(space) //nolint:gosec - for i := 0; i < space; i++ { - port := ((offset + i) % space) + start - - err := v.allocateLocalAddr(ip, port) - if err == nil { - return port, nil - } - } - - return -1, errPortSpaceExhausted -} - -func (v *Net) getStaticIPs() []net.IP { - return v.staticIPs -} - -// NetConfig is a bag of configuration parameters passed to NewNet(). -type NetConfig struct { - // StaticIPs is an array of static IP addresses to be assigned for this Net. - // If no static IP address is given, the router will automatically assign - // an IP address. - StaticIPs []string - - // StaticIP is deprecated. Use StaticIPs. - StaticIP string -} - -// NewNet creates an instance of a virtual network. -// -// By design, it always have lo0 and eth0 interfaces. -// The lo0 has the address 127.0.0.1 assigned by default. -// IP address for eth0 will be assigned when this Net is added to a router. -func NewNet(config *NetConfig) (*Net, error) { - lo0 := transport.NewInterface(net.Interface{ - Index: 1, - MTU: 16384, - Name: lo0String, - HardwareAddr: nil, - Flags: net.FlagUp | net.FlagLoopback | net.FlagMulticast, - }) - lo0.AddAddress(&net.IPNet{ - IP: net.ParseIP("127.0.0.1"), - Mask: net.CIDRMask(8, 32), - }) - - eth0 := transport.NewInterface(net.Interface{ - Index: 2, - MTU: 1500, - Name: "eth0", - HardwareAddr: newMACAddress(), - Flags: net.FlagUp | net.FlagMulticast, - }) - - var staticIPs []net.IP - for _, ipStr := range config.StaticIPs { - if ip := net.ParseIP(ipStr); ip != nil { - staticIPs = append(staticIPs, ip) - } - } - if len(config.StaticIP) > 0 { - if ip := net.ParseIP(config.StaticIP); ip != nil { - staticIPs = append(staticIPs, ip) - } - } - - return &Net{ - interfaces: []*transport.Interface{lo0, eth0}, - staticIPs: staticIPs, - udpConns: newUDPConnMap(), - }, nil -} - -// DialTCP acts like Dial for TCP networks. -func (v *Net) DialTCP(string, *net.TCPAddr, *net.TCPAddr) (transport.TCPConn, error) { - return nil, transport.ErrNotSupported -} - -// ListenTCP acts like Listen for TCP networks. -func (v *Net) ListenTCP(string, *net.TCPAddr) (transport.TCPListener, error) { - return nil, transport.ErrNotSupported -} - -// CreateDialer creates an instance of vnet.Dialer -func (v *Net) CreateDialer(d *net.Dialer) transport.Dialer { - return &dialer{ - dialer: d, - net: v, - } -} - -type dialer struct { - dialer *net.Dialer - net *Net -} - -func (d *dialer) Dial(network, address string) (net.Conn, error) { - return d.net.Dial(network, address) -} diff --git a/vendor/github.com/pion/transport/v2/vnet/resolver.go b/vendor/github.com/pion/transport/v2/vnet/resolver.go deleted file mode 100644 index a391cc7f..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/resolver.go +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "errors" - "fmt" - "net" - "sync" - - "github.com/pion/logging" -) - -var ( - errHostnameEmpty = errors.New("host name must not be empty") - errFailedToParseIPAddr = errors.New("failed to parse IP address") -) - -type resolverConfig struct { - LoggerFactory logging.LoggerFactory -} - -type resolver struct { - parent *resolver // read-only - hosts map[string]net.IP // requires mutex - mutex sync.RWMutex // thread-safe - log logging.LeveledLogger // read-only -} - -func newResolver(config *resolverConfig) *resolver { - r := &resolver{ - hosts: map[string]net.IP{}, - log: config.LoggerFactory.NewLogger("vnet"), - } - - if err := r.addHost("localhost", "127.0.0.1"); err != nil { - r.log.Warn("failed to add localhost to resolver") - } - return r -} - -func (r *resolver) setParent(parent *resolver) { - r.mutex.Lock() - defer r.mutex.Unlock() - - r.parent = parent -} - -func (r *resolver) addHost(name string, ipAddr string) error { - r.mutex.Lock() - defer r.mutex.Unlock() - - if len(name) == 0 { - return errHostnameEmpty - } - ip := net.ParseIP(ipAddr) - if ip == nil { - return fmt.Errorf("%w \"%s\"", errFailedToParseIPAddr, ipAddr) - } - r.hosts[name] = ip - return nil -} - -func (r *resolver) lookUp(hostName string) (net.IP, error) { - ip := func() net.IP { - r.mutex.RLock() - defer r.mutex.RUnlock() - - if ip2, ok := r.hosts[hostName]; ok { - return ip2 - } - return nil - }() - if ip != nil { - return ip, nil - } - - // mutex must be unlocked before calling into parent resolver - - if r.parent != nil { - return r.parent.lookUp(hostName) - } - - return nil, &net.DNSError{ - Err: "host not found", - Name: hostName, - Server: "vnet resolver", - IsTimeout: false, - IsTemporary: false, - } -} diff --git a/vendor/github.com/pion/transport/v2/vnet/router.go b/vendor/github.com/pion/transport/v2/vnet/router.go deleted file mode 100644 index cd4b88dc..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/router.go +++ /dev/null @@ -1,621 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "errors" - "fmt" - "math/rand" - "net" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/pion/logging" - "github.com/pion/transport/v2" -) - -const ( - defaultRouterQueueSize = 0 // unlimited -) - -var ( - errInvalidLocalIPinStaticIPs = errors.New("invalid local IP in StaticIPs") - errLocalIPBeyondStaticIPsSubset = errors.New("mapped in StaticIPs is beyond subnet") - errLocalIPNoStaticsIPsAssociated = errors.New("all StaticIPs must have associated local IPs") - errRouterAlreadyStarted = errors.New("router already started") - errRouterAlreadyStopped = errors.New("router already stopped") - errStaticIPisBeyondSubnet = errors.New("static IP is beyond subnet") - errAddressSpaceExhausted = errors.New("address space exhausted") - errNoIPAddrEth0 = errors.New("no IP address is assigned for eth0") -) - -// Generate a unique router name -var assignRouterName = func() func() string { //nolint:gochecknoglobals - var routerIDCtr uint64 - - return func() string { - n := atomic.AddUint64(&routerIDCtr, 1) - return fmt.Sprintf("router%d", n) - } -}() - -// RouterConfig ... -type RouterConfig struct { - // Name of router. If not specified, a unique name will be assigned. - Name string - // CIDR notation, like "192.0.2.0/24" - CIDR string - // StaticIPs is an array of static IP addresses to be assigned for this router. - // If no static IP address is given, the router will automatically assign - // an IP address. - // This will be ignored if this router is the root. - StaticIPs []string - // StaticIP is deprecated. Use StaticIPs. - StaticIP string - // Internal queue size - QueueSize int - // Effective only when this router has a parent router - NATType *NATType - // Minimum Delay - MinDelay time.Duration - // Max Jitter - MaxJitter time.Duration - // Logger factory - LoggerFactory logging.LoggerFactory -} - -// NIC is a network interface controller that interfaces Router -type NIC interface { - getInterface(ifName string) (*transport.Interface, error) - onInboundChunk(c Chunk) - getStaticIPs() []net.IP - setRouter(r *Router) error -} - -// ChunkFilter is a handler users can add to filter chunks. -// If the filter returns false, the packet will be dropped. -type ChunkFilter func(c Chunk) bool - -// Router ... -type Router struct { - name string // read-only - interfaces []*transport.Interface // read-only - ipv4Net *net.IPNet // read-only - staticIPs []net.IP // read-only - staticLocalIPs map[string]net.IP // read-only, - lastID byte // requires mutex [x], used to assign the last digit of IPv4 address - queue *chunkQueue // read-only - parent *Router // read-only - children []*Router // read-only - natType *NATType // read-only - nat *networkAddressTranslator // read-only - nics map[string]NIC // read-only - stopFunc func() // requires mutex [x] - resolver *resolver // read-only - chunkFilters []ChunkFilter // requires mutex [x] - minDelay time.Duration // requires mutex [x] - maxJitter time.Duration // requires mutex [x] - mutex sync.RWMutex // thread-safe - pushCh chan struct{} // writer requires mutex - loggerFactory logging.LoggerFactory // read-only - log logging.LeveledLogger // read-only -} - -// NewRouter ... -func NewRouter(config *RouterConfig) (*Router, error) { - loggerFactory := config.LoggerFactory - log := loggerFactory.NewLogger("vnet") - - _, ipv4Net, err := net.ParseCIDR(config.CIDR) - if err != nil { - return nil, err - } - - queueSize := defaultRouterQueueSize - if config.QueueSize > 0 { - queueSize = config.QueueSize - } - - // set up network interface, lo0 - lo0 := transport.NewInterface(net.Interface{ - Index: 1, - MTU: 16384, - Name: lo0String, - HardwareAddr: nil, - Flags: net.FlagUp | net.FlagLoopback | net.FlagMulticast, - }) - lo0.AddAddress(&net.IPAddr{IP: net.ParseIP("127.0.0.1"), Zone: ""}) - - // set up network interface, eth0 - eth0 := transport.NewInterface(net.Interface{ - Index: 2, - MTU: 1500, - Name: "eth0", - HardwareAddr: newMACAddress(), - Flags: net.FlagUp | net.FlagMulticast, - }) - - // local host name resolver - resolver := newResolver(&resolverConfig{ - LoggerFactory: config.LoggerFactory, - }) - - name := config.Name - if len(name) == 0 { - name = assignRouterName() - } - - var staticIPs []net.IP - staticLocalIPs := map[string]net.IP{} - for _, ipStr := range config.StaticIPs { - ipPair := strings.Split(ipStr, "/") - if ip := net.ParseIP(ipPair[0]); ip != nil { - if len(ipPair) > 1 { - locIP := net.ParseIP(ipPair[1]) - if locIP == nil { - return nil, errInvalidLocalIPinStaticIPs - } - if !ipv4Net.Contains(locIP) { - return nil, fmt.Errorf("local IP %s %w", locIP.String(), errLocalIPBeyondStaticIPsSubset) - } - staticLocalIPs[ip.String()] = locIP - } - staticIPs = append(staticIPs, ip) - } - } - if len(config.StaticIP) > 0 { - log.Warn("StaticIP is deprecated. Use StaticIPs instead") - if ip := net.ParseIP(config.StaticIP); ip != nil { - staticIPs = append(staticIPs, ip) - } - } - - if nStaticLocal := len(staticLocalIPs); nStaticLocal > 0 { - if nStaticLocal != len(staticIPs) { - return nil, errLocalIPNoStaticsIPsAssociated - } - } - - return &Router{ - name: name, - interfaces: []*transport.Interface{lo0, eth0}, - ipv4Net: ipv4Net, - staticIPs: staticIPs, - staticLocalIPs: staticLocalIPs, - queue: newChunkQueue(queueSize, 0), - natType: config.NATType, - nics: map[string]NIC{}, - resolver: resolver, - minDelay: config.MinDelay, - maxJitter: config.MaxJitter, - pushCh: make(chan struct{}, 1), - loggerFactory: loggerFactory, - log: log, - }, nil -} - -// caller must hold the mutex -func (r *Router) getInterfaces() ([]*transport.Interface, error) { - if len(r.interfaces) == 0 { - return nil, fmt.Errorf("%w is available", errNoInterface) - } - - return r.interfaces, nil -} - -func (r *Router) getInterface(ifName string) (*transport.Interface, error) { - r.mutex.RLock() - defer r.mutex.RUnlock() - - ifs, err := r.getInterfaces() - if err != nil { - return nil, err - } - for _, ifc := range ifs { - if ifc.Name == ifName { - return ifc, nil - } - } - - return nil, fmt.Errorf("%w: %s", transport.ErrInterfaceNotFound, ifName) -} - -// Start ... -func (r *Router) Start() error { - r.mutex.Lock() - defer r.mutex.Unlock() - - if r.stopFunc != nil { - return errRouterAlreadyStarted - } - - cancelCh := make(chan struct{}) - - go func() { - loop: - for { - d, err := r.processChunks() - if err != nil { - r.log.Errorf("[%s] %s", r.name, err.Error()) - break - } - - if d <= 0 { - select { - case <-r.pushCh: - case <-cancelCh: - break loop - } - } else { - t := time.NewTimer(d) - select { - case <-t.C: - case <-cancelCh: - break loop - } - } - } - }() - - r.stopFunc = func() { - close(cancelCh) - } - - for _, child := range r.children { - if err := child.Start(); err != nil { - return err - } - } - - return nil -} - -// Stop ... -func (r *Router) Stop() error { - r.mutex.Lock() - defer r.mutex.Unlock() - - if r.stopFunc == nil { - return errRouterAlreadyStopped - } - - for _, router := range r.children { - r.mutex.Unlock() - err := router.Stop() - r.mutex.Lock() - - if err != nil { - return err - } - } - - r.stopFunc() - r.stopFunc = nil - return nil -} - -// caller must hold the mutex -func (r *Router) addNIC(nic NIC) error { - ifc, err := nic.getInterface("eth0") - if err != nil { - return err - } - - var ips []net.IP - - if ips = nic.getStaticIPs(); len(ips) == 0 { - // assign an IP address - ip, err2 := r.assignIPAddress() - if err2 != nil { - return err2 - } - ips = append(ips, ip) - } - - for _, ip := range ips { - if !r.ipv4Net.Contains(ip) { - return fmt.Errorf("%w: %s", errStaticIPisBeyondSubnet, r.ipv4Net.String()) - } - - ifc.AddAddress(&net.IPNet{ - IP: ip, - Mask: r.ipv4Net.Mask, - }) - - r.nics[ip.String()] = nic - } - - return nic.setRouter(r) -} - -// AddRouter adds a child Router. -func (r *Router) AddRouter(router *Router) error { - r.mutex.Lock() - defer r.mutex.Unlock() - - // Router is a NIC. Add it as a NIC so that packets are routed to this child - // router. - err := r.addNIC(router) - if err != nil { - return err - } - - if err = router.setRouter(r); err != nil { - return err - } - - r.children = append(r.children, router) - return nil -} - -// AddChildRouter is like AddRouter, but does not add the child routers NIC to -// the parent. This has to be done manually by calling AddNet, which allows to -// use a wrapper around the subrouters NIC. -// AddNet MUST be called before AddChildRouter. -func (r *Router) AddChildRouter(router *Router) error { - r.mutex.Lock() - defer r.mutex.Unlock() - if err := router.setRouter(r); err != nil { - return err - } - - r.children = append(r.children, router) - return nil -} - -// AddNet ... -func (r *Router) AddNet(nic NIC) error { - r.mutex.Lock() - defer r.mutex.Unlock() - - return r.addNIC(nic) -} - -// AddHost adds a mapping of hostname and an IP address to the local resolver. -func (r *Router) AddHost(hostName string, ipAddr string) error { - return r.resolver.addHost(hostName, ipAddr) -} - -// AddChunkFilter adds a filter for chunks traversing this router. -// You may add more than one filter. The filters are called in the order of this method call. -// If a chunk is dropped by a filter, subsequent filter will not receive the chunk. -func (r *Router) AddChunkFilter(filter ChunkFilter) { - r.mutex.Lock() - defer r.mutex.Unlock() - - r.chunkFilters = append(r.chunkFilters, filter) -} - -// caller should hold the mutex -func (r *Router) assignIPAddress() (net.IP, error) { - // See: https://stackoverflow.com/questions/14915188/ip-address-ending-with-zero - - if r.lastID == 0xfe { - return nil, errAddressSpaceExhausted - } - - ip := make(net.IP, 4) - copy(ip, r.ipv4Net.IP[:3]) - r.lastID++ - ip[3] = r.lastID - return ip, nil -} - -func (r *Router) push(c Chunk) { - r.mutex.Lock() - defer r.mutex.Unlock() - - r.log.Debugf("[%s] route %s", r.name, c.String()) - if r.stopFunc != nil { - c.setTimestamp() - if r.queue.push(c) { - select { - case r.pushCh <- struct{}{}: - default: - } - } else { - r.log.Warnf("[%s] queue was full. dropped a chunk", r.name) - } - } -} - -func (r *Router) processChunks() (time.Duration, error) { - r.mutex.Lock() - defer r.mutex.Unlock() - - // Introduce jitter by delaying the processing of chunks. - if r.maxJitter > 0 { - jitter := time.Duration(rand.Int63n(int64(r.maxJitter))) //nolint:gosec - time.Sleep(jitter) - } - - // cutOff - // v min delay - // |<--->| - // +------------:-- - // |OOOOOOXXXXX : --> time - // +------------:-- - // |<--->| now - // due - - enteredAt := time.Now() - cutOff := enteredAt.Add(-r.minDelay) - - var d time.Duration // the next sleep duration - - for { - d = 0 - - c := r.queue.peek() - if c == nil { - break // no more chunk in the queue - } - - // check timestamp to find if the chunk is due - if c.getTimestamp().After(cutOff) { - // There is one or more chunk in the queue but none of them are due. - // Calculate the next sleep duration here. - nextExpire := c.getTimestamp().Add(r.minDelay) - d = nextExpire.Sub(enteredAt) - break - } - - var ok bool - if c, ok = r.queue.pop(); !ok { - break // no more chunk in the queue - } - - blocked := false - for i := 0; i < len(r.chunkFilters); i++ { - filter := r.chunkFilters[i] - if !filter(c) { - blocked = true - break - } - } - if blocked { - continue // discard - } - - dstIP := c.getDestinationIP() - - // check if the destination is in our subnet - if r.ipv4Net.Contains(dstIP) { - // search for the destination NIC - var nic NIC - if nic, ok = r.nics[dstIP.String()]; !ok { - // NIC not found. drop it. - r.log.Debugf("[%s] %s unreachable", r.name, c.String()) - continue - } - - // found the NIC, forward the chunk to the NIC. - // call to NIC must unlock mutex - r.mutex.Unlock() - nic.onInboundChunk(c) - r.mutex.Lock() - continue - } - - // the destination is outside of this subnet - // is this WAN? - if r.parent == nil { - // this WAN. No route for this chunk - r.log.Debugf("[%s] no route found for %s", r.name, c.String()) - continue - } - - // Pass it to the parent via NAT - toParent, err := r.nat.translateOutbound(c) - if err != nil { - return 0, err - } - - if toParent == nil { - continue - } - - //nolint:godox - /* FIXME: this implementation would introduce a duplicate packet! - if r.nat.natType.Hairpinning { - hairpinned, err := r.nat.translateInbound(toParent) - if err != nil { - r.log.Warnf("[%s] %s", r.name, err.Error()) - } else { - go func() { - r.push(hairpinned) - }() - } - } - */ - - // call to parent router mutex unlock mutex - r.mutex.Unlock() - r.parent.push(toParent) - r.mutex.Lock() - } - - return d, nil -} - -// caller must hold the mutex -func (r *Router) setRouter(parent *Router) error { - r.parent = parent - r.resolver.setParent(parent.resolver) - - // when this method is called, one or more IP address has already been assigned by - // the parent router. - ifc, err := r.getInterface("eth0") - if err != nil { - return err - } - - addrs, _ := ifc.Addrs() - if len(addrs) == 0 { - return errNoIPAddrEth0 - } - - mappedIPs := []net.IP{} - localIPs := []net.IP{} - - for _, ifcAddr := range addrs { - var ip net.IP - switch addr := ifcAddr.(type) { - case *net.IPNet: - ip = addr.IP - case *net.IPAddr: // Do we really need this case? - ip = addr.IP - default: - } - - if ip == nil { - continue - } - - mappedIPs = append(mappedIPs, ip) - - if locIP := r.staticLocalIPs[ip.String()]; locIP != nil { - localIPs = append(localIPs, locIP) - } - } - - // Set up NAT here - if r.natType == nil { - r.natType = &NATType{ - MappingBehavior: EndpointIndependent, - FilteringBehavior: EndpointAddrPortDependent, - Hairpinning: false, - PortPreservation: false, - MappingLifeTime: 30 * time.Second, - } - } - r.nat, err = newNAT(&natConfig{ - name: r.name, - natType: *r.natType, - mappedIPs: mappedIPs, - localIPs: localIPs, - loggerFactory: r.loggerFactory, - }) - if err != nil { - return err - } - - return nil -} - -func (r *Router) onInboundChunk(c Chunk) { - fromParent, err := r.nat.translateInbound(c) - if err != nil { - r.log.Warnf("[%s] %s", r.name, err.Error()) - return - } - - r.push(fromParent) -} - -func (r *Router) getStaticIPs() []net.IP { - return r.staticIPs -} diff --git a/vendor/github.com/pion/transport/v2/vnet/tbf.go b/vendor/github.com/pion/transport/v2/vnet/tbf.go deleted file mode 100644 index e6188e31..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/tbf.go +++ /dev/null @@ -1,167 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "math" - "sync" - "time" - - "github.com/pion/logging" -) - -const ( - // Bit is a single bit - Bit = 1 - // KBit is a kilobit - KBit = 1000 * Bit - // MBit is a Megabit - MBit = 1000 * KBit -) - -// TokenBucketFilter implements a token bucket rate limit algorithm. -type TokenBucketFilter struct { - NIC - currentTokensInBucket float64 - c chan Chunk - queue *chunkQueue - queueSize int // in bytes - - mutex sync.Mutex - rate int - maxBurst int - minRefillDuration time.Duration - - wg sync.WaitGroup - done chan struct{} - - log logging.LeveledLogger -} - -// TBFOption is the option type to configure a TokenBucketFilter -type TBFOption func(*TokenBucketFilter) TBFOption - -// TBFQueueSizeInBytes sets the max number of bytes waiting in the queue. Can -// only be set in constructor before using the TBF. -func TBFQueueSizeInBytes(bytes int) TBFOption { - return func(t *TokenBucketFilter) TBFOption { - prev := t.queueSize - t.queueSize = bytes - return TBFQueueSizeInBytes(prev) - } -} - -// TBFRate sets the bit rate of a TokenBucketFilter -func TBFRate(rate int) TBFOption { - return func(t *TokenBucketFilter) TBFOption { - t.mutex.Lock() - defer t.mutex.Unlock() - previous := t.rate - t.rate = rate - return TBFRate(previous) - } -} - -// TBFMaxBurst sets the bucket size of the token bucket filter. This is the -// maximum size that can instantly leave the filter, if the bucket is full. -func TBFMaxBurst(size int) TBFOption { - return func(t *TokenBucketFilter) TBFOption { - t.mutex.Lock() - defer t.mutex.Unlock() - previous := t.maxBurst - t.maxBurst = size - return TBFMaxBurst(previous) - } -} - -// Set updates a setting on the token bucket filter -func (t *TokenBucketFilter) Set(opts ...TBFOption) (previous TBFOption) { - for _, opt := range opts { - previous = opt(t) - } - return previous -} - -// NewTokenBucketFilter creates and starts a new TokenBucketFilter -func NewTokenBucketFilter(n NIC, opts ...TBFOption) (*TokenBucketFilter, error) { - tbf := &TokenBucketFilter{ - NIC: n, - currentTokensInBucket: 0, - c: make(chan Chunk), - queue: nil, - queueSize: 50000, - mutex: sync.Mutex{}, - rate: 1 * MBit, - maxBurst: 8 * KBit, - minRefillDuration: 100 * time.Millisecond, - wg: sync.WaitGroup{}, - done: make(chan struct{}), - log: logging.NewDefaultLoggerFactory().NewLogger("tbf"), - } - tbf.Set(opts...) - tbf.queue = newChunkQueue(0, tbf.queueSize) - tbf.wg.Add(1) - go tbf.run() - return tbf, nil -} - -func (t *TokenBucketFilter) onInboundChunk(c Chunk) { - t.c <- c -} - -func (t *TokenBucketFilter) run() { - defer t.wg.Done() - - t.refillTokens(t.minRefillDuration) - lastRefill := time.Now() - - for { - select { - case <-t.done: - t.drainQueue() - return - case chunk := <-t.c: - if time.Since(lastRefill) > t.minRefillDuration { - t.refillTokens(time.Since(lastRefill)) - lastRefill = time.Now() - } - t.queue.push(chunk) - t.drainQueue() - } - } -} - -func (t *TokenBucketFilter) refillTokens(dt time.Duration) { - m := 1000.0 / float64(dt.Milliseconds()) - add := (float64(t.rate) / m) / 8.0 - t.mutex.Lock() - defer t.mutex.Unlock() - t.currentTokensInBucket = math.Min(float64(t.maxBurst), t.currentTokensInBucket+add) - t.log.Tracef("add=(%v / %v) / 8 = %v, currentTokensInBucket=%v, maxBurst=%v", t.rate, m, add, t.currentTokensInBucket, t.maxBurst) -} - -func (t *TokenBucketFilter) drainQueue() { - for { - next := t.queue.peek() - if next == nil { - break - } - tokens := float64(len(next.UserData())) - if t.currentTokensInBucket < tokens { - t.log.Tracef("currentTokensInBucket=%v, tokens=%v, stop drain", t.currentTokensInBucket, tokens) - break - } - t.log.Tracef("currentTokensInBucket=%v, tokens=%v, pop chunk", t.currentTokensInBucket, tokens) - t.queue.pop() - t.NIC.onInboundChunk(next) - t.currentTokensInBucket -= tokens - } -} - -// Close closes and stops the token bucket filter queue -func (t *TokenBucketFilter) Close() error { - close(t.done) - t.wg.Wait() - return nil -} diff --git a/vendor/github.com/pion/transport/v2/vnet/udpproxy.go b/vendor/github.com/pion/transport/v2/vnet/udpproxy.go deleted file mode 100644 index c5b4f996..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/udpproxy.go +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "context" - "net" - "sync" - "time" -) - -// UDPProxy is a proxy between real server(net.UDPConn) and vnet.UDPConn. -// -// High level design: -// -// .............................................. -// : Virtual Network (vnet) : -// : : -// +-------+ * 1 +----+ +--------+ : -// | :App |------------>|:Net|--o<-----|:Router | ............................. -// +-------+ +----+ | | : UDPProxy : -// : | | +----+ +---------+ +---------+ +--------+ -// : | |--->o--|:Net|-->o-| vnet. |-->o-| net. |--->-| :Real | -// : | | +----+ | UDPConn | | UDPConn | | Server | -// : | | : +---------+ +---------+ +--------+ -// : | | ............................: -// : +--------+ : -// ............................................... -type UDPProxy struct { - // The router bind to. - router *Router - - // Each vnet source, bind to a real socket to server. - // key is real server addr, which is net.Addr - // value is *aUDPProxyWorker - workers sync.Map - - // For each endpoint, we never know when to start and stop proxy, - // so we stop the endpoint when timeout. - timeout time.Duration - - // For utest, to mock the target real server. - // Optional, use the address of received client packet. - mockRealServerAddr *net.UDPAddr -} - -// NewProxy create a proxy, the router for this proxy belongs/bind to. If need to proxy for -// please create a new proxy for each router. For all addresses we proxy, we will create a -// vnet.Net in this router and proxy all packets. -func NewProxy(router *Router) (*UDPProxy, error) { - v := &UDPProxy{router: router, timeout: 2 * time.Minute} - return v, nil -} - -// Close the proxy, stop all workers. -func (v *UDPProxy) Close() error { - v.workers.Range(func(key, value interface{}) bool { - _ = value.(*aUDPProxyWorker).Close() //nolint:forcetypeassert - return true - }) - return nil -} - -// Proxy starts a worker for server, ignore if already started. -func (v *UDPProxy) Proxy(client *Net, server *net.UDPAddr) error { - // Note that even if the worker exists, it's also ok to create a same worker, - // because the router will use the last one, and the real server will see a address - // change event after we switch to the next worker. - if _, ok := v.workers.Load(server.String()); ok { - // nolint:godox // TODO: Need to restart the stopped worker? - return nil - } - - // Not exists, create a new one. - worker := &aUDPProxyWorker{ - router: v.router, mockRealServerAddr: v.mockRealServerAddr, - } - - // Create context for cleanup. - var ctx context.Context - ctx, worker.ctxDisposeCancel = context.WithCancel(context.Background()) - - v.workers.Store(server.String(), worker) - - return worker.Proxy(ctx, client, server) -} - -// A proxy worker for a specified proxy server. -type aUDPProxyWorker struct { - router *Router - mockRealServerAddr *net.UDPAddr - - // Each vnet source, bind to a real socket to server. - // key is vnet client addr, which is net.Addr - // value is *net.UDPConn - endpoints sync.Map - - // For cleanup. - ctxDisposeCancel context.CancelFunc - wg sync.WaitGroup -} - -func (v *aUDPProxyWorker) Close() error { - // Notify all goroutines to dispose. - v.ctxDisposeCancel() - - // Wait for all goroutines quit. - v.wg.Wait() - - return nil -} - -func (v *aUDPProxyWorker) Proxy(ctx context.Context, _ *Net, serverAddr *net.UDPAddr) error { // nolint:gocognit - // Create vnet for real server by serverAddr. - nw, err := NewNet(&NetConfig{ - StaticIP: serverAddr.IP.String(), - }) - if err != nil { - return err - } - - if err = v.router.AddNet(nw); err != nil { - return err - } - - // We must create a "same" vnet.UDPConn as the net.UDPConn, - // which has the same ip:port, to copy packets between them. - vnetSocket, err := nw.ListenUDP("udp4", serverAddr) - if err != nil { - return err - } - - // User stop proxy, we should close the socket. - go func() { - <-ctx.Done() - _ = vnetSocket.Close() - }() - - // Got new vnet client, start a new endpoint. - findEndpointBy := func(addr net.Addr) (*net.UDPConn, error) { - // Exists binding. - if value, ok := v.endpoints.Load(addr.String()); ok { - // Exists endpoint, reuse it. - return value.(*net.UDPConn), nil //nolint:forcetypeassert - } - - // The real server we proxy to, for utest to mock it. - realAddr := serverAddr - if v.mockRealServerAddr != nil { - realAddr = v.mockRealServerAddr - } - - // Got new vnet client, create new endpoint. - realSocket, err := net.DialUDP("udp4", nil, realAddr) - if err != nil { - return nil, err - } - - // User stop proxy, we should close the socket. - go func() { - <-ctx.Done() - _ = realSocket.Close() - }() - - // Bind address. - v.endpoints.Store(addr.String(), realSocket) - - // Got packet from real serverAddr, we should proxy it to vnet. - v.wg.Add(1) - go func(vnetClientAddr net.Addr) { - defer v.wg.Done() - - buf := make([]byte, 1500) - for { - n, _, err := realSocket.ReadFrom(buf) - if err != nil { - return - } - - if n <= 0 { - continue // Drop packet - } - - if _, err := vnetSocket.WriteTo(buf[:n], vnetClientAddr); err != nil { - return - } - } - }(addr) - - return realSocket, nil - } - - // Start a proxy goroutine. - v.wg.Add(1) - go func() { - defer v.wg.Done() - - buf := make([]byte, 1500) - - for { - n, addr, err := vnetSocket.ReadFrom(buf) - if err != nil { - return - } - - if n <= 0 || addr == nil { - continue // Drop packet - } - - realSocket, err := findEndpointBy(addr) - if err != nil { - continue // Drop packet. - } - - if _, err := realSocket.Write(buf[:n]); err != nil { - return - } - } - }() - - return nil -} diff --git a/vendor/github.com/pion/transport/v2/vnet/udpproxy_direct.go b/vendor/github.com/pion/transport/v2/vnet/udpproxy_direct.go deleted file mode 100644 index bb2aedfd..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/udpproxy_direct.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package vnet - -import ( - "fmt" - "net" -) - -// Deliver directly send packet to vnet or real-server. -// For example, we can use this API to simulate the REPLAY ATTACK. -func (v *UDPProxy) Deliver(sourceAddr, destAddr net.Addr, b []byte) (nn int, err error) { - v.workers.Range(func(key, value interface{}) bool { - if nn, err = value.(*aUDPProxyWorker).Deliver(sourceAddr, destAddr, b); err != nil { - return false // Fail, abort. - } else if nn == len(b) { - return false // Done. - } - - return true // Deliver by next worker. - }) - return -} - -func (v *aUDPProxyWorker) Deliver(sourceAddr, _ net.Addr, b []byte) (nn int, err error) { - addr, ok := sourceAddr.(*net.UDPAddr) - if !ok { - return 0, fmt.Errorf("invalid addr %v", sourceAddr) // nolint:goerr113 - } - - // nolint:godox // TODO: Support deliver packet from real server to vnet. - // If packet is from vnet, proxy to real server. - var realSocket *net.UDPConn - value, ok := v.endpoints.Load(addr.String()) - if !ok { - return 0, nil - } - - realSocket = value.(*net.UDPConn) // nolint:forcetypeassert - - // Send to real server. - if _, err := realSocket.Write(b); err != nil { - return 0, err - } - - return len(b), nil -} diff --git a/vendor/github.com/pion/transport/v2/vnet/vnet.go b/vendor/github.com/pion/transport/v2/vnet/vnet.go deleted file mode 100644 index 1d244f07..00000000 --- a/vendor/github.com/pion/transport/v2/vnet/vnet.go +++ /dev/null @@ -1,5 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package vnet provides a virtual network layer for pion -package vnet diff --git a/vendor/github.com/pion/turn/v2/.gitignore b/vendor/github.com/pion/turn/v2/.gitignore deleted file mode 100644 index f977e748..00000000 --- a/vendor/github.com/pion/turn/v2/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/turn/v2/.golangci.yml b/vendor/github.com/pion/turn/v2/.golangci.yml deleted file mode 100644 index 48696f16..00000000 --- a/vendor/github.com/pion/turn/v2/.golangci.yml +++ /dev/null @@ -1,116 +0,0 @@ -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - forbidigo # Forbids identifiers - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/turn/v2/.goreleaser.yml b/vendor/github.com/pion/turn/v2/.goreleaser.yml deleted file mode 100644 index 2caa5fbd..00000000 --- a/vendor/github.com/pion/turn/v2/.goreleaser.yml +++ /dev/null @@ -1,2 +0,0 @@ -builds: -- skip: true diff --git a/vendor/github.com/pion/turn/v2/AUTHORS.txt b/vendor/github.com/pion/turn/v2/AUTHORS.txt deleted file mode 100644 index 3b38a5c1..00000000 --- a/vendor/github.com/pion/turn/v2/AUTHORS.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -Aaron France -Aleksandr Razumov -andrefsp -Antonio Sorrentino -Atsushi Watanabe -backkem -Caleb Phillips -cnderrauber -David Colburn -Gabor Retvari -Herman Banken -Hugo Arregui -Igor German -Ingmar Wittkau -Jannis Mattheis -John Bradley -jose nazario -Juliusz Chroboczek -lllf -Lukas Rezek -Marouane <6729798+nindolabs@users.noreply.github.com> -Mészáros Mihály -nindolabs <6729798+nindolabs@users.noreply.github.com> -Onwuka Gideon -Robert Eperjesi -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -songjiayang -Steffen Vogel -ted -Tom Clift -Yusuke Nakamura -Yutaka Takeda - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/turn/v2/DESIGN.md b/vendor/github.com/pion/turn/v2/DESIGN.md deleted file mode 100644 index 2c524669..00000000 --- a/vendor/github.com/pion/turn/v2/DESIGN.md +++ /dev/null @@ -1,31 +0,0 @@ -# Why Pion TURN -TURN servers aren't exactly a hot technology, they are usually an after thought when building something. Most of the time -beginners build an interesting WebRTC application, but at the very end realize they need a TURN server. It is really frustrating when you -want to share your cool new project, only to realize you have to run another service. - -Then you find yourself building from source, fighting with config files and making changes you don't fully understand. Pion TURN was born -hoping to solve these frustrations. These are the guiding principals/features that define pion-turn. - -## Easy setup -simple-turn is a statically built TURN server, configured by environment variables. The entire install setup is 5 commands, on any platform! -The goal is that anyone should be able to run a TURN server on any platform. - -## Integration first -pion-turn makes no assumptions about how you authenticate users, how you log, or even your topology! Instead of running a dedicated TURN server you -can inherit from github.com/pion/turn and set whatever logger you want. - -## Embeddable -You can add this to an existing service. This means all your config files stay homogeneous instead of having the mismatch that makes it harder to manage your services. -For small setups it is usually an overkill to deploy dedicated TURN servers, this makes it easier to solve the problems you care about. - -## Safe -Golang provides a great foundation to build safe network services. Especially when running a networked service that is highly concurrent bugs can be devastating. - -## Readable -All network interaction is commented with a link to the spec. This makes learning and debugging easier, the TURN server was written to also serve as a guide for others. - -## Tested -Every commit is tested via travis-ci Go provides fantastic facilities for testing, and more will be added as time goes on. - -## Shared libraries -Every pion product is built using shared libraries, allowing others to build things using existing tested STUN and TURN tools. diff --git a/vendor/github.com/pion/turn/v2/FAQ.md b/vendor/github.com/pion/turn/v2/FAQ.md deleted file mode 100644 index a8ffd649..00000000 --- a/vendor/github.com/pion/turn/v2/FAQ.md +++ /dev/null @@ -1,17 +0,0 @@ - - -## FAQ - -Q: Will pion/turn also act as a STUN server? - -A: Yes. - -Q: How do I implement token-based authentication? - -A: Replace the username with a token in the [AuthHandler](https://github.com/pion/turn/blob/6d0ff435910870eb9024b18321b93b61844fcfec/examples/turn-server/simple/main.go#L49). -The password sent by the client can be any non-empty string, as long as it matches that used by the [GenerateAuthKey](https://github.com/pion/turn/blob/6d0ff435910870eb9024b18321b93b61844fcfec/examples/turn-server/simple/main.go#L41) -function. - -Q: Will WebRTC prioritize using STUN over TURN? - -A: Yes. \ No newline at end of file diff --git a/vendor/github.com/pion/turn/v2/LICENSE.md b/vendor/github.com/pion/turn/v2/LICENSE.md deleted file mode 100644 index 5cc9cbdc..00000000 --- a/vendor/github.com/pion/turn/v2/LICENSE.md +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2018 Pion LLC - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/pion/turn/v2/README.md b/vendor/github.com/pion/turn/v2/README.md deleted file mode 100644 index b8901fd3..00000000 --- a/vendor/github.com/pion/turn/v2/README.md +++ /dev/null @@ -1,69 +0,0 @@ -

- Pion TURN -
- Pion TURN -
-

-

A toolkit for building TURN clients and servers in Go

-

- Pion TURN - Slack Widget - -
- Build Status - GoDoc - Coverage Status - Go Report Card - License: MIT -

-
- -Pion TURN is a Go toolkit for building TURN servers and clients. We wrote it to solve problems we had when building RTC projects. - -* **Deployable** - Use modern tooling of the Go ecosystem. Stop generating config files. -* **Embeddable** - Include `pion/turn` in your existing applications. No need to manage another service. -* **Extendable** - TURN as an API so you can easily integrate with your existing monitoring and metrics. -* **Maintainable** - `pion/turn` is simple and well documented. Designed for learning and easy debugging. -* **Portable** - Quickly deploy to multiple architectures/platforms just by setting an environment variable. -* **Safe** - Stability and safety is important for network services. Go provides everything we need. -* **Scalable** - Create allocations and mutate state at runtime. Designed to make scaling easy. - -# Using -`pion/turn` is an API for building STUN/TURN clients and servers, not a binary you deploy then configure. It may require copying our examples and -making minor modifications to fit your need, no knowledge of Go is required however. You may be able to download the pre-made binaries of our examples -if you wish to get started quickly. - -The advantage of this is that you don't need to deal with complicated config files, or custom APIs to modify the state of Pion TURN. -After you instantiate an instance of a Pion TURN server or client you interact with it like any library. The quickest way to get started is to look at the -[examples](examples) or [GoDoc](https://godoc.org/github.com/pion/turn) - -# Examples -We try to cover most common use cases in [examples](examples). If more examples could be helpful please file an issue, we are always looking -to expand and improve `pion/turn` to make it easier for developers. - -To build any example you just need to run `go build` in the directory of the example you care about. -It is also very easy to [cross compile](https://dave.cheney.net/2015/08/22/cross-compilation-with-go-1-5) Go programs. - -You can also see `pion/turn` usage in [pion/ice](https://github.com/pion/ice) - -# [FAQ](https://github.com/pion/webrtc/wiki/FAQ) - -### RFCs -#### Implemented -* [RFC 5389: Session Traversal Utilities for NAT (STUN)](https://tools.ietf.org/html/rfc5389) -* [RFC 5766: Traversal Using Relays around NAT (TURN)](https://tools.ietf.org/html/rfc5766) - -#### Planned -* [RFC 6062: Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations](https://tools.ietf.org/html/rfc6062) -* [RFC 6156: Traversal Using Relays around NAT (TURN) Extension for IPv6](https://tools.ietf.org/html/rfc6156) - -### Community -Pion has an active community on the [Golang Slack](https://pion.ly/slack). Sign up and join the **#pion** channel for discussions and support. - -We are always looking to support **your projects**. Please reach out if you have something to build! - -### Contributing -Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible. - -### License -MIT License - see [LICENSE.md](LICENSE.md) for full text diff --git a/vendor/github.com/pion/turn/v2/client.go b/vendor/github.com/pion/turn/v2/client.go deleted file mode 100644 index 5e675fd3..00000000 --- a/vendor/github.com/pion/turn/v2/client.go +++ /dev/null @@ -1,581 +0,0 @@ -package turn - -import ( - b64 "encoding/base64" - "fmt" - "math" - "net" - "sync" - "time" - - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" - "github.com/pion/transport/v2/vnet" - "github.com/pion/turn/v2/internal/client" - "github.com/pion/turn/v2/internal/proto" -) - -const ( - defaultRTO = 200 * time.Millisecond - maxRtxCount = 7 // total 7 requests (Rc) - maxDataBufferSize = math.MaxUint16 // message size limit for Chromium -) - -// interval [msec] -// 0: 0 ms +500 -// 1: 500 ms +1000 -// 2: 1500 ms +2000 -// 3: 3500 ms +4000 -// 4: 7500 ms +8000 -// 5: 15500 ms +16000 -// 6: 31500 ms +32000 -// -: 63500 ms failed - -// ClientConfig is a bag of config parameters for Client. -type ClientConfig struct { - STUNServerAddr string // STUN server address (e.g. "stun.abc.com:3478") - TURNServerAddr string // TURN server address (e.g. "turn.abc.com:3478") - Username string - Password string - Realm string - Software string - RTO time.Duration - Conn net.PacketConn // Listening socket (net.PacketConn) - LoggerFactory logging.LoggerFactory - Net transport.Net -} - -// Client is a STUN server client -type Client struct { - conn net.PacketConn // read-only - stunServ net.Addr // read-only - turnServ net.Addr // read-only - stunServStr string // read-only, used for de-multiplexing - turnServStr string // read-only, used for de-multiplexing - username stun.Username // read-only - password string // read-only - realm stun.Realm // read-only - integrity stun.MessageIntegrity // read-only - software stun.Software // read-only - trMap *client.TransactionMap // thread-safe - rto time.Duration // read-only - relayedConn *client.UDPConn // protected by mutex *** - allocTryLock client.TryLock // thread-safe - listenTryLock client.TryLock // thread-safe - net transport.Net // read-only - mutex sync.RWMutex // thread-safe - mutexTrMap sync.Mutex // thread-safe - log logging.LeveledLogger // read-only -} - -// NewClient returns a new Client instance. listeningAddress is the address and port to listen on, default "0.0.0.0:0" -func NewClient(config *ClientConfig) (*Client, error) { - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - log := loggerFactory.NewLogger("turnc") - - if config.Conn == nil { - return nil, errNilConn - } - - var err error - if config.Net == nil { - config.Net, err = stdnet.NewNet() // defaults to native operation - if err != nil { - return nil, err - } - } else if _, ok := config.Net.(*vnet.Net); ok { - log.Warn("Virtual network is enabled") - } - - var stunServ, turnServ net.Addr - var stunServStr, turnServStr string - if len(config.STUNServerAddr) > 0 { - log.Debugf("resolving %s", config.STUNServerAddr) - stunServ, err = config.Net.ResolveUDPAddr("udp4", config.STUNServerAddr) - if err != nil { - return nil, err - } - stunServStr = stunServ.String() - log.Debugf("stunServ: %s", stunServStr) - } - if len(config.TURNServerAddr) > 0 { - log.Debugf("resolving %s", config.TURNServerAddr) - turnServ, err = config.Net.ResolveUDPAddr("udp4", config.TURNServerAddr) - if err != nil { - return nil, err - } - turnServStr = turnServ.String() - log.Debugf("turnServ: %s", turnServStr) - } - - rto := defaultRTO - if config.RTO > 0 { - rto = config.RTO - } - - c := &Client{ - conn: config.Conn, - stunServ: stunServ, - turnServ: turnServ, - stunServStr: stunServStr, - turnServStr: turnServStr, - username: stun.NewUsername(config.Username), - password: config.Password, - realm: stun.NewRealm(config.Realm), - software: stun.NewSoftware(config.Software), - net: config.Net, - trMap: client.NewTransactionMap(), - rto: rto, - log: log, - } - - return c, nil -} - -// TURNServerAddr return the TURN server address -func (c *Client) TURNServerAddr() net.Addr { - return c.turnServ -} - -// STUNServerAddr return the STUN server address -func (c *Client) STUNServerAddr() net.Addr { - return c.stunServ -} - -// Username returns username -func (c *Client) Username() stun.Username { - return c.username -} - -// Realm return realm -func (c *Client) Realm() stun.Realm { - return c.realm -} - -// WriteTo sends data to the specified destination using the base socket. -func (c *Client) WriteTo(data []byte, to net.Addr) (int, error) { - return c.conn.WriteTo(data, to) -} - -// Listen will have this client start listening on the conn provided via the config. -// This is optional. If not used, you will need to call HandleInbound method -// to supply incoming data, instead. -func (c *Client) Listen() error { - if err := c.listenTryLock.Lock(); err != nil { - return fmt.Errorf("%w: %s", errAlreadyListening, err.Error()) - } - - go func() { - buf := make([]byte, maxDataBufferSize) - for { - n, from, err := c.conn.ReadFrom(buf) - if err != nil { - c.log.Debugf("exiting read loop: %s", err.Error()) - break - } - - _, err = c.HandleInbound(buf[:n], from) - if err != nil { - c.log.Debugf("exiting read loop: %s", err.Error()) - break - } - } - - c.listenTryLock.Unlock() - }() - - return nil -} - -// Close closes this client -func (c *Client) Close() { - c.mutexTrMap.Lock() - defer c.mutexTrMap.Unlock() - - c.trMap.CloseAndDeleteAll() -} - -// TransactionID & Base64: https://play.golang.org/p/EEgmJDI971P - -// SendBindingRequestTo sends a new STUN request to the given transport address -func (c *Client) SendBindingRequestTo(to net.Addr) (net.Addr, error) { - attrs := []stun.Setter{stun.TransactionID, stun.BindingRequest} - if len(c.software) > 0 { - attrs = append(attrs, c.software) - } - - msg, err := stun.Build(attrs...) - if err != nil { - return nil, err - } - trRes, err := c.PerformTransaction(msg, to, false) - if err != nil { - return nil, err - } - - var reflAddr stun.XORMappedAddress - if err := reflAddr.GetFrom(trRes.Msg); err != nil { - return nil, err - } - - return &net.UDPAddr{ - IP: reflAddr.IP, - Port: reflAddr.Port, - }, nil -} - -// SendBindingRequest sends a new STUN request to the STUN server -func (c *Client) SendBindingRequest() (net.Addr, error) { - if c.stunServ == nil { - return nil, errSTUNServerAddressNotSet - } - return c.SendBindingRequestTo(c.stunServ) -} - -// Allocate sends a TURN allocation request to the given transport address -func (c *Client) Allocate() (net.PacketConn, error) { - if err := c.allocTryLock.Lock(); err != nil { - return nil, fmt.Errorf("%w: %s", errOneAllocateOnly, err.Error()) - } - defer c.allocTryLock.Unlock() - - relayedConn := c.relayedUDPConn() - if relayedConn != nil { - return nil, fmt.Errorf("%w: %s", errAlreadyAllocated, relayedConn.LocalAddr().String()) - } - - msg, err := stun.Build( - stun.TransactionID, - stun.NewType(stun.MethodAllocate, stun.ClassRequest), - proto.RequestedTransport{Protocol: proto.ProtoUDP}, - stun.Fingerprint, - ) - if err != nil { - return nil, err - } - - trRes, err := c.PerformTransaction(msg, c.turnServ, false) - if err != nil { - return nil, err - } - - res := trRes.Msg - - // Anonymous allocate failed, trying to authenticate. - var nonce stun.Nonce - if err = nonce.GetFrom(res); err != nil { - return nil, err - } - if err = c.realm.GetFrom(res); err != nil { - return nil, err - } - c.realm = append([]byte(nil), c.realm...) - c.integrity = stun.NewLongTermIntegrity( - c.username.String(), c.realm.String(), c.password, - ) - // Trying to authorize. - msg, err = stun.Build( - stun.TransactionID, - stun.NewType(stun.MethodAllocate, stun.ClassRequest), - proto.RequestedTransport{Protocol: proto.ProtoUDP}, - &c.username, - &c.realm, - &nonce, - &c.integrity, - stun.Fingerprint, - ) - if err != nil { - return nil, err - } - - trRes, err = c.PerformTransaction(msg, c.turnServ, false) - if err != nil { - return nil, err - } - res = trRes.Msg - - if res.Type.Class == stun.ClassErrorResponse { - var code stun.ErrorCodeAttribute - if err = code.GetFrom(res); err == nil { - return nil, fmt.Errorf("%s (error %s)", res.Type, code) //nolint:goerr113 - } - return nil, fmt.Errorf("%s", res.Type) //nolint:goerr113 - } - - // Getting relayed addresses from response. - var relayed proto.RelayedAddress - if err := relayed.GetFrom(res); err != nil { - return nil, err - } - relayedAddr := &net.UDPAddr{ - IP: relayed.IP, - Port: relayed.Port, - } - - // Getting lifetime from response - var lifetime proto.Lifetime - if err := lifetime.GetFrom(res); err != nil { - return nil, err - } - - relayedConn = client.NewUDPConn(&client.UDPConnConfig{ - Observer: c, - RelayedAddr: relayedAddr, - Integrity: c.integrity, - Nonce: nonce, - Lifetime: lifetime.Duration, - Log: c.log, - }) - - c.setRelayedUDPConn(relayedConn) - - return relayedConn, nil -} - -// CreatePermission Issues a CreatePermission request for the supplied addresses -// as described in https://datatracker.ietf.org/doc/html/rfc5766#section-9 -func (c *Client) CreatePermission(addrs ...net.Addr) error { - return c.relayedUDPConn().CreatePermissions(addrs...) -} - -// PerformTransaction performs STUN transaction -func (c *Client) PerformTransaction(msg *stun.Message, to net.Addr, ignoreResult bool) (client.TransactionResult, - error, -) { - trKey := b64.StdEncoding.EncodeToString(msg.TransactionID[:]) - - raw := make([]byte, len(msg.Raw)) - copy(raw, msg.Raw) - - tr := client.NewTransaction(&client.TransactionConfig{ - Key: trKey, - Raw: raw, - To: to, - Interval: c.rto, - IgnoreResult: ignoreResult, - }) - - c.trMap.Insert(trKey, tr) - - c.log.Tracef("start %s transaction %s to %s", msg.Type, trKey, tr.To.String()) - _, err := c.conn.WriteTo(tr.Raw, to) - if err != nil { - return client.TransactionResult{}, err - } - - tr.StartRtxTimer(c.onRtxTimeout) - - // If dontWait is true, get the transaction going and return immediately - if ignoreResult { - return client.TransactionResult{}, nil - } - - res := tr.WaitForResult() - if res.Err != nil { - return res, res.Err - } - return res, nil -} - -// OnDeallocated is called when de-allocation of relay address has been complete. -// (Called by UDPConn) -func (c *Client) OnDeallocated(relayedAddr net.Addr) { - c.setRelayedUDPConn(nil) -} - -// HandleInbound handles data received. -// This method handles incoming packet de-multiplex it by the source address -// and the types of the message. -// This return a boolean (handled or not) and if there was an error. -// Caller should check if the packet was handled by this client or not. -// If not handled, it is assumed that the packet is application data. -// If an error is returned, the caller should discard the packet regardless. -func (c *Client) HandleInbound(data []byte, from net.Addr) (bool, error) { - // +-------------------+-------------------------------+ - // | Return Values | | - // +-------------------+ Meaning / Action | - // | handled | error | | - // |=========+=========+===============================+ - // | false | nil | Handle the packet as app data | - // |---------+---------+-------------------------------+ - // | true | nil | Nothing to do | - // |---------+---------+-------------------------------+ - // | false | error | (shouldn't happen) | - // |---------+---------+-------------------------------+ - // | true | error | Error occurred while handling | - // +---------+---------+-------------------------------+ - // Possible causes of the error: - // - Malformed packet (parse error) - // - STUN message was a request - // - Non-STUN message from the STUN server - - switch { - case stun.IsMessage(data): - return true, c.handleSTUNMessage(data, from) - case proto.IsChannelData(data): - return true, c.handleChannelData(data) - case len(c.stunServStr) != 0 && from.String() == c.stunServStr: - // received from STUN server but it is not a STUN message - return true, errNonSTUNMessage - default: - // assume, this is an application data - c.log.Tracef("non-STUN/TURN packet, unhandled") - } - - return false, nil -} - -func (c *Client) handleSTUNMessage(data []byte, from net.Addr) error { - raw := make([]byte, len(data)) - copy(raw, data) - - msg := &stun.Message{Raw: raw} - if err := msg.Decode(); err != nil { - return fmt.Errorf("%w: %s", errFailedToDecodeSTUN, err.Error()) - } - - if msg.Type.Class == stun.ClassRequest { - return fmt.Errorf("%w : %s", errUnexpectedSTUNRequestMessage, msg.String()) - } - - if msg.Type.Class == stun.ClassIndication { - if msg.Type.Method == stun.MethodData { - var peerAddr proto.PeerAddress - if err := peerAddr.GetFrom(msg); err != nil { - return err - } - from = &net.UDPAddr{ - IP: peerAddr.IP, - Port: peerAddr.Port, - } - - var data proto.Data - if err := data.GetFrom(msg); err != nil { - return err - } - - c.log.Debugf("data indication received from %s", from.String()) - - relayedConn := c.relayedUDPConn() - if relayedConn == nil { - c.log.Debug("no relayed conn allocated") - return nil // silently discard - } - - relayedConn.HandleInbound(data, from) - } - return nil - } - - // This is a STUN response message (transactional) - // The type is either: - // - stun.ClassSuccessResponse - // - stun.ClassErrorResponse - - trKey := b64.StdEncoding.EncodeToString(msg.TransactionID[:]) - - c.mutexTrMap.Lock() - tr, ok := c.trMap.Find(trKey) - if !ok { - c.mutexTrMap.Unlock() - // silently discard - c.log.Debugf("no transaction for %s", msg.String()) - return nil - } - - // End the transaction - tr.StopRtxTimer() - c.trMap.Delete(trKey) - c.mutexTrMap.Unlock() - - if !tr.WriteResult(client.TransactionResult{ - Msg: msg, - From: from, - Retries: tr.Retries(), - }) { - c.log.Debugf("no listener for %s", msg.String()) - } - - return nil -} - -func (c *Client) handleChannelData(data []byte) error { - chData := &proto.ChannelData{ - Raw: make([]byte, len(data)), - } - copy(chData.Raw, data) - if err := chData.Decode(); err != nil { - return err - } - - relayedConn := c.relayedUDPConn() - if relayedConn == nil { - c.log.Debug("no relayed conn allocated") - return nil // silently discard - } - - addr, ok := relayedConn.FindAddrByChannelNumber(uint16(chData.Number)) - if !ok { - return fmt.Errorf("%w: %d", errChannelBindNotFound, int(chData.Number)) - } - - c.log.Tracef("channel data received from %s (ch=%d)", addr.String(), int(chData.Number)) - - relayedConn.HandleInbound(chData.Data, addr) - return nil -} - -func (c *Client) onRtxTimeout(trKey string, nRtx int) { - c.mutexTrMap.Lock() - defer c.mutexTrMap.Unlock() - - tr, ok := c.trMap.Find(trKey) - if !ok { - return // already gone - } - - if nRtx == maxRtxCount { - // all retransmissions failed - c.trMap.Delete(trKey) - if !tr.WriteResult(client.TransactionResult{ - Err: fmt.Errorf("%w %s", errAllRetransmissionsFailed, trKey), - }) { - c.log.Debug("no listener for transaction") - } - return - } - - c.log.Tracef("retransmitting transaction %s to %s (nRtx=%d)", - trKey, tr.To.String(), nRtx) - _, err := c.conn.WriteTo(tr.Raw, tr.To) - if err != nil { - c.trMap.Delete(trKey) - if !tr.WriteResult(client.TransactionResult{ - Err: fmt.Errorf("%w %s", errFailedToRetransmitTransaction, trKey), - }) { - c.log.Debug("no listener for transaction") - } - return - } - tr.StartRtxTimer(c.onRtxTimeout) -} - -func (c *Client) setRelayedUDPConn(conn *client.UDPConn) { - c.mutex.Lock() - defer c.mutex.Unlock() - - c.relayedConn = conn -} - -func (c *Client) relayedUDPConn() *client.UDPConn { - c.mutex.RLock() - defer c.mutex.RUnlock() - - return c.relayedConn -} diff --git a/vendor/github.com/pion/turn/v2/codecov.yml b/vendor/github.com/pion/turn/v2/codecov.yml deleted file mode 100644 index 085200a4..00000000 --- a/vendor/github.com/pion/turn/v2/codecov.yml +++ /dev/null @@ -1,20 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/turn/v2/errors.go b/vendor/github.com/pion/turn/v2/errors.go deleted file mode 100644 index 12d5e0e8..00000000 --- a/vendor/github.com/pion/turn/v2/errors.go +++ /dev/null @@ -1,28 +0,0 @@ -package turn - -import "errors" - -var ( - errRelayAddressInvalid = errors.New("turn: RelayAddress must be valid IP to use RelayAddressGeneratorStatic") - errNoAvailableConns = errors.New("turn: PacketConnConfigs and ConnConfigs are empty, unable to proceed") - errConnUnset = errors.New("turn: PacketConnConfig must have a non-nil Conn") - errListenerUnset = errors.New("turn: ListenerConfig must have a non-nil Listener") - errListeningAddressInvalid = errors.New("turn: RelayAddressGenerator has invalid ListeningAddress") - errRelayAddressGeneratorUnset = errors.New("turn: RelayAddressGenerator in RelayConfig is unset") - errMaxRetriesExceeded = errors.New("turn: max retries exceeded") - errMaxPortNotZero = errors.New("turn: MaxPort must be not 0") - errMinPortNotZero = errors.New("turn: MaxPort must be not 0") - errNilConn = errors.New("turn: conn cannot not be nil") - errTODO = errors.New("turn: TODO") - errAlreadyListening = errors.New("turn: already listening") - errFailedToClose = errors.New("turn: Server failed to close") - errFailedToRetransmitTransaction = errors.New("turn: failed to retransmit transaction") - errAllRetransmissionsFailed = errors.New("all retransmissions failed for") - errChannelBindNotFound = errors.New("no binding found for channel") - errSTUNServerAddressNotSet = errors.New("STUN server address is not set for the client") - errOneAllocateOnly = errors.New("only one Allocate() caller is allowed") - errAlreadyAllocated = errors.New("already allocated") - errNonSTUNMessage = errors.New("non-STUN message from STUN server") - errFailedToDecodeSTUN = errors.New("failed to decode STUN message") - errUnexpectedSTUNRequestMessage = errors.New("unexpected STUN request message") -) diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go b/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go deleted file mode 100644 index 7a3ce1dd..00000000 --- a/vendor/github.com/pion/turn/v2/internal/allocation/allocation.go +++ /dev/null @@ -1,293 +0,0 @@ -// Package allocation contains all CRUD operations for allocations -package allocation - -import ( - "net" - "sync" - "sync/atomic" - "time" - - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/ipnet" - "github.com/pion/turn/v2/internal/proto" -) - -type allocationResponse struct { - transactionID [stun.TransactionIDSize]byte - responseAttrs []stun.Setter -} - -// Allocation is tied to a FiveTuple and relays traffic -// use CreateAllocation and GetAllocation to operate -type Allocation struct { - RelayAddr net.Addr - Protocol Protocol - TurnSocket net.PacketConn - RelaySocket net.PacketConn - fiveTuple *FiveTuple - permissionsLock sync.RWMutex - permissions map[string]*Permission - channelBindingsLock sync.RWMutex - channelBindings []*ChannelBind - lifetimeTimer *time.Timer - closed chan interface{} - log logging.LeveledLogger - - // some clients (Firefox or others using resiprocate's nICE lib) may retry allocation - // with same 5 tuple when received 413, for compatible with these clients, - // cache for response lost and client retry to implement 'stateless stack approach' - // https://datatracker.ietf.org/doc/html/rfc5766#section-6.2 - responseCache atomic.Value // *allocationResponse -} - -func addr2IPFingerprint(addr net.Addr) string { - switch a := addr.(type) { - case *net.UDPAddr: - return a.IP.String() - case *net.TCPAddr: // Do we really need this case? - return a.IP.String() - } - return "" // should never happen -} - -// NewAllocation creates a new instance of NewAllocation. -func NewAllocation(turnSocket net.PacketConn, fiveTuple *FiveTuple, log logging.LeveledLogger) *Allocation { - return &Allocation{ - TurnSocket: turnSocket, - fiveTuple: fiveTuple, - permissions: make(map[string]*Permission, 64), - closed: make(chan interface{}), - log: log, - } -} - -// GetPermission gets the Permission from the allocation -func (a *Allocation) GetPermission(addr net.Addr) *Permission { - a.permissionsLock.RLock() - defer a.permissionsLock.RUnlock() - - return a.permissions[addr2IPFingerprint(addr)] -} - -// AddPermission adds a new permission to the allocation -func (a *Allocation) AddPermission(p *Permission) { - fingerprint := addr2IPFingerprint(p.Addr) - - a.permissionsLock.RLock() - existedPermission, ok := a.permissions[fingerprint] - a.permissionsLock.RUnlock() - - if ok { - existedPermission.refresh(permissionTimeout) - return - } - - p.allocation = a - a.permissionsLock.Lock() - a.permissions[fingerprint] = p - a.permissionsLock.Unlock() - - p.start(permissionTimeout) -} - -// RemovePermission removes the net.Addr's fingerprint from the allocation's permissions -func (a *Allocation) RemovePermission(addr net.Addr) { - a.permissionsLock.Lock() - defer a.permissionsLock.Unlock() - delete(a.permissions, addr2IPFingerprint(addr)) -} - -// AddChannelBind adds a new ChannelBind to the allocation, it also updates the -// permissions needed for this ChannelBind -func (a *Allocation) AddChannelBind(c *ChannelBind, lifetime time.Duration) error { - // Check that this channel id isn't bound to another transport address, and - // that this transport address isn't bound to another channel number. - channelByNumber := a.GetChannelByNumber(c.Number) - - if channelByNumber != a.GetChannelByAddr(c.Peer) { - return errSameChannelDifferentPeer - } - - // Add or refresh this channel. - if channelByNumber == nil { - a.channelBindingsLock.Lock() - defer a.channelBindingsLock.Unlock() - - c.allocation = a - a.channelBindings = append(a.channelBindings, c) - c.start(lifetime) - - // Channel binds also refresh permissions. - a.AddPermission(NewPermission(c.Peer, a.log)) - } else { - channelByNumber.refresh(lifetime) - - // Channel binds also refresh permissions. - a.AddPermission(NewPermission(channelByNumber.Peer, a.log)) - } - - return nil -} - -// RemoveChannelBind removes the ChannelBind from this allocation by id -func (a *Allocation) RemoveChannelBind(number proto.ChannelNumber) bool { - a.channelBindingsLock.Lock() - defer a.channelBindingsLock.Unlock() - - for i := len(a.channelBindings) - 1; i >= 0; i-- { - if a.channelBindings[i].Number == number { - a.channelBindings = append(a.channelBindings[:i], a.channelBindings[i+1:]...) - return true - } - } - - return false -} - -// GetChannelByNumber gets the ChannelBind from this allocation by id -func (a *Allocation) GetChannelByNumber(number proto.ChannelNumber) *ChannelBind { - a.channelBindingsLock.RLock() - defer a.channelBindingsLock.RUnlock() - for _, cb := range a.channelBindings { - if cb.Number == number { - return cb - } - } - return nil -} - -// GetChannelByAddr gets the ChannelBind from this allocation by net.Addr -func (a *Allocation) GetChannelByAddr(addr net.Addr) *ChannelBind { - a.channelBindingsLock.RLock() - defer a.channelBindingsLock.RUnlock() - for _, cb := range a.channelBindings { - if ipnet.AddrEqual(cb.Peer, addr) { - return cb - } - } - return nil -} - -// Refresh updates the allocations lifetime -func (a *Allocation) Refresh(lifetime time.Duration) { - if !a.lifetimeTimer.Reset(lifetime) { - a.log.Errorf("Failed to reset allocation timer for %v", a.fiveTuple) - } -} - -// SetResponseCache cache allocation response for retransmit allocation request -func (a *Allocation) SetResponseCache(transactionID [stun.TransactionIDSize]byte, attrs []stun.Setter) { - a.responseCache.Store(&allocationResponse{ - transactionID: transactionID, - responseAttrs: attrs, - }) -} - -// GetResponseCache return response cache for retransmit allocation request -func (a *Allocation) GetResponseCache() (id [stun.TransactionIDSize]byte, attrs []stun.Setter) { - if res, ok := a.responseCache.Load().(*allocationResponse); ok && res != nil { - id, attrs = res.transactionID, res.responseAttrs - } - return -} - -// Close closes the allocation -func (a *Allocation) Close() error { - select { - case <-a.closed: - return nil - default: - } - close(a.closed) - - a.lifetimeTimer.Stop() - - a.permissionsLock.RLock() - for _, p := range a.permissions { - p.lifetimeTimer.Stop() - } - a.permissionsLock.RUnlock() - - a.channelBindingsLock.RLock() - for _, c := range a.channelBindings { - c.lifetimeTimer.Stop() - } - a.channelBindingsLock.RUnlock() - - return a.RelaySocket.Close() -} - -// https://tools.ietf.org/html/rfc5766#section-10.3 -// When the server receives a UDP datagram at a currently allocated -// relayed transport address, the server looks up the allocation -// associated with the relayed transport address. The server then -// checks to see whether the set of permissions for the allocation allow -// the relaying of the UDP datagram as described in Section 8. -// -// If relaying is permitted, then the server checks if there is a -// channel bound to the peer that sent the UDP datagram (see -// Section 11). If a channel is bound, then processing proceeds as -// described in Section 11.7. -// -// If relaying is permitted but no channel is bound to the peer, then -// the server forms and sends a Data indication. The Data indication -// MUST contain both an XOR-PEER-ADDRESS and a DATA attribute. The DATA -// attribute is set to the value of the 'data octets' field from the -// datagram, and the XOR-PEER-ADDRESS attribute is set to the source -// transport address of the received UDP datagram. The Data indication -// is then sent on the 5-tuple associated with the allocation. - -const rtpMTU = 1600 - -func (a *Allocation) packetHandler(m *Manager) { - buffer := make([]byte, rtpMTU) - - for { - n, srcAddr, err := a.RelaySocket.ReadFrom(buffer) - if err != nil { - m.DeleteAllocation(a.fiveTuple) - return - } - - a.log.Debugf("relay socket %s received %d bytes from %s", - a.RelaySocket.LocalAddr().String(), - n, - srcAddr.String()) - - if channel := a.GetChannelByAddr(srcAddr); channel != nil { - channelData := &proto.ChannelData{ - Data: buffer[:n], - Number: channel.Number, - } - channelData.Encode() - - if _, err = a.TurnSocket.WriteTo(channelData.Raw, a.fiveTuple.SrcAddr); err != nil { - a.log.Errorf("Failed to send ChannelData from allocation %v %v", srcAddr, err) - } - } else if p := a.GetPermission(srcAddr); p != nil { - udpAddr, ok := srcAddr.(*net.UDPAddr) - if !ok { - a.log.Errorf("Failed to send DataIndication from allocation %v %v", srcAddr, err) - return - } - - peerAddressAttr := proto.PeerAddress{IP: udpAddr.IP, Port: udpAddr.Port} - dataAttr := proto.Data(buffer[:n]) - - msg, err := stun.Build(stun.TransactionID, stun.NewType(stun.MethodData, stun.ClassIndication), peerAddressAttr, dataAttr) - if err != nil { - a.log.Errorf("Failed to send DataIndication from allocation %v %v", srcAddr, err) - return - } - a.log.Debugf("relaying message from %s to client at %s", - srcAddr.String(), - a.fiveTuple.SrcAddr.String()) - if _, err = a.TurnSocket.WriteTo(msg.Raw, a.fiveTuple.SrcAddr); err != nil { - a.log.Errorf("Failed to send DataIndication from allocation %v %v", srcAddr, err) - } - } else { - a.log.Infof("No Permission or Channel exists for %v on allocation %v", srcAddr, a.RelayAddr.String()) - } - } -} diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go b/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go deleted file mode 100644 index 5e924ac6..00000000 --- a/vendor/github.com/pion/turn/v2/internal/allocation/allocation_manager.go +++ /dev/null @@ -1,215 +0,0 @@ -package allocation - -import ( - "fmt" - "net" - "sync" - "time" - - "github.com/pion/logging" -) - -// ManagerConfig a bag of config params for Manager. -type ManagerConfig struct { - LeveledLogger logging.LeveledLogger - AllocatePacketConn func(network string, requestedPort int) (net.PacketConn, net.Addr, error) - AllocateConn func(network string, requestedPort int) (net.Conn, net.Addr, error) - PermissionHandler func(sourceAddr net.Addr, peerIP net.IP) bool -} - -type reservation struct { - token string - port int -} - -// Manager is used to hold active allocations -type Manager struct { - lock sync.RWMutex - log logging.LeveledLogger - - allocations map[string]*Allocation - reservations []*reservation - - allocatePacketConn func(network string, requestedPort int) (net.PacketConn, net.Addr, error) - allocateConn func(network string, requestedPort int) (net.Conn, net.Addr, error) - permissionHandler func(sourceAddr net.Addr, peerIP net.IP) bool -} - -// NewManager creates a new instance of Manager. -func NewManager(config ManagerConfig) (*Manager, error) { - switch { - case config.AllocatePacketConn == nil: - return nil, errAllocatePacketConnMustBeSet - case config.AllocateConn == nil: - return nil, errAllocateConnMustBeSet - case config.LeveledLogger == nil: - return nil, errLeveledLoggerMustBeSet - } - - return &Manager{ - log: config.LeveledLogger, - allocations: make(map[string]*Allocation, 64), - allocatePacketConn: config.AllocatePacketConn, - allocateConn: config.AllocateConn, - permissionHandler: config.PermissionHandler, - }, nil -} - -// GetAllocation fetches the allocation matching the passed FiveTuple -func (m *Manager) GetAllocation(fiveTuple *FiveTuple) *Allocation { - m.lock.RLock() - defer m.lock.RUnlock() - return m.allocations[fiveTuple.Fingerprint()] -} - -// AllocationCount returns the number of existing allocations -func (m *Manager) AllocationCount() int { - m.lock.RLock() - defer m.lock.RUnlock() - return len(m.allocations) -} - -// Close closes the manager and closes all allocations it manages -func (m *Manager) Close() error { - m.lock.Lock() - defer m.lock.Unlock() - - for _, a := range m.allocations { - if err := a.Close(); err != nil { - return err - } - } - return nil -} - -// CreateAllocation creates a new allocation and starts relaying -func (m *Manager) CreateAllocation(fiveTuple *FiveTuple, turnSocket net.PacketConn, requestedPort int, lifetime time.Duration) (*Allocation, error) { - switch { - case fiveTuple == nil: - return nil, errNilFiveTuple - case fiveTuple.SrcAddr == nil: - return nil, errNilFiveTupleSrcAddr - case fiveTuple.DstAddr == nil: - return nil, errNilFiveTupleDstAddr - case turnSocket == nil: - return nil, errNilTurnSocket - case lifetime == 0: - return nil, errLifetimeZero - } - - if a := m.GetAllocation(fiveTuple); a != nil { - return nil, fmt.Errorf("%w: %v", errDupeFiveTuple, fiveTuple) - } - a := NewAllocation(turnSocket, fiveTuple, m.log) - - conn, relayAddr, err := m.allocatePacketConn("udp4", requestedPort) - if err != nil { - return nil, err - } - - a.RelaySocket = conn - a.RelayAddr = relayAddr - - m.log.Debugf("listening on relay addr: %s", a.RelayAddr.String()) - - a.lifetimeTimer = time.AfterFunc(lifetime, func() { - m.DeleteAllocation(a.fiveTuple) - }) - - m.lock.Lock() - m.allocations[fiveTuple.Fingerprint()] = a - m.lock.Unlock() - - go a.packetHandler(m) - return a, nil -} - -// DeleteAllocation removes an allocation -func (m *Manager) DeleteAllocation(fiveTuple *FiveTuple) { - fingerprint := fiveTuple.Fingerprint() - - m.lock.Lock() - allocation := m.allocations[fingerprint] - delete(m.allocations, fingerprint) - m.lock.Unlock() - - if allocation == nil { - return - } - - if err := allocation.Close(); err != nil { - m.log.Errorf("Failed to close allocation: %v", err) - } -} - -// CreateReservation stores the reservation for the token+port -func (m *Manager) CreateReservation(reservationToken string, port int) { - time.AfterFunc(30*time.Second, func() { - m.lock.Lock() - defer m.lock.Unlock() - for i := len(m.reservations) - 1; i >= 0; i-- { - if m.reservations[i].token == reservationToken { - m.reservations = append(m.reservations[:i], m.reservations[i+1:]...) - return - } - } - }) - - m.lock.Lock() - m.reservations = append(m.reservations, &reservation{ - token: reservationToken, - port: port, - }) - m.lock.Unlock() -} - -// GetReservation returns the port for a given reservation if it exists -func (m *Manager) GetReservation(reservationToken string) (int, bool) { - m.lock.RLock() - defer m.lock.RUnlock() - - for _, r := range m.reservations { - if r.token == reservationToken { - return r.port, true - } - } - return 0, false -} - -// GetRandomEvenPort returns a random un-allocated udp4 port -func (m *Manager) GetRandomEvenPort() (int, error) { - for i := 0; i < 128; i++ { - conn, addr, err := m.allocatePacketConn("udp4", 0) - if err != nil { - return 0, err - } - udpAddr, ok := addr.(*net.UDPAddr) - err = conn.Close() - if err != nil { - return 0, err - } - - if !ok { - return 0, errFailedToCastUDPAddr - } - if udpAddr.Port%2 == 0 { - return udpAddr.Port, nil - } - } - return 0, errFailedToAllocateEvenPort -} - -// GrantPermission handles permission requests by calling the permission handler callback -// associated with the TURN server listener socket -func (m *Manager) GrantPermission(sourceAddr net.Addr, peerIP net.IP) error { - // no permission handler: open - if m.permissionHandler == nil { - return nil - } - - if m.permissionHandler(sourceAddr, peerIP) { - return nil - } - - return errAdminProhibited -} diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/channel_bind.go b/vendor/github.com/pion/turn/v2/internal/allocation/channel_bind.go deleted file mode 100644 index 6216369d..00000000 --- a/vendor/github.com/pion/turn/v2/internal/allocation/channel_bind.go +++ /dev/null @@ -1,43 +0,0 @@ -package allocation - -import ( - "net" - "time" - - "github.com/pion/logging" - "github.com/pion/turn/v2/internal/proto" -) - -// ChannelBind represents a TURN Channel -// https://tools.ietf.org/html/rfc5766#section-2.5 -type ChannelBind struct { - Peer net.Addr - Number proto.ChannelNumber - - allocation *Allocation - lifetimeTimer *time.Timer - log logging.LeveledLogger -} - -// NewChannelBind creates a new ChannelBind -func NewChannelBind(number proto.ChannelNumber, peer net.Addr, log logging.LeveledLogger) *ChannelBind { - return &ChannelBind{ - Number: number, - Peer: peer, - log: log, - } -} - -func (c *ChannelBind) start(lifetime time.Duration) { - c.lifetimeTimer = time.AfterFunc(lifetime, func() { - if !c.allocation.RemoveChannelBind(c.Number) { - c.log.Errorf("Failed to remove ChannelBind for %v %x %v", c.Number, c.Peer, c.allocation.fiveTuple) - } - }) -} - -func (c *ChannelBind) refresh(lifetime time.Duration) { - if !c.lifetimeTimer.Reset(lifetime) { - c.log.Errorf("Failed to reset ChannelBind timer for %v %x %v", c.Number, c.Peer, c.allocation.fiveTuple) - } -} diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/errors.go b/vendor/github.com/pion/turn/v2/internal/allocation/errors.go deleted file mode 100644 index b9677e11..00000000 --- a/vendor/github.com/pion/turn/v2/internal/allocation/errors.go +++ /dev/null @@ -1,19 +0,0 @@ -package allocation - -import "errors" - -var ( - errAllocatePacketConnMustBeSet = errors.New("AllocatePacketConn must be set") - errAllocateConnMustBeSet = errors.New("AllocateConn must be set") - errLeveledLoggerMustBeSet = errors.New("LeveledLogger must be set") - errSameChannelDifferentPeer = errors.New("you cannot use the same channel number with different peer") - errNilFiveTuple = errors.New("allocations must not be created with nil FivTuple") - errNilFiveTupleSrcAddr = errors.New("allocations must not be created with nil FiveTuple.SrcAddr") - errNilFiveTupleDstAddr = errors.New("allocations must not be created with nil FiveTuple.DstAddr") - errNilTurnSocket = errors.New("allocations must not be created with nil turnSocket") - errLifetimeZero = errors.New("allocations must not be created with a lifetime of 0") - errDupeFiveTuple = errors.New("allocation attempt created with duplicate FiveTuple") - errFailedToCastUDPAddr = errors.New("failed to cast net.Addr to *net.UDPAddr") - errFailedToAllocateEvenPort = errors.New("failed to allocate an even port") - errAdminProhibited = errors.New("permission request administratively prohibited") -) diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go b/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go deleted file mode 100644 index 1f2b3b5b..00000000 --- a/vendor/github.com/pion/turn/v2/internal/allocation/five_tuple.go +++ /dev/null @@ -1,36 +0,0 @@ -package allocation - -import ( - "fmt" - "net" -) - -// Protocol is an enum for relay protocol -type Protocol uint8 - -// Network protocols for relay -const ( - UDP Protocol = iota - TCP -) - -// FiveTuple is the combination (client IP address and port, server IP -// address and port, and transport protocol (currently one of UDP, -// TCP, or TLS)) used to communicate between the client and the -// server. The 5-tuple uniquely identifies this communication -// stream. The 5-tuple also uniquely identifies the Allocation on -// the server. -type FiveTuple struct { - Protocol - SrcAddr, DstAddr net.Addr -} - -// Equal asserts if two FiveTuples are equal -func (f *FiveTuple) Equal(b *FiveTuple) bool { - return f.Fingerprint() == b.Fingerprint() -} - -// Fingerprint is the identity of a FiveTuple -func (f *FiveTuple) Fingerprint() string { - return fmt.Sprintf("%d_%s_%s", f.Protocol, f.SrcAddr.String(), f.DstAddr.String()) -} diff --git a/vendor/github.com/pion/turn/v2/internal/allocation/permission.go b/vendor/github.com/pion/turn/v2/internal/allocation/permission.go deleted file mode 100644 index 03538eb5..00000000 --- a/vendor/github.com/pion/turn/v2/internal/allocation/permission.go +++ /dev/null @@ -1,40 +0,0 @@ -package allocation - -import ( - "net" - "time" - - "github.com/pion/logging" -) - -const permissionTimeout = time.Duration(5) * time.Minute - -// Permission represents a TURN permission. TURN permissions mimic the address-restricted -// filtering mechanism of NATs that comply with [RFC4787]. -// https://tools.ietf.org/html/rfc5766#section-2.3 -type Permission struct { - Addr net.Addr - allocation *Allocation - lifetimeTimer *time.Timer - log logging.LeveledLogger -} - -// NewPermission create a new Permission -func NewPermission(addr net.Addr, log logging.LeveledLogger) *Permission { - return &Permission{ - Addr: addr, - log: log, - } -} - -func (p *Permission) start(lifetime time.Duration) { - p.lifetimeTimer = time.AfterFunc(lifetime, func() { - p.allocation.RemovePermission(p.Addr) - }) -} - -func (p *Permission) refresh(lifetime time.Duration) { - if !p.lifetimeTimer.Reset(lifetime) { - p.log.Errorf("Failed to reset permission timer for %v %v", p.Addr, p.allocation.fiveTuple) - } -} diff --git a/vendor/github.com/pion/turn/v2/internal/client/binding.go b/vendor/github.com/pion/turn/v2/internal/client/binding.go deleted file mode 100644 index f4d6fa2b..00000000 --- a/vendor/github.com/pion/turn/v2/internal/client/binding.go +++ /dev/null @@ -1,152 +0,0 @@ -package client - -import ( - "net" - "sync" - "sync/atomic" - "time" -) - -// Channel number: -// -// 0x4000 through 0x7FFF: These values are the allowed channel -// numbers (16,383 possible values). -const ( - minChannelNumber uint16 = 0x4000 - maxChannelNumber uint16 = 0x7fff -) - -type bindingState int32 - -const ( - bindingStateIdle bindingState = iota - bindingStateRequest - bindingStateReady - bindingStateRefresh - bindingStateFailed -) - -type binding struct { - number uint16 // read-only - st bindingState // thread-safe (atomic op) - addr net.Addr // read-only - mgr *bindingManager // read-only - muBind sync.Mutex // thread-safe, for ChannelBind ops - _refreshedAt time.Time // protected by mutex - mutex sync.RWMutex // thread-safe -} - -func (b *binding) setState(state bindingState) { - atomic.StoreInt32((*int32)(&b.st), int32(state)) -} - -func (b *binding) state() bindingState { - return bindingState(atomic.LoadInt32((*int32)(&b.st))) -} - -func (b *binding) setRefreshedAt(at time.Time) { - b.mutex.Lock() - defer b.mutex.Unlock() - - b._refreshedAt = at -} - -func (b *binding) refreshedAt() time.Time { - b.mutex.RLock() - defer b.mutex.RUnlock() - - return b._refreshedAt -} - -// Thread-safe binding map -type bindingManager struct { - chanMap map[uint16]*binding - addrMap map[string]*binding - next uint16 - mutex sync.RWMutex -} - -func newBindingManager() *bindingManager { - return &bindingManager{ - chanMap: map[uint16]*binding{}, - addrMap: map[string]*binding{}, - next: minChannelNumber, - } -} - -func (mgr *bindingManager) assignChannelNumber() uint16 { - n := mgr.next - if mgr.next == maxChannelNumber { - mgr.next = minChannelNumber - } else { - mgr.next++ - } - return n -} - -func (mgr *bindingManager) create(addr net.Addr) *binding { - mgr.mutex.Lock() - defer mgr.mutex.Unlock() - - b := &binding{ - number: mgr.assignChannelNumber(), - addr: addr, - mgr: mgr, - _refreshedAt: time.Now(), - } - - mgr.chanMap[b.number] = b - mgr.addrMap[b.addr.String()] = b - return b -} - -func (mgr *bindingManager) findByAddr(addr net.Addr) (*binding, bool) { - mgr.mutex.RLock() - defer mgr.mutex.RUnlock() - - b, ok := mgr.addrMap[addr.String()] - return b, ok -} - -func (mgr *bindingManager) findByNumber(number uint16) (*binding, bool) { - mgr.mutex.RLock() - defer mgr.mutex.RUnlock() - - b, ok := mgr.chanMap[number] - return b, ok -} - -func (mgr *bindingManager) deleteByAddr(addr net.Addr) bool { - mgr.mutex.Lock() - defer mgr.mutex.Unlock() - - b, ok := mgr.addrMap[addr.String()] - if !ok { - return false - } - - delete(mgr.addrMap, addr.String()) - delete(mgr.chanMap, b.number) - return true -} - -func (mgr *bindingManager) deleteByNumber(number uint16) bool { - mgr.mutex.Lock() - defer mgr.mutex.Unlock() - - b, ok := mgr.chanMap[number] - if !ok { - return false - } - - delete(mgr.addrMap, b.addr.String()) - delete(mgr.chanMap, number) - return true -} - -func (mgr *bindingManager) size() int { - mgr.mutex.RLock() - defer mgr.mutex.RUnlock() - - return len(mgr.chanMap) -} diff --git a/vendor/github.com/pion/turn/v2/internal/client/conn.go b/vendor/github.com/pion/turn/v2/internal/client/conn.go deleted file mode 100644 index 8aeb742c..00000000 --- a/vendor/github.com/pion/turn/v2/internal/client/conn.go +++ /dev/null @@ -1,623 +0,0 @@ -// Package client implements the API for a TURN client -package client - -import ( - "errors" - "fmt" - "io" - "math" - "net" - "sync" - "time" - - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/proto" -) - -const ( - maxReadQueueSize = 1024 - permRefreshInterval = 120 * time.Second - maxRetryAttempts = 3 -) - -const ( - timerIDRefreshAlloc int = iota - timerIDRefreshPerms -) - -func noDeadline() time.Time { - return time.Time{} -} - -type inboundData struct { - data []byte - from net.Addr -} - -// UDPConnObserver is an interface to UDPConn observer -type UDPConnObserver interface { - TURNServerAddr() net.Addr - Username() stun.Username - Realm() stun.Realm - WriteTo(data []byte, to net.Addr) (int, error) - PerformTransaction(msg *stun.Message, to net.Addr, dontWait bool) (TransactionResult, error) - OnDeallocated(relayedAddr net.Addr) -} - -// UDPConnConfig is a set of configuration params use by NewUDPConn -type UDPConnConfig struct { - Observer UDPConnObserver - RelayedAddr net.Addr - Integrity stun.MessageIntegrity - Nonce stun.Nonce - Lifetime time.Duration - Log logging.LeveledLogger -} - -// UDPConn is the implementation of the Conn and PacketConn interfaces for UDP network connections. -// comatible with net.PacketConn and net.Conn -type UDPConn struct { - obs UDPConnObserver // read-only - relayedAddr net.Addr // read-only - permMap *permissionMap // thread-safe - bindingMgr *bindingManager // thread-safe - integrity stun.MessageIntegrity // read-only - _nonce stun.Nonce // needs mutex x - _lifetime time.Duration // needs mutex x - readCh chan *inboundData // thread-safe - closeCh chan struct{} // thread-safe - readTimer *time.Timer // thread-safe - refreshAllocTimer *PeriodicTimer // thread-safe - refreshPermsTimer *PeriodicTimer // thread-safe - mutex sync.RWMutex // thread-safe - log logging.LeveledLogger // read-only -} - -// NewUDPConn creates a new instance of UDPConn -func NewUDPConn(config *UDPConnConfig) *UDPConn { - c := &UDPConn{ - obs: config.Observer, - relayedAddr: config.RelayedAddr, - permMap: newPermissionMap(), - bindingMgr: newBindingManager(), - integrity: config.Integrity, - _nonce: config.Nonce, - _lifetime: config.Lifetime, - readCh: make(chan *inboundData, maxReadQueueSize), - closeCh: make(chan struct{}), - readTimer: time.NewTimer(time.Duration(math.MaxInt64)), - log: config.Log, - } - - c.log.Debugf("initial lifetime: %d seconds", int(c.lifetime().Seconds())) - - c.refreshAllocTimer = NewPeriodicTimer( - timerIDRefreshAlloc, - c.onRefreshTimers, - c.lifetime()/2, - ) - - c.refreshPermsTimer = NewPeriodicTimer( - timerIDRefreshPerms, - c.onRefreshTimers, - permRefreshInterval, - ) - - if c.refreshAllocTimer.Start() { - c.log.Debugf("refreshAllocTimer started") - } - if c.refreshPermsTimer.Start() { - c.log.Debugf("refreshPermsTimer started") - } - - return c -} - -// ReadFrom reads a packet from the connection, -// copying the payload into p. It returns the number of -// bytes copied into p and the return address that -// was on the packet. -// It returns the number of bytes read (0 <= n <= len(p)) -// and any error encountered. Callers should always process -// the n > 0 bytes returned before considering the error err. -// ReadFrom can be made to time out and return -// an Error with Timeout() == true after a fixed time limit; -// see SetDeadline and SetReadDeadline. -func (c *UDPConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { - for { - select { - case ibData := <-c.readCh: - n := copy(p, ibData.data) - if n < len(ibData.data) { - return 0, nil, io.ErrShortBuffer - } - return n, ibData.from, nil - - case <-c.readTimer.C: - return 0, nil, &net.OpError{ - Op: "read", - Net: c.LocalAddr().Network(), - Addr: c.LocalAddr(), - Err: newTimeoutError("i/o timeout"), - } - - case <-c.closeCh: - return 0, nil, &net.OpError{ - Op: "read", - Net: c.LocalAddr().Network(), - Addr: c.LocalAddr(), - Err: errClosed, - } - } - } -} - -func (c *UDPConn) createPermission(perm *permission, addr net.Addr) error { - perm.mutex.Lock() - defer perm.mutex.Unlock() - - if perm.state() == permStateIdle { - // punch a hole! (this would block a bit..) - if err := c.CreatePermissions(addr); err != nil { - c.permMap.delete(addr) - return err - } - perm.setState(permStatePermitted) - } - return nil -} - -// WriteTo writes a packet with payload p to addr. -// WriteTo can be made to time out and return -// an Error with Timeout() == true after a fixed time limit; -// see SetDeadline and SetWriteDeadline. -// On packet-oriented connections, write timeouts are rare. -func (c *UDPConn) WriteTo(p []byte, addr net.Addr) (int, error) { //nolint: gocognit - var err error - _, ok := addr.(*net.UDPAddr) - if !ok { - return 0, errUDPAddrCast - } - - // check if we have a permission for the destination IP addr - perm, ok := c.permMap.find(addr) - if !ok { - perm = &permission{} - c.permMap.insert(addr, perm) - } - - for i := 0; i < maxRetryAttempts; i++ { - // c.createPermission() would block, per destination IP (, or perm), - // until the perm state becomes "requested". Purpose of this is to - // guarantee the order of packets (within the same perm). - // Note that CreatePermission transaction may not be complete before - // all the data transmission. This is done assuming that the request - // will be most likely successful and we can tolerate some loss of - // UDP packet (or reorder), inorder to minimize the latency in most cases. - if err = c.createPermission(perm, addr); !errors.Is(err, errTryAgain) { - break - } - } - if err != nil { - return 0, err - } - - // bind channel - b, ok := c.bindingMgr.findByAddr(addr) - if !ok { - b = c.bindingMgr.create(addr) - } - - bindSt := b.state() - - if bindSt == bindingStateIdle || bindSt == bindingStateRequest || bindSt == bindingStateFailed { - func() { - // block only callers with the same binding until - // the binding transaction has been complete - b.muBind.Lock() - defer b.muBind.Unlock() - - // binding state may have been changed while waiting. check again. - if b.state() == bindingStateIdle { - b.setState(bindingStateRequest) - go func() { - err2 := c.bind(b) - if err2 != nil { - c.log.Warnf("bind() failed: %s", err2.Error()) - b.setState(bindingStateFailed) - // keep going... - } else { - b.setState(bindingStateReady) - } - }() - } - }() - - // send data using SendIndication - peerAddr := addr2PeerAddress(addr) - var msg *stun.Message - msg, err = stun.Build( - stun.TransactionID, - stun.NewType(stun.MethodSend, stun.ClassIndication), - proto.Data(p), - peerAddr, - stun.Fingerprint, - ) - if err != nil { - return 0, err - } - - // indication has no transaction (fire-and-forget) - - return c.obs.WriteTo(msg.Raw, c.obs.TURNServerAddr()) - } - - // binding is either ready - - // check if the binding needs a refresh - func() { - b.muBind.Lock() - defer b.muBind.Unlock() - - if b.state() == bindingStateReady && time.Since(b.refreshedAt()) > 5*time.Minute { - b.setState(bindingStateRefresh) - go func() { - err = c.bind(b) - if err != nil { - c.log.Warnf("bind() for refresh failed: %s", err.Error()) - b.setState(bindingStateFailed) - // keep going... - } else { - b.setRefreshedAt(time.Now()) - b.setState(bindingStateReady) - } - }() - } - }() - - // send via ChannelData - _, err = c.sendChannelData(p, b.number) - if err != nil { - return 0, err - } - return len(p), nil -} - -// Close closes the connection. -// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors. -func (c *UDPConn) Close() error { - c.refreshAllocTimer.Stop() - c.refreshPermsTimer.Stop() - - select { - case <-c.closeCh: - return errAlreadyClosed - default: - close(c.closeCh) - } - - c.obs.OnDeallocated(c.relayedAddr) - return c.refreshAllocation(0, true /* dontWait=true */) -} - -// LocalAddr returns the local network address. -func (c *UDPConn) LocalAddr() net.Addr { - return c.relayedAddr -} - -// SetDeadline sets the read and write deadlines associated -// with the connection. It is equivalent to calling both -// SetReadDeadline and SetWriteDeadline. -// -// A deadline is an absolute time after which I/O operations -// fail with a timeout (see type Error) instead of -// blocking. The deadline applies to all future and pending -// I/O, not just the immediately following call to ReadFrom or -// WriteTo. After a deadline has been exceeded, the connection -// can be refreshed by setting a deadline in the future. -// -// An idle timeout can be implemented by repeatedly extending -// the deadline after successful ReadFrom or WriteTo calls. -// -// A zero value for t means I/O operations will not time out. -func (c *UDPConn) SetDeadline(t time.Time) error { - return c.SetReadDeadline(t) -} - -// SetReadDeadline sets the deadline for future ReadFrom calls -// and any currently-blocked ReadFrom call. -// A zero value for t means ReadFrom will not time out. -func (c *UDPConn) SetReadDeadline(t time.Time) error { - var d time.Duration - if t == noDeadline() { - d = time.Duration(math.MaxInt64) - } else { - d = time.Until(t) - } - c.readTimer.Reset(d) - return nil -} - -// SetWriteDeadline sets the deadline for future WriteTo calls -// and any currently-blocked WriteTo call. -// Even if write times out, it may return n > 0, indicating that -// some of the data was successfully written. -// A zero value for t means WriteTo will not time out. -func (c *UDPConn) SetWriteDeadline(t time.Time) error { - // Write never blocks. - return nil -} - -func addr2PeerAddress(addr net.Addr) proto.PeerAddress { - var peerAddr proto.PeerAddress - switch a := addr.(type) { - case *net.UDPAddr: - peerAddr.IP = a.IP - peerAddr.Port = a.Port - case *net.TCPAddr: - peerAddr.IP = a.IP - peerAddr.Port = a.Port - } - - return peerAddr -} - -// CreatePermissions Issues a CreatePermission request for the supplied addresses -// as described in https://datatracker.ietf.org/doc/html/rfc5766#section-9 -func (c *UDPConn) CreatePermissions(addrs ...net.Addr) error { - setters := []stun.Setter{ - stun.TransactionID, - stun.NewType(stun.MethodCreatePermission, stun.ClassRequest), - } - - for _, addr := range addrs { - setters = append(setters, addr2PeerAddress(addr)) - } - - setters = append(setters, - c.obs.Username(), - c.obs.Realm(), - c.nonce(), - c.integrity, - stun.Fingerprint) - - msg, err := stun.Build(setters...) - if err != nil { - return err - } - - trRes, err := c.obs.PerformTransaction(msg, c.obs.TURNServerAddr(), false) - if err != nil { - return err - } - - res := trRes.Msg - - if res.Type.Class == stun.ClassErrorResponse { - var code stun.ErrorCodeAttribute - if err = code.GetFrom(res); err == nil { - if code.Code == stun.CodeStaleNonce { - c.setNonceFromMsg(res) - return errTryAgain - } - return fmt.Errorf("%s (error %s)", res.Type, code) //nolint:goerr113 - } - - return fmt.Errorf("%s", res.Type) //nolint:goerr113 - } - - return nil -} - -// HandleInbound passes inbound data in UDPConn -func (c *UDPConn) HandleInbound(data []byte, from net.Addr) { - // copy data - copied := make([]byte, len(data)) - copy(copied, data) - - select { - case c.readCh <- &inboundData{data: copied, from: from}: - default: - c.log.Warnf("receive buffer full") - } -} - -// FindAddrByChannelNumber returns a peer address associated with the -// channel number on this UDPConn -func (c *UDPConn) FindAddrByChannelNumber(chNum uint16) (net.Addr, bool) { - b, ok := c.bindingMgr.findByNumber(chNum) - if !ok { - return nil, false - } - return b.addr, true -} - -func (c *UDPConn) setNonceFromMsg(msg *stun.Message) { - // Update nonce - var nonce stun.Nonce - if err := nonce.GetFrom(msg); err == nil { - c.setNonce(nonce) - c.log.Debug("refresh allocation: 438, got new nonce.") - } else { - c.log.Warn("refresh allocation: 438 but no nonce.") - } -} - -func (c *UDPConn) refreshAllocation(lifetime time.Duration, dontWait bool) error { - msg, err := stun.Build( - stun.TransactionID, - stun.NewType(stun.MethodRefresh, stun.ClassRequest), - proto.Lifetime{Duration: lifetime}, - c.obs.Username(), - c.obs.Realm(), - c.nonce(), - c.integrity, - stun.Fingerprint, - ) - if err != nil { - return fmt.Errorf("%w: %s", errFailedToBuildRefreshRequest, err.Error()) - } - - c.log.Debugf("send refresh request (dontWait=%v)", dontWait) - trRes, err := c.obs.PerformTransaction(msg, c.obs.TURNServerAddr(), dontWait) - if err != nil { - return fmt.Errorf("%w: %s", errFailedToRefreshAllocation, err.Error()) - } - - if dontWait { - c.log.Debug("refresh request sent") - return nil - } - - c.log.Debug("refresh request sent, and waiting response") - - res := trRes.Msg - if res.Type.Class == stun.ClassErrorResponse { - var code stun.ErrorCodeAttribute - if err = code.GetFrom(res); err == nil { - if code.Code == stun.CodeStaleNonce { - c.setNonceFromMsg(res) - return errTryAgain - } - return err - } - return fmt.Errorf("%s", res.Type) //nolint:goerr113 - } - - // Getting lifetime from response - var updatedLifetime proto.Lifetime - if err := updatedLifetime.GetFrom(res); err != nil { - return fmt.Errorf("%w: %s", errFailedToGetLifetime, err.Error()) - } - - c.setLifetime(updatedLifetime.Duration) - c.log.Debugf("updated lifetime: %d seconds", int(c.lifetime().Seconds())) - return nil -} - -func (c *UDPConn) refreshPermissions() error { - addrs := c.permMap.addrs() - if len(addrs) == 0 { - c.log.Debug("no permission to refresh") - return nil - } - if err := c.CreatePermissions(addrs...); err != nil { - if errors.Is(err, errTryAgain) { - return errTryAgain - } - c.log.Errorf("fail to refresh permissions: %s", err.Error()) - return err - } - c.log.Debug("refresh permissions successful") - return nil -} - -func (c *UDPConn) bind(b *binding) error { - setters := []stun.Setter{ - stun.TransactionID, - stun.NewType(stun.MethodChannelBind, stun.ClassRequest), - addr2PeerAddress(b.addr), - proto.ChannelNumber(b.number), - c.obs.Username(), - c.obs.Realm(), - c.nonce(), - c.integrity, - stun.Fingerprint, - } - - msg, err := stun.Build(setters...) - if err != nil { - return err - } - - trRes, err := c.obs.PerformTransaction(msg, c.obs.TURNServerAddr(), false) - if err != nil { - c.bindingMgr.deleteByAddr(b.addr) - return err - } - - res := trRes.Msg - - if res.Type != stun.NewType(stun.MethodChannelBind, stun.ClassSuccessResponse) { - return fmt.Errorf("unexpected response type %s", res.Type) //nolint:goerr113 - } - - c.log.Debugf("channel binding successful: %s %d", b.addr.String(), b.number) - - // Success. - return nil -} - -func (c *UDPConn) sendChannelData(data []byte, chNum uint16) (int, error) { - chData := &proto.ChannelData{ - Data: data, - Number: proto.ChannelNumber(chNum), - } - chData.Encode() - _, err := c.obs.WriteTo(chData.Raw, c.obs.TURNServerAddr()) - if err != nil { - return 0, err - } - return len(data), nil -} - -func (c *UDPConn) onRefreshTimers(id int) { - c.log.Debugf("refresh timer %d expired", id) - switch id { - case timerIDRefreshAlloc: - var err error - lifetime := c.lifetime() - // limit the max retries on errTryAgain to 3 - // when stale nonce returns, sencond retry should succeed - for i := 0; i < maxRetryAttempts; i++ { - err = c.refreshAllocation(lifetime, false) - if !errors.Is(err, errTryAgain) { - break - } - } - if err != nil { - c.log.Warnf("refresh allocation failed") - } - case timerIDRefreshPerms: - var err error - for i := 0; i < maxRetryAttempts; i++ { - err = c.refreshPermissions() - if !errors.Is(err, errTryAgain) { - break - } - } - if err != nil { - c.log.Warnf("refresh permissions failed") - } - } -} - -func (c *UDPConn) nonce() stun.Nonce { - c.mutex.RLock() - defer c.mutex.RUnlock() - - return c._nonce -} - -func (c *UDPConn) setNonce(nonce stun.Nonce) { - c.mutex.Lock() - defer c.mutex.Unlock() - - c.log.Debugf("set new nonce with %d bytes", len(nonce)) - c._nonce = nonce -} - -func (c *UDPConn) lifetime() time.Duration { - c.mutex.RLock() - defer c.mutex.RUnlock() - - return c._lifetime -} - -func (c *UDPConn) setLifetime(lifetime time.Duration) { - c.mutex.Lock() - defer c.mutex.Unlock() - - c._lifetime = lifetime -} diff --git a/vendor/github.com/pion/turn/v2/internal/client/errors.go b/vendor/github.com/pion/turn/v2/internal/client/errors.go deleted file mode 100644 index 7fc816fd..00000000 --- a/vendor/github.com/pion/turn/v2/internal/client/errors.go +++ /dev/null @@ -1,37 +0,0 @@ -package client - -import ( - "errors" -) - -var ( - errFake = errors.New("fake error") - errTryAgain = errors.New("try again") - errClosed = errors.New("use of closed network connection") - errUDPAddrCast = errors.New("addr is not a net.UDPAddr") - errAlreadyClosed = errors.New("already closed") - errDoubleLock = errors.New("try-lock is already locked") - errTransactionClosed = errors.New("transaction closed") - errWaitForResultOnNonResultTransaction = errors.New("WaitForResult called on non-result transaction") - errFailedToBuildRefreshRequest = errors.New("failed to build refresh request") - errFailedToRefreshAllocation = errors.New("failed to refresh allocation") - errFailedToGetLifetime = errors.New("failed to get lifetime from refresh response") -) - -type timeoutError struct { - msg string -} - -func newTimeoutError(msg string) error { - return &timeoutError{ - msg: msg, - } -} - -func (e *timeoutError) Error() string { - return e.msg -} - -func (e *timeoutError) Timeout() bool { - return true -} diff --git a/vendor/github.com/pion/turn/v2/internal/client/periodic_timer.go b/vendor/github.com/pion/turn/v2/internal/client/periodic_timer.go deleted file mode 100644 index fcd56787..00000000 --- a/vendor/github.com/pion/turn/v2/internal/client/periodic_timer.go +++ /dev/null @@ -1,82 +0,0 @@ -package client - -import ( - "sync" - "time" -) - -// PeriodicTimerTimeoutHandler is a handler called on timeout -type PeriodicTimerTimeoutHandler func(timerID int) - -// PeriodicTimer is a periodic timer -type PeriodicTimer struct { - id int - interval time.Duration - timeoutHandler PeriodicTimerTimeoutHandler - stopFunc func() - mutex sync.RWMutex -} - -// NewPeriodicTimer create a new timer -func NewPeriodicTimer(id int, timeoutHandler PeriodicTimerTimeoutHandler, interval time.Duration) *PeriodicTimer { - return &PeriodicTimer{ - id: id, - interval: interval, - timeoutHandler: timeoutHandler, - } -} - -// Start starts the timer. -func (t *PeriodicTimer) Start() bool { - t.mutex.Lock() - defer t.mutex.Unlock() - - // this is a noop if the timer is always running - if t.stopFunc != nil { - return false - } - - cancelCh := make(chan struct{}) - - go func() { - canceling := false - - for !canceling { - timer := time.NewTimer(t.interval) - - select { - case <-timer.C: - t.timeoutHandler(t.id) - case <-cancelCh: - canceling = true - timer.Stop() - } - } - }() - - t.stopFunc = func() { - close(cancelCh) - } - - return true -} - -// Stop stops the timer. -func (t *PeriodicTimer) Stop() { - t.mutex.Lock() - defer t.mutex.Unlock() - - if t.stopFunc != nil { - t.stopFunc() - t.stopFunc = nil - } -} - -// IsRunning tests if the timer is running. -// Debug purpose only -func (t *PeriodicTimer) IsRunning() bool { - t.mutex.RLock() - defer t.mutex.RUnlock() - - return (t.stopFunc != nil) -} diff --git a/vendor/github.com/pion/turn/v2/internal/client/permission.go b/vendor/github.com/pion/turn/v2/internal/client/permission.go deleted file mode 100644 index 5546a22e..00000000 --- a/vendor/github.com/pion/turn/v2/internal/client/permission.go +++ /dev/null @@ -1,90 +0,0 @@ -package client - -import ( - "net" - "sync" - "sync/atomic" -) - -type permState int32 - -const ( - permStateIdle permState = iota - permStatePermitted -) - -type permission struct { - st permState // thread-safe (atomic op) - mutex sync.RWMutex // thread-safe -} - -func (p *permission) setState(state permState) { - atomic.StoreInt32((*int32)(&p.st), int32(state)) -} - -func (p *permission) state() permState { - return permState(atomic.LoadInt32((*int32)(&p.st))) -} - -// Thread-safe permission map -type permissionMap struct { - permMap map[string]*permission - mutex sync.RWMutex -} - -func (m *permissionMap) insert(addr net.Addr, p *permission) bool { - m.mutex.Lock() - defer m.mutex.Unlock() - - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - return false - } - - m.permMap[udpAddr.IP.String()] = p - return true -} - -func (m *permissionMap) find(addr net.Addr) (*permission, bool) { - m.mutex.RLock() - defer m.mutex.RUnlock() - - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - return nil, false - } - - p, ok := m.permMap[udpAddr.IP.String()] - return p, ok -} - -func (m *permissionMap) delete(addr net.Addr) { - m.mutex.Lock() - defer m.mutex.Unlock() - - udpAddr, ok := addr.(*net.UDPAddr) - if !ok { - return - } - - delete(m.permMap, udpAddr.IP.String()) -} - -func (m *permissionMap) addrs() []net.Addr { - m.mutex.RLock() - defer m.mutex.RUnlock() - - addrs := []net.Addr{} - for k := range m.permMap { - addrs = append(addrs, &net.UDPAddr{ - IP: net.ParseIP(k), - }) - } - return addrs -} - -func newPermissionMap() *permissionMap { - return &permissionMap{ - permMap: map[string]*permission{}, - } -} diff --git a/vendor/github.com/pion/turn/v2/internal/client/transaction.go b/vendor/github.com/pion/turn/v2/internal/client/transaction.go deleted file mode 100644 index 54024b44..00000000 --- a/vendor/github.com/pion/turn/v2/internal/client/transaction.go +++ /dev/null @@ -1,185 +0,0 @@ -package client - -import ( - "net" - "sync" - "time" - - "github.com/pion/stun" -) - -const ( - maxRtxInterval time.Duration = 1600 * time.Millisecond -) - -// TransactionResult is a bag of result values of a transaction -type TransactionResult struct { - Msg *stun.Message - From net.Addr - Retries int - Err error -} - -// TransactionConfig is a set of config params used by NewTransaction -type TransactionConfig struct { - Key string - Raw []byte - To net.Addr - Interval time.Duration - IgnoreResult bool // true to throw away the result of this transaction (it will not be readable using WaitForResult) -} - -// Transaction represents a transaction -type Transaction struct { - Key string // read-only - Raw []byte // read-only - To net.Addr // read-only - nRtx int // modified only by the timer thread - interval time.Duration // modified only by the timer thread - timer *time.Timer // thread-safe, set only by the creator, and stopper - resultCh chan TransactionResult // thread-safe - mutex sync.RWMutex -} - -// NewTransaction creates a new instance of Transaction -func NewTransaction(config *TransactionConfig) *Transaction { - var resultCh chan TransactionResult - if !config.IgnoreResult { - resultCh = make(chan TransactionResult) - } - - return &Transaction{ - Key: config.Key, // read-only - Raw: config.Raw, // read-only - To: config.To, // read-only - interval: config.Interval, // modified only by the timer thread - resultCh: resultCh, // thread-safe - } -} - -// StartRtxTimer starts the transaction timer -func (t *Transaction) StartRtxTimer(onTimeout func(trKey string, nRtx int)) { - t.mutex.Lock() - defer t.mutex.Unlock() - - t.timer = time.AfterFunc(t.interval, func() { - t.mutex.Lock() - t.nRtx++ - nRtx := t.nRtx - t.interval *= 2 - if t.interval > maxRtxInterval { - t.interval = maxRtxInterval - } - t.mutex.Unlock() - onTimeout(t.Key, nRtx) - }) -} - -// StopRtxTimer stop the transaction timer -func (t *Transaction) StopRtxTimer() { - t.mutex.Lock() - defer t.mutex.Unlock() - - if t.timer != nil { - t.timer.Stop() - } -} - -// WriteResult writes the result to the result channel -func (t *Transaction) WriteResult(res TransactionResult) bool { - if t.resultCh == nil { - return false - } - - t.resultCh <- res - - return true -} - -// WaitForResult waits for the transaction result -func (t *Transaction) WaitForResult() TransactionResult { - if t.resultCh == nil { - return TransactionResult{ - Err: errWaitForResultOnNonResultTransaction, - } - } - - result, ok := <-t.resultCh - if !ok { - result.Err = errTransactionClosed - } - return result -} - -// Close closes the transaction -func (t *Transaction) Close() { - if t.resultCh != nil { - close(t.resultCh) - } -} - -// Retries returns the number of retransmission it has made -func (t *Transaction) Retries() int { - t.mutex.RLock() - defer t.mutex.RUnlock() - - return t.nRtx -} - -// TransactionMap is a thread-safe transaction map -type TransactionMap struct { - trMap map[string]*Transaction - mutex sync.RWMutex -} - -// NewTransactionMap create a new instance of the transaction map -func NewTransactionMap() *TransactionMap { - return &TransactionMap{ - trMap: map[string]*Transaction{}, - } -} - -// Insert inserts a transaction to the map -func (m *TransactionMap) Insert(key string, tr *Transaction) bool { - m.mutex.Lock() - defer m.mutex.Unlock() - - m.trMap[key] = tr - return true -} - -// Find looks up a transaction by its key -func (m *TransactionMap) Find(key string) (*Transaction, bool) { - m.mutex.RLock() - defer m.mutex.RUnlock() - - tr, ok := m.trMap[key] - return tr, ok -} - -// Delete deletes a transaction by its key -func (m *TransactionMap) Delete(key string) { - m.mutex.Lock() - defer m.mutex.Unlock() - - delete(m.trMap, key) -} - -// CloseAndDeleteAll closes and deletes all transactions -func (m *TransactionMap) CloseAndDeleteAll() { - m.mutex.Lock() - defer m.mutex.Unlock() - - for trKey, tr := range m.trMap { - tr.Close() - delete(m.trMap, trKey) - } -} - -// Size returns the length of the transaction map -func (m *TransactionMap) Size() int { - m.mutex.RLock() - defer m.mutex.RUnlock() - - return len(m.trMap) -} diff --git a/vendor/github.com/pion/turn/v2/internal/client/trylock.go b/vendor/github.com/pion/turn/v2/internal/client/trylock.go deleted file mode 100644 index 2d11a2d3..00000000 --- a/vendor/github.com/pion/turn/v2/internal/client/trylock.go +++ /dev/null @@ -1,24 +0,0 @@ -package client - -import ( - "sync/atomic" -) - -// TryLock implement the classic "try-lock" operation. -type TryLock struct { - n int32 -} - -// Lock tries to lock the try-lock. If successful, it returns true. -// Otherwise, it returns false immediately. -func (c *TryLock) Lock() error { - if !atomic.CompareAndSwapInt32(&c.n, 0, 1) { - return errDoubleLock - } - return nil -} - -// Unlock unlocks the try-lock. -func (c *TryLock) Unlock() { - atomic.StoreInt32(&c.n, 0) -} diff --git a/vendor/github.com/pion/turn/v2/internal/ipnet/util.go b/vendor/github.com/pion/turn/v2/internal/ipnet/util.go deleted file mode 100644 index 24256b0a..00000000 --- a/vendor/github.com/pion/turn/v2/internal/ipnet/util.go +++ /dev/null @@ -1,40 +0,0 @@ -// Package ipnet contains helper functions around net and IP -package ipnet - -import ( - "errors" - "net" -) - -var errFailedToCastAddr = errors.New("failed to cast net.Addr to *net.UDPAddr or *net.TCPAddr") - -// AddrIPPort extracts the IP and Port from a net.Addr -func AddrIPPort(a net.Addr) (net.IP, int, error) { - aUDP, ok := a.(*net.UDPAddr) - if ok { - return aUDP.IP, aUDP.Port, nil - } - - aTCP, ok := a.(*net.TCPAddr) - if ok { - return aTCP.IP, aTCP.Port, nil - } - - return nil, 0, errFailedToCastAddr -} - -// AddrEqual asserts that two net.Addrs are equal -// Currently only supports UDP but will be extended in the future to support others -func AddrEqual(a, b net.Addr) bool { - aUDP, ok := a.(*net.UDPAddr) - if !ok { - return false - } - - bUDP, ok := b.(*net.UDPAddr) - if !ok { - return false - } - - return aUDP.IP.Equal(bUDP.IP) && aUDP.Port == bUDP.Port -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/addr.go b/vendor/github.com/pion/turn/v2/internal/proto/addr.go deleted file mode 100644 index b1d654d9..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/addr.go +++ /dev/null @@ -1,65 +0,0 @@ -package proto - -import ( - "fmt" - "net" -) - -// Addr is ip:port. -type Addr struct { - IP net.IP - Port int -} - -// Network implements net.Addr. -func (Addr) Network() string { return "turn" } - -// FromUDPAddr sets addr to UDPAddr. -func (a *Addr) FromUDPAddr(n *net.UDPAddr) { - a.IP = n.IP - a.Port = n.Port -} - -// Equal returns true if b == a. -func (a Addr) Equal(b Addr) bool { - if a.Port != b.Port { - return false - } - return a.IP.Equal(b.IP) -} - -// EqualIP returns true if a and b have equal IP addresses. -func (a Addr) EqualIP(b Addr) bool { - return a.IP.Equal(b.IP) -} - -func (a Addr) String() string { - return fmt.Sprintf("%s:%d", a.IP, a.Port) -} - -// FiveTuple represents 5-TUPLE value. -type FiveTuple struct { - Client Addr - Server Addr - Proto Protocol -} - -func (t FiveTuple) String() string { - return fmt.Sprintf("%s->%s (%s)", - t.Client, t.Server, t.Proto, - ) -} - -// Equal returns true if b == t. -func (t FiveTuple) Equal(b FiveTuple) bool { - if t.Proto != b.Proto { - return false - } - if !t.Client.Equal(b.Client) { - return false - } - if !t.Server.Equal(b.Server) { - return false - } - return true -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/chandata.go b/vendor/github.com/pion/turn/v2/internal/proto/chandata.go deleted file mode 100644 index 6f023e08..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/chandata.go +++ /dev/null @@ -1,140 +0,0 @@ -package proto - -import ( - "bytes" - "encoding/binary" - "errors" - "io" -) - -// ChannelData represents The ChannelData Message. -// -// See RFC 5766 Section 11.4 -type ChannelData struct { - Data []byte // can be sub slice of Raw - Length int // ignored while encoding, len(Data) is used - Number ChannelNumber - Raw []byte -} - -// Equal returns true if b == c. -func (c *ChannelData) Equal(b *ChannelData) bool { - if c == nil && b == nil { - return true - } - if c == nil || b == nil { - return false - } - if c.Number != b.Number { - return false - } - if len(c.Data) != len(b.Data) { - return false - } - return bytes.Equal(c.Data, b.Data) -} - -// grow ensures that internal buffer will fit v more bytes and -// increases it capacity if necessary. -// -// Similar to stun.Message.grow method. -func (c *ChannelData) grow(v int) { - n := len(c.Raw) + v - for cap(c.Raw) < n { - c.Raw = append(c.Raw, 0) - } - c.Raw = c.Raw[:n] -} - -// Reset resets Length, Data and Raw length. -func (c *ChannelData) Reset() { - c.Raw = c.Raw[:0] - c.Length = 0 - c.Data = c.Data[:0] -} - -// Encode encodes ChannelData Message to Raw. -func (c *ChannelData) Encode() { - c.Raw = c.Raw[:0] - c.WriteHeader() - c.Raw = append(c.Raw, c.Data...) - padded := nearestPaddedValueLength(len(c.Raw)) - if bytesToAdd := padded - len(c.Raw); bytesToAdd > 0 { - for i := 0; i < bytesToAdd; i++ { - c.Raw = append(c.Raw, 0) - } - } -} - -const padding = 4 - -func nearestPaddedValueLength(l int) int { - n := padding * (l / padding) - if n < l { - n += padding - } - return n -} - -// WriteHeader writes channel number and length. -func (c *ChannelData) WriteHeader() { - if len(c.Raw) < channelDataHeaderSize { - // Making WriteHeader call valid even when c.Raw - // is nil or len(c.Raw) is less than needed for header. - c.grow(channelDataHeaderSize) - } - // Early bounds check to guarantee safety of writes below. - _ = c.Raw[:channelDataHeaderSize] - binary.BigEndian.PutUint16(c.Raw[:channelDataNumberSize], uint16(c.Number)) - binary.BigEndian.PutUint16(c.Raw[channelDataNumberSize:channelDataHeaderSize], - uint16(len(c.Data)), - ) -} - -// ErrBadChannelDataLength means that channel data length is not equal -// to actual data length. -var ErrBadChannelDataLength = errors.New("channelData length != len(Data)") - -// Decode decodes The ChannelData Message from Raw. -func (c *ChannelData) Decode() error { - buf := c.Raw - if len(buf) < channelDataHeaderSize { - return io.ErrUnexpectedEOF - } - num := binary.BigEndian.Uint16(buf[:channelDataNumberSize]) - c.Number = ChannelNumber(num) - l := binary.BigEndian.Uint16(buf[channelDataNumberSize:channelDataHeaderSize]) - c.Data = buf[channelDataHeaderSize:] - c.Length = int(l) - if !c.Number.Valid() { - return ErrInvalidChannelNumber - } - if int(l) < len(c.Data) { - c.Data = c.Data[:int(l)] - } - if int(l) > len(buf[channelDataHeaderSize:]) { - return ErrBadChannelDataLength - } - return nil -} - -const ( - channelDataLengthSize = 2 - channelDataNumberSize = channelDataLengthSize - channelDataHeaderSize = channelDataLengthSize + channelDataNumberSize -) - -// IsChannelData returns true if buf looks like the ChannelData Message. -func IsChannelData(buf []byte) bool { - if len(buf) < channelDataHeaderSize { - return false - } - - if int(binary.BigEndian.Uint16(buf[channelDataNumberSize:channelDataHeaderSize])) > len(buf[channelDataHeaderSize:]) { - return false - } - - // Quick check for channel number. - num := binary.BigEndian.Uint16(buf[0:channelNumberSize]) - return isChannelNumberValid(num) -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/chann.go b/vendor/github.com/pion/turn/v2/internal/proto/chann.go deleted file mode 100644 index d64ef73f..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/chann.go +++ /dev/null @@ -1,67 +0,0 @@ -package proto - -import ( - "encoding/binary" - "errors" - "strconv" - - "github.com/pion/stun" -) - -// ChannelNumber represents CHANNEL-NUMBER attribute. -// -// The CHANNEL-NUMBER attribute contains the number of the channel. -// -// RFC 5766 Section 14.1 -type ChannelNumber uint16 // encoded as uint16 - -func (n ChannelNumber) String() string { return strconv.Itoa(int(n)) } - -// 16 bits of uint + 16 bits of RFFU = 0. -const channelNumberSize = 4 - -// AddTo adds CHANNEL-NUMBER to message. -func (n ChannelNumber) AddTo(m *stun.Message) error { - v := make([]byte, channelNumberSize) - binary.BigEndian.PutUint16(v[:2], uint16(n)) - // v[2:4] are zeroes (RFFU = 0) - m.Add(stun.AttrChannelNumber, v) - return nil -} - -// GetFrom decodes CHANNEL-NUMBER from message. -func (n *ChannelNumber) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrChannelNumber) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrChannelNumber, len(v), channelNumberSize); err != nil { - return err - } - _ = v[channelNumberSize-1] // asserting length - *n = ChannelNumber(binary.BigEndian.Uint16(v[:2])) - // v[2:4] is RFFU and equals to 0. - return nil -} - -// See https://tools.ietf.org/html/rfc5766#section-11: -// -// 0x4000 through 0x7FFF: These values are the allowed channel -// numbers (16,383 possible values). -const ( - MinChannelNumber = 0x4000 - MaxChannelNumber = 0x7FFF -) - -// ErrInvalidChannelNumber means that channel number is not valid as by RFC 5766 Section 11. -var ErrInvalidChannelNumber = errors.New("channel number not in [0x4000, 0x7FFF]") - -// isChannelNumberValid returns true if c in [0x4000, 0x7FFF]. -func isChannelNumberValid(c uint16) bool { - return c >= MinChannelNumber && c <= MaxChannelNumber -} - -// Valid returns true if channel number has correct value that complies RFC 5766 Section 11 range. -func (n ChannelNumber) Valid() bool { - return isChannelNumberValid(uint16(n)) -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/connection_id.go b/vendor/github.com/pion/turn/v2/internal/proto/connection_id.go deleted file mode 100644 index 4984b474..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/connection_id.go +++ /dev/null @@ -1,39 +0,0 @@ -package proto - -import ( - "encoding/binary" - - "github.com/pion/stun" -) - -// ConnectionID represents CONNECTION-ID attribute. -// -// The CONNECTION-ID attribute uniquely identifies a peer data -// connection. It is a 32-bit unsigned integral value. -// -// RFC 6062 Section 6.2.1 -type ConnectionID uint32 - -const connectionIDSize = 4 // uint32: 4 bytes, 32 bits - -// AddTo adds CONNECTION-ID to message. -func (c ConnectionID) AddTo(m *stun.Message) error { - v := make([]byte, lifetimeSize) - binary.BigEndian.PutUint32(v, uint32(c)) - m.Add(stun.AttrConnectionID, v) - return nil -} - -// GetFrom decodes CONNECTION-ID from message. -func (c *ConnectionID) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrConnectionID) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrConnectionID, len(v), connectionIDSize); err != nil { - return err - } - _ = v[connectionIDSize-1] // asserting length - *(*uint32)(c) = binary.BigEndian.Uint32(v) - return nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/data.go b/vendor/github.com/pion/turn/v2/internal/proto/data.go deleted file mode 100644 index 64243e0c..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/data.go +++ /dev/null @@ -1,30 +0,0 @@ -package proto - -import "github.com/pion/stun" - -// Data represents DATA attribute. -// -// The DATA attribute is present in all Send and Data indications. The -// value portion of this attribute is variable length and consists of -// the application data (that is, the data that would immediately follow -// the UDP header if the data was been sent directly between the client -// and the peer). -// -// RFC 5766 Section 14.4 -type Data []byte - -// AddTo adds DATA to message. -func (d Data) AddTo(m *stun.Message) error { - m.Add(stun.AttrData, d) - return nil -} - -// GetFrom decodes DATA from message. -func (d *Data) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrData) - if err != nil { - return err - } - *d = v - return nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/dontfrag.go b/vendor/github.com/pion/turn/v2/internal/proto/dontfrag.go deleted file mode 100644 index ac52b2b5..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/dontfrag.go +++ /dev/null @@ -1,45 +0,0 @@ -package proto - -import ( - "github.com/pion/stun" -) - -// DontFragmentAttr is a deprecated alias for DontFragment -// Deprecated: Please use DontFragment -type DontFragmentAttr = DontFragment - -// DontFragment represents DONT-FRAGMENT attribute. -// -// This attribute is used by the client to request that the server set -// the DF (Don't Fragment) bit in the IP header when relaying the -// application data onward to the peer. This attribute has no value -// part and thus the attribute length field is 0. -// -// RFC 5766 Section 14.8 -type DontFragment struct{} - -const dontFragmentSize = 0 - -// AddTo adds DONT-FRAGMENT attribute to message. -func (DontFragment) AddTo(m *stun.Message) error { - m.Add(stun.AttrDontFragment, nil) - return nil -} - -// GetFrom decodes DONT-FRAGMENT from message. -func (d *DontFragment) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrDontFragment) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrDontFragment, len(v), dontFragmentSize); err != nil { - return err - } - return nil -} - -// IsSet returns true if DONT-FRAGMENT attribute is set. -func (DontFragment) IsSet(m *stun.Message) bool { - _, err := m.Get(stun.AttrDontFragment) - return err == nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/evenport.go b/vendor/github.com/pion/turn/v2/internal/proto/evenport.go deleted file mode 100644 index a5a38825..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/evenport.go +++ /dev/null @@ -1,55 +0,0 @@ -package proto - -import "github.com/pion/stun" - -// EvenPort represents EVEN-PORT attribute. -// -// This attribute allows the client to request that the port in the -// relayed transport address be even, and (optionally) that the server -// reserve the next-higher port number. -// -// RFC 5766 Section 14.6 -type EvenPort struct { - // ReservePort means that the server is requested to reserve - // the next-higher port number (on the same IP address) - // for a subsequent allocation. - ReservePort bool -} - -func (p EvenPort) String() string { - if p.ReservePort { - return "reserve: true" - } - return "reserve: false" -} - -const ( - evenPortSize = 1 - firstBitSet = (1 << 8) - 1 // 0b100000000 -) - -// AddTo adds EVEN-PORT to message. -func (p EvenPort) AddTo(m *stun.Message) error { - v := make([]byte, evenPortSize) - if p.ReservePort { - // Set first bit to 1. - v[0] = firstBitSet - } - m.Add(stun.AttrEvenPort, v) - return nil -} - -// GetFrom decodes EVEN-PORT from message. -func (p *EvenPort) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrEvenPort) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrEvenPort, len(v), evenPortSize); err != nil { - return err - } - if v[0]&firstBitSet > 0 { - p.ReservePort = true - } - return nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/lifetime.go b/vendor/github.com/pion/turn/v2/internal/proto/lifetime.go deleted file mode 100644 index b7816966..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/lifetime.go +++ /dev/null @@ -1,52 +0,0 @@ -package proto - -import ( - "encoding/binary" - "time" - - "github.com/pion/stun" -) - -// DefaultLifetime in RFC 5766 is 10 minutes. -// -// RFC 5766 Section 2.2 -const DefaultLifetime = time.Minute * 10 - -// Lifetime represents LIFETIME attribute. -// -// The LIFETIME attribute represents the duration for which the server -// will maintain an allocation in the absence of a refresh. The value -// portion of this attribute is 4-bytes long and consists of a 32-bit -// unsigned integral value representing the number of seconds remaining -// until expiration. -// -// RFC 5766 Section 14.2 -type Lifetime struct { - time.Duration -} - -// uint32 seconds -const lifetimeSize = 4 // 4 bytes, 32 bits - -// AddTo adds LIFETIME to message. -func (l Lifetime) AddTo(m *stun.Message) error { - v := make([]byte, lifetimeSize) - binary.BigEndian.PutUint32(v, uint32(l.Seconds())) - m.Add(stun.AttrLifetime, v) - return nil -} - -// GetFrom decodes LIFETIME from message. -func (l *Lifetime) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrLifetime) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrLifetime, len(v), lifetimeSize); err != nil { - return err - } - _ = v[lifetimeSize-1] // asserting length - seconds := binary.BigEndian.Uint32(v) - l.Duration = time.Second * time.Duration(seconds) - return nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/peeraddr.go b/vendor/github.com/pion/turn/v2/internal/proto/peeraddr.go deleted file mode 100644 index b357b823..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/peeraddr.go +++ /dev/null @@ -1,42 +0,0 @@ -package proto - -import ( - "net" - - "github.com/pion/stun" -) - -// PeerAddress implements XOR-PEER-ADDRESS attribute. -// -// The XOR-PEER-ADDRESS specifies the address and port of the peer as -// seen from the TURN server. (For example, the peer's server-reflexive -// transport address if the peer is behind a NAT.) -// -// RFC 5766 Section 14.3 -type PeerAddress struct { - IP net.IP - Port int -} - -func (a PeerAddress) String() string { - return stun.XORMappedAddress(a).String() -} - -// AddTo adds XOR-PEER-ADDRESS to message. -func (a PeerAddress) AddTo(m *stun.Message) error { - return stun.XORMappedAddress(a).AddToAs(m, stun.AttrXORPeerAddress) -} - -// GetFrom decodes XOR-PEER-ADDRESS from message. -func (a *PeerAddress) GetFrom(m *stun.Message) error { - return (*stun.XORMappedAddress)(a).GetFromAs(m, stun.AttrXORPeerAddress) -} - -// XORPeerAddress implements XOR-PEER-ADDRESS attribute. -// -// The XOR-PEER-ADDRESS specifies the address and port of the peer as -// seen from the TURN server. (For example, the peer's server-reflexive -// transport address if the peer is behind a NAT.) -// -// RFC 5766 Section 14.3 -type XORPeerAddress = PeerAddress diff --git a/vendor/github.com/pion/turn/v2/internal/proto/proto.go b/vendor/github.com/pion/turn/v2/internal/proto/proto.go deleted file mode 100644 index 4b08c762..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/proto.go +++ /dev/null @@ -1,30 +0,0 @@ -// Package proto implements RFC 5766 Traversal Using Relays around NAT. -// -// Merged from gortc/turn v0.80. -package proto - -import ( - "github.com/pion/stun" -) - -// Default ports for TURN from RFC 5766 Section 4. -const ( - // DefaultPort for TURN is same as STUN. - DefaultPort = stun.DefaultPort - // DefaultTLSPort is for TURN over TLS and is same as STUN. - DefaultTLSPort = stun.DefaultTLSPort -) - -// CreatePermissionRequest is shorthand for create permission request type. -func CreatePermissionRequest() stun.MessageType { - return stun.NewType(stun.MethodCreatePermission, stun.ClassRequest) -} - -// AllocateRequest is shorthand for allocation request message type. -func AllocateRequest() stun.MessageType { return stun.NewType(stun.MethodAllocate, stun.ClassRequest) } - -// SendIndication is shorthand for send indication message type. -func SendIndication() stun.MessageType { return stun.NewType(stun.MethodSend, stun.ClassIndication) } - -// RefreshRequest is shorthand for refresh request message type. -func RefreshRequest() stun.MessageType { return stun.NewType(stun.MethodRefresh, stun.ClassRequest) } diff --git a/vendor/github.com/pion/turn/v2/internal/proto/relayedaddr.go b/vendor/github.com/pion/turn/v2/internal/proto/relayedaddr.go deleted file mode 100644 index 2169cb75..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/relayedaddr.go +++ /dev/null @@ -1,40 +0,0 @@ -package proto - -import ( - "net" - - "github.com/pion/stun" -) - -// RelayedAddress implements XOR-RELAYED-ADDRESS attribute. -// -// It specifies the address and port that the server allocated to the -// client. It is encoded in the same way as XOR-MAPPED-ADDRESS. -// -// RFC 5766 Section 14.5 -type RelayedAddress struct { - IP net.IP - Port int -} - -func (a RelayedAddress) String() string { - return stun.XORMappedAddress(a).String() -} - -// AddTo adds XOR-PEER-ADDRESS to message. -func (a RelayedAddress) AddTo(m *stun.Message) error { - return stun.XORMappedAddress(a).AddToAs(m, stun.AttrXORRelayedAddress) -} - -// GetFrom decodes XOR-PEER-ADDRESS from message. -func (a *RelayedAddress) GetFrom(m *stun.Message) error { - return (*stun.XORMappedAddress)(a).GetFromAs(m, stun.AttrXORRelayedAddress) -} - -// XORRelayedAddress implements XOR-RELAYED-ADDRESS attribute. -// -// It specifies the address and port that the server allocated to the -// client. It is encoded in the same way as XOR-MAPPED-ADDRESS. -// -// RFC 5766 Section 14.5 -type XORRelayedAddress = RelayedAddress diff --git a/vendor/github.com/pion/turn/v2/internal/proto/reqfamily.go b/vendor/github.com/pion/turn/v2/internal/proto/reqfamily.go deleted file mode 100644 index e83d6bba..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/reqfamily.go +++ /dev/null @@ -1,61 +0,0 @@ -package proto - -import ( - "errors" - - "github.com/pion/stun" -) - -// RequestedAddressFamily represents the REQUESTED-ADDRESS-FAMILY Attribute as -// defined in RFC 6156 Section 4.1.1. -type RequestedAddressFamily byte - -const requestedFamilySize = 4 - -var errInvalidRequestedFamilyValue = errors.New("invalid value for requested family attribute") - -// GetFrom decodes REQUESTED-ADDRESS-FAMILY from message. -func (f *RequestedAddressFamily) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrRequestedAddressFamily) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrRequestedAddressFamily, len(v), requestedFamilySize); err != nil { - return err - } - switch v[0] { - case byte(RequestedFamilyIPv4), byte(RequestedFamilyIPv6): - *f = RequestedAddressFamily(v[0]) - default: - return errInvalidRequestedFamilyValue - } - return nil -} - -func (f RequestedAddressFamily) String() string { - switch f { - case RequestedFamilyIPv4: - return "IPv4" - case RequestedFamilyIPv6: - return "IPv6" - default: - return "unknown" - } -} - -// AddTo adds REQUESTED-ADDRESS-FAMILY to message. -func (f RequestedAddressFamily) AddTo(m *stun.Message) error { - v := make([]byte, requestedFamilySize) - v[0] = byte(f) - // b[1:4] is RFFU = 0. - // The RFFU field MUST be set to zero on transmission and MUST be - // ignored on reception. It is reserved for future uses. - m.Add(stun.AttrRequestedAddressFamily, v) - return nil -} - -// Values for RequestedAddressFamily as defined in RFC 6156 Section 4.1.1. -const ( - RequestedFamilyIPv4 RequestedAddressFamily = 0x01 - RequestedFamilyIPv6 RequestedAddressFamily = 0x02 -) diff --git a/vendor/github.com/pion/turn/v2/internal/proto/reqtrans.go b/vendor/github.com/pion/turn/v2/internal/proto/reqtrans.go deleted file mode 100644 index cc73a471..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/reqtrans.go +++ /dev/null @@ -1,65 +0,0 @@ -package proto - -import ( - "strconv" - - "github.com/pion/stun" -) - -// Protocol is IANA assigned protocol number. -type Protocol byte - -const ( - // ProtoUDP is IANA assigned protocol number for UDP. - ProtoUDP Protocol = 17 -) - -func (p Protocol) String() string { - switch p { - case ProtoUDP: - return "UDP" - default: - return strconv.Itoa(int(p)) - } -} - -// RequestedTransport represents REQUESTED-TRANSPORT attribute. -// -// This attribute is used by the client to request a specific transport -// protocol for the allocated transport address. RFC 5766 only allows the use of -// code point 17 (User Datagram Protocol). -// -// RFC 5766 Section 14.7 -type RequestedTransport struct { - Protocol Protocol -} - -func (t RequestedTransport) String() string { - return "protocol: " + t.Protocol.String() -} - -const requestedTransportSize = 4 - -// AddTo adds REQUESTED-TRANSPORT to message. -func (t RequestedTransport) AddTo(m *stun.Message) error { - v := make([]byte, requestedTransportSize) - v[0] = byte(t.Protocol) - // b[1:4] is RFFU = 0. - // The RFFU field MUST be set to zero on transmission and MUST be - // ignored on reception. It is reserved for future uses. - m.Add(stun.AttrRequestedTransport, v) - return nil -} - -// GetFrom decodes REQUESTED-TRANSPORT from message. -func (t *RequestedTransport) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrRequestedTransport) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrRequestedTransport, len(v), requestedTransportSize); err != nil { - return err - } - t.Protocol = Protocol(v[0]) - return nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/proto/rsrvtoken.go b/vendor/github.com/pion/turn/v2/internal/proto/rsrvtoken.go deleted file mode 100644 index 6e2ed4d8..00000000 --- a/vendor/github.com/pion/turn/v2/internal/proto/rsrvtoken.go +++ /dev/null @@ -1,39 +0,0 @@ -package proto - -import "github.com/pion/stun" - -// ReservationToken represents RESERVATION-TOKEN attribute. -// -// The RESERVATION-TOKEN attribute contains a token that uniquely -// identifies a relayed transport address being held in reserve by the -// server. The server includes this attribute in a success response to -// tell the client about the token, and the client includes this -// attribute in a subsequent Allocate request to request the server use -// that relayed transport address for the allocation. -// -// RFC 5766 Section 14.9 -type ReservationToken []byte - -const reservationTokenSize = 8 // 8 bytes - -// AddTo adds RESERVATION-TOKEN to message. -func (t ReservationToken) AddTo(m *stun.Message) error { - if err := stun.CheckSize(stun.AttrReservationToken, len(t), reservationTokenSize); err != nil { - return err - } - m.Add(stun.AttrReservationToken, t) - return nil -} - -// GetFrom decodes RESERVATION-TOKEN from message. -func (t *ReservationToken) GetFrom(m *stun.Message) error { - v, err := m.Get(stun.AttrReservationToken) - if err != nil { - return err - } - if err = stun.CheckSize(stun.AttrReservationToken, len(v), reservationTokenSize); err != nil { - return err - } - *t = v - return nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/server/errors.go b/vendor/github.com/pion/turn/v2/internal/server/errors.go deleted file mode 100644 index 13f8ee1a..00000000 --- a/vendor/github.com/pion/turn/v2/internal/server/errors.go +++ /dev/null @@ -1,26 +0,0 @@ -package server - -import "errors" - -var ( - errFailedToGenerateNonce = errors.New("failed to generate nonce") - errFailedToSendError = errors.New("failed to send error message") - errDuplicatedNonce = errors.New("duplicated Nonce generated, discarding request") - errNoSuchUser = errors.New("no such user exists") - errUnexpectedClass = errors.New("unexpected class") - errUnexpectedMethod = errors.New("unexpected method") - errFailedToHandle = errors.New("failed to handle") - errUnhandledSTUNPacket = errors.New("unhandled STUN packet") - errUnableToHandleChannelData = errors.New("unable to handle ChannelData") - errFailedToCreateSTUNPacket = errors.New("failed to create stun message from packet") - errFailedToCreateChannelData = errors.New("failed to create channel data from packet") - errRelayAlreadyAllocatedForFiveTuple = errors.New("relay already allocated for 5-TUPLE") - errRequestedTransportMustBeUDP = errors.New("RequestedTransport must be UDP") - errNoDontFragmentSupport = errors.New("no support for DONT-FRAGMENT") - errRequestWithReservationTokenAndEvenPort = errors.New("Request must not contain RESERVATION-TOKEN and EVEN-PORT") - errNoAllocationFound = errors.New("no allocation found") - errNoPermission = errors.New("unable to handle send-indication, no permission added") - errShortWrite = errors.New("packet write smaller than packet") - errNoSuchChannelBind = errors.New("no such channel bind") - errFailedWriteSocket = errors.New("failed writing to socket") -) diff --git a/vendor/github.com/pion/turn/v2/internal/server/server.go b/vendor/github.com/pion/turn/v2/internal/server/server.go deleted file mode 100644 index 27f37583..00000000 --- a/vendor/github.com/pion/turn/v2/internal/server/server.go +++ /dev/null @@ -1,109 +0,0 @@ -// Package server implements the private API to implement a TURN server -package server - -import ( - "fmt" - "net" - "sync" - "time" - - "github.com/pion/logging" - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/allocation" - "github.com/pion/turn/v2/internal/proto" -) - -// Request contains all the state needed to process a single incoming datagram -type Request struct { - // Current Request State - Conn net.PacketConn - SrcAddr net.Addr - Buff []byte - - // Server State - AllocationManager *allocation.Manager - Nonces *sync.Map - - // User Configuration - AuthHandler func(username string, realm string, srcAddr net.Addr) (key []byte, ok bool) - Log logging.LeveledLogger - Realm string - ChannelBindTimeout time.Duration -} - -// HandleRequest processes the give Request -func HandleRequest(r Request) error { - r.Log.Debugf("received %d bytes of udp from %s on %s", len(r.Buff), r.SrcAddr.String(), r.Conn.LocalAddr().String()) - - if proto.IsChannelData(r.Buff) { - return handleDataPacket(r) - } - - return handleTURNPacket(r) -} - -func handleDataPacket(r Request) error { - r.Log.Debugf("received DataPacket from %s", r.SrcAddr.String()) - c := proto.ChannelData{Raw: r.Buff} - if err := c.Decode(); err != nil { - return fmt.Errorf("%w: %v", errFailedToCreateChannelData, err) - } - - err := handleChannelData(r, &c) - if err != nil { - err = fmt.Errorf("%w from %v: %v", errUnableToHandleChannelData, r.SrcAddr, err) - } - - return err -} - -func handleTURNPacket(r Request) error { - r.Log.Debug("handleTURNPacket") - m := &stun.Message{Raw: append([]byte{}, r.Buff...)} - if err := m.Decode(); err != nil { - return fmt.Errorf("%w: %v", errFailedToCreateSTUNPacket, err) - } - - h, err := getMessageHandler(m.Type.Class, m.Type.Method) - if err != nil { - return fmt.Errorf("%w %v-%v from %v: %v", errUnhandledSTUNPacket, m.Type.Method, m.Type.Class, r.SrcAddr, err) - } - - err = h(r, m) - if err != nil { - return fmt.Errorf("%w %v-%v from %v: %v", errFailedToHandle, m.Type.Method, m.Type.Class, r.SrcAddr, err) - } - - return nil -} - -func getMessageHandler(class stun.MessageClass, method stun.Method) (func(r Request, m *stun.Message) error, error) { - switch class { - case stun.ClassIndication: - switch method { - case stun.MethodSend: - return handleSendIndication, nil - default: - return nil, fmt.Errorf("%w: %s", errUnexpectedMethod, method) - } - - case stun.ClassRequest: - switch method { - case stun.MethodAllocate: - return handleAllocateRequest, nil - case stun.MethodRefresh: - return handleRefreshRequest, nil - case stun.MethodCreatePermission: - return handleCreatePermissionRequest, nil - case stun.MethodChannelBind: - return handleChannelBindRequest, nil - case stun.MethodBinding: - return handleBindingRequest, nil - default: - return nil, fmt.Errorf("%w: %s", errUnexpectedMethod, method) - } - - default: - return nil, fmt.Errorf("%w: %s", errUnexpectedClass, class) - } -} diff --git a/vendor/github.com/pion/turn/v2/internal/server/stun.go b/vendor/github.com/pion/turn/v2/internal/server/stun.go deleted file mode 100644 index 673e99f6..00000000 --- a/vendor/github.com/pion/turn/v2/internal/server/stun.go +++ /dev/null @@ -1,22 +0,0 @@ -package server - -import ( - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/ipnet" -) - -func handleBindingRequest(r Request, m *stun.Message) error { - r.Log.Debugf("received BindingRequest from %s", r.SrcAddr.String()) - - ip, port, err := ipnet.AddrIPPort(r.SrcAddr) - if err != nil { - return err - } - - attrs := buildMsg(m.TransactionID, stun.BindingSuccess, &stun.XORMappedAddress{ - IP: ip, - Port: port, - }, stun.Fingerprint) - - return buildAndSend(r.Conn, r.SrcAddr, attrs...) -} diff --git a/vendor/github.com/pion/turn/v2/internal/server/turn.go b/vendor/github.com/pion/turn/v2/internal/server/turn.go deleted file mode 100644 index 4e7d25db..00000000 --- a/vendor/github.com/pion/turn/v2/internal/server/turn.go +++ /dev/null @@ -1,376 +0,0 @@ -package server - -import ( - "fmt" - "net" - - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/allocation" - "github.com/pion/turn/v2/internal/ipnet" - "github.com/pion/turn/v2/internal/proto" -) - -// // https://tools.ietf.org/html/rfc5766#section-6.2 -func handleAllocateRequest(r Request, m *stun.Message) error { - r.Log.Debugf("received AllocateRequest from %s", r.SrcAddr.String()) - - // 1. The server MUST require that the request be authenticated. This - // authentication MUST be done using the long-term credential - // mechanism of [https://tools.ietf.org/html/rfc5389#section-10.2.2] - // unless the client and server agree to use another mechanism through - // some procedure outside the scope of this document. - messageIntegrity, hasAuth, err := authenticateRequest(r, m, stun.MethodAllocate) - if !hasAuth { - return err - } - - fiveTuple := &allocation.FiveTuple{ - SrcAddr: r.SrcAddr, - DstAddr: r.Conn.LocalAddr(), - Protocol: allocation.UDP, - } - requestedPort := 0 - reservationToken := "" - - badRequestMsg := buildMsg(m.TransactionID, stun.NewType(stun.MethodAllocate, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeBadRequest}) - insufficientCapacityMsg := buildMsg(m.TransactionID, stun.NewType(stun.MethodAllocate, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeInsufficientCapacity}) - - // 2. The server checks if the 5-tuple is currently in use by an - // existing allocation. If yes, the server rejects the request with - // a 437 (Allocation Mismatch) error. - if alloc := r.AllocationManager.GetAllocation(fiveTuple); alloc != nil { - id, attrs := alloc.GetResponseCache() - if id != m.TransactionID { - msg := buildMsg(m.TransactionID, stun.NewType(stun.MethodAllocate, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeAllocMismatch}) - return buildAndSendErr(r.Conn, r.SrcAddr, errRelayAlreadyAllocatedForFiveTuple, msg...) - } - // a retry allocation - msg := buildMsg(m.TransactionID, stun.NewType(stun.MethodAllocate, stun.ClassSuccessResponse), append(attrs, messageIntegrity)...) - return buildAndSend(r.Conn, r.SrcAddr, msg...) - } - - // 3. The server checks if the request contains a REQUESTED-TRANSPORT - // attribute. If the REQUESTED-TRANSPORT attribute is not included - // or is malformed, the server rejects the request with a 400 (Bad - // Request) error. Otherwise, if the attribute is included but - // specifies a protocol other that UDP, the server rejects the - // request with a 442 (Unsupported Transport Protocol) error. - var requestedTransport proto.RequestedTransport - if err = requestedTransport.GetFrom(m); err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } else if requestedTransport.Protocol != proto.ProtoUDP { - msg := buildMsg(m.TransactionID, stun.NewType(stun.MethodAllocate, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeUnsupportedTransProto}) - return buildAndSendErr(r.Conn, r.SrcAddr, errRequestedTransportMustBeUDP, msg...) - } - - // 4. The request may contain a DONT-FRAGMENT attribute. If it does, - // but the server does not support sending UDP datagrams with the DF - // bit set to 1 (see Section 12), then the server treats the DONT- - // FRAGMENT attribute in the Allocate request as an unknown - // comprehension-required attribute. - if m.Contains(stun.AttrDontFragment) { - msg := buildMsg(m.TransactionID, stun.NewType(stun.MethodAllocate, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeUnknownAttribute}, &stun.UnknownAttributes{stun.AttrDontFragment}) - return buildAndSendErr(r.Conn, r.SrcAddr, errNoDontFragmentSupport, msg...) - } - - // 5. The server checks if the request contains a RESERVATION-TOKEN - // attribute. If yes, and the request also contains an EVEN-PORT - // attribute, then the server rejects the request with a 400 (Bad - // Request) error. Otherwise, it checks to see if the token is - // valid (i.e., the token is in range and has not expired and the - // corresponding relayed transport address is still available). If - // the token is not valid for some reason, the server rejects the - // request with a 508 (Insufficient Capacity) error. - var reservationTokenAttr proto.ReservationToken - if err = reservationTokenAttr.GetFrom(m); err == nil { - var evenPort proto.EvenPort - if err = evenPort.GetFrom(m); err == nil { - return buildAndSendErr(r.Conn, r.SrcAddr, errRequestWithReservationTokenAndEvenPort, badRequestMsg...) - } - } - - // 6. The server checks if the request contains an EVEN-PORT attribute. - // If yes, then the server checks that it can satisfy the request - // (i.e., can allocate a relayed transport address as described - // below). If the server cannot satisfy the request, then the - // server rejects the request with a 508 (Insufficient Capacity) - // error. - var evenPort proto.EvenPort - if err = evenPort.GetFrom(m); err == nil { - var randomPort int - randomPort, err = r.AllocationManager.GetRandomEvenPort() - if err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, insufficientCapacityMsg...) - } - requestedPort = randomPort - reservationToken = randSeq(8) - } - - // 7. At any point, the server MAY choose to reject the request with a - // 486 (Allocation Quota Reached) error if it feels the client is - // trying to exceed some locally defined allocation quota. The - // server is free to define this allocation quota any way it wishes, - // but SHOULD define it based on the username used to authenticate - // the request, and not on the client's transport address. - - // 8. Also at any point, the server MAY choose to reject the request - // with a 300 (Try Alternate) error if it wishes to redirect the - // client to a different server. The use of this error code and - // attribute follow the specification in [RFC5389]. - lifetimeDuration := allocationLifeTime(m) - a, err := r.AllocationManager.CreateAllocation( - fiveTuple, - r.Conn, - requestedPort, - lifetimeDuration) - if err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, insufficientCapacityMsg...) - } - - // Once the allocation is created, the server replies with a success - // response. The success response contains: - // * An XOR-RELAYED-ADDRESS attribute containing the relayed transport - // address. - // * A LIFETIME attribute containing the current value of the time-to- - // expiry timer. - // * A RESERVATION-TOKEN attribute (if a second relayed transport - // address was reserved). - // * An XOR-MAPPED-ADDRESS attribute containing the client's IP address - // and port (from the 5-tuple). - - srcIP, srcPort, err := ipnet.AddrIPPort(r.SrcAddr) - if err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - relayIP, relayPort, err := ipnet.AddrIPPort(a.RelayAddr) - if err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - responseAttrs := []stun.Setter{ - &proto.RelayedAddress{ - IP: relayIP, - Port: relayPort, - }, - &proto.Lifetime{ - Duration: lifetimeDuration, - }, - &stun.XORMappedAddress{ - IP: srcIP, - Port: srcPort, - }, - } - - if reservationToken != "" { - r.AllocationManager.CreateReservation(reservationToken, relayPort) - responseAttrs = append(responseAttrs, proto.ReservationToken([]byte(reservationToken))) - } - - msg := buildMsg(m.TransactionID, stun.NewType(stun.MethodAllocate, stun.ClassSuccessResponse), append(responseAttrs, messageIntegrity)...) - a.SetResponseCache(m.TransactionID, responseAttrs) - return buildAndSend(r.Conn, r.SrcAddr, msg...) -} - -func handleRefreshRequest(r Request, m *stun.Message) error { - r.Log.Debugf("received RefreshRequest from %s", r.SrcAddr.String()) - - messageIntegrity, hasAuth, err := authenticateRequest(r, m, stun.MethodRefresh) - if !hasAuth { - return err - } - - lifetimeDuration := allocationLifeTime(m) - fiveTuple := &allocation.FiveTuple{ - SrcAddr: r.SrcAddr, - DstAddr: r.Conn.LocalAddr(), - Protocol: allocation.UDP, - } - - if lifetimeDuration != 0 { - a := r.AllocationManager.GetAllocation(fiveTuple) - - if a == nil { - return fmt.Errorf("%w %v:%v", errNoAllocationFound, r.SrcAddr, r.Conn.LocalAddr()) - } - a.Refresh(lifetimeDuration) - } else { - r.AllocationManager.DeleteAllocation(fiveTuple) - } - - return buildAndSend(r.Conn, r.SrcAddr, buildMsg(m.TransactionID, stun.NewType(stun.MethodRefresh, stun.ClassSuccessResponse), []stun.Setter{ - &proto.Lifetime{ - Duration: lifetimeDuration, - }, - messageIntegrity, - }...)...) -} - -func handleCreatePermissionRequest(r Request, m *stun.Message) error { - r.Log.Debugf("received CreatePermission from %s", r.SrcAddr.String()) - - a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{ - SrcAddr: r.SrcAddr, - DstAddr: r.Conn.LocalAddr(), - Protocol: allocation.UDP, - }) - if a == nil { - return fmt.Errorf("%w %v:%v", errNoAllocationFound, r.SrcAddr, r.Conn.LocalAddr()) - } - - messageIntegrity, hasAuth, err := authenticateRequest(r, m, stun.MethodCreatePermission) - if !hasAuth { - return err - } - - addCount := 0 - - if err := m.ForEach(stun.AttrXORPeerAddress, func(m *stun.Message) error { - var peerAddress proto.PeerAddress - if err := peerAddress.GetFrom(m); err != nil { - return err - } - - if err := r.AllocationManager.GrantPermission(r.SrcAddr, peerAddress.IP); err != nil { - r.Log.Infof("permission denied for client %s to peer %s", r.SrcAddr.String(), - peerAddress.IP.String()) - return err - } - - r.Log.Debugf("adding permission for %s", fmt.Sprintf("%s:%d", - peerAddress.IP.String(), peerAddress.Port)) - - a.AddPermission(allocation.NewPermission( - &net.UDPAddr{ - IP: peerAddress.IP, - Port: peerAddress.Port, - }, - r.Log, - )) - addCount++ - return nil - }); err != nil { - addCount = 0 - } - - respClass := stun.ClassSuccessResponse - if addCount == 0 { - respClass = stun.ClassErrorResponse - } - - return buildAndSend(r.Conn, r.SrcAddr, buildMsg(m.TransactionID, stun.NewType(stun.MethodCreatePermission, respClass), []stun.Setter{messageIntegrity}...)...) -} - -func handleSendIndication(r Request, m *stun.Message) error { - r.Log.Debugf("received SendIndication from %s", r.SrcAddr.String()) - a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{ - SrcAddr: r.SrcAddr, - DstAddr: r.Conn.LocalAddr(), - Protocol: allocation.UDP, - }) - if a == nil { - return fmt.Errorf("%w %v:%v", errNoAllocationFound, r.SrcAddr, r.Conn.LocalAddr()) - } - - dataAttr := proto.Data{} - if err := dataAttr.GetFrom(m); err != nil { - return err - } - - peerAddress := proto.PeerAddress{} - if err := peerAddress.GetFrom(m); err != nil { - return err - } - - msgDst := &net.UDPAddr{IP: peerAddress.IP, Port: peerAddress.Port} - if perm := a.GetPermission(msgDst); perm == nil { - return fmt.Errorf("%w: %v", errNoPermission, msgDst) - } - - l, err := a.RelaySocket.WriteTo(dataAttr, msgDst) - if l != len(dataAttr) { - return fmt.Errorf("%w %d != %d (expected) err: %v", errShortWrite, l, len(dataAttr), err) - } - return err -} - -func handleChannelBindRequest(r Request, m *stun.Message) error { - r.Log.Debugf("received ChannelBindRequest from %s", r.SrcAddr.String()) - - a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{ - SrcAddr: r.SrcAddr, - DstAddr: r.Conn.LocalAddr(), - Protocol: allocation.UDP, - }) - if a == nil { - return fmt.Errorf("%w %v:%v", errNoAllocationFound, r.SrcAddr, r.Conn.LocalAddr()) - } - - badRequestMsg := buildMsg(m.TransactionID, stun.NewType(stun.MethodChannelBind, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeBadRequest}) - - messageIntegrity, hasAuth, err := authenticateRequest(r, m, stun.MethodChannelBind) - if !hasAuth { - return err - } - - var channel proto.ChannelNumber - if err = channel.GetFrom(m); err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - peerAddr := proto.PeerAddress{} - if err = peerAddr.GetFrom(m); err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - if err = r.AllocationManager.GrantPermission(r.SrcAddr, peerAddr.IP); err != nil { - r.Log.Infof("permission denied for client %s to peer %s", r.SrcAddr.String(), - peerAddr.IP.String()) - - unauthorizedRequestMsg := buildMsg(m.TransactionID, - stun.NewType(stun.MethodChannelBind, stun.ClassErrorResponse), - &stun.ErrorCodeAttribute{Code: stun.CodeUnauthorized}) - return buildAndSendErr(r.Conn, r.SrcAddr, err, unauthorizedRequestMsg...) - } - - r.Log.Debugf("binding channel %d to %s", - channel, - fmt.Sprintf("%s:%d", peerAddr.IP.String(), peerAddr.Port)) - err = a.AddChannelBind(allocation.NewChannelBind( - channel, - &net.UDPAddr{IP: peerAddr.IP, Port: peerAddr.Port}, - r.Log, - ), r.ChannelBindTimeout) - if err != nil { - return buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - return buildAndSend(r.Conn, r.SrcAddr, buildMsg(m.TransactionID, stun.NewType(stun.MethodChannelBind, stun.ClassSuccessResponse), []stun.Setter{messageIntegrity}...)...) -} - -func handleChannelData(r Request, c *proto.ChannelData) error { - r.Log.Debugf("received ChannelData from %s", r.SrcAddr.String()) - - a := r.AllocationManager.GetAllocation(&allocation.FiveTuple{ - SrcAddr: r.SrcAddr, - DstAddr: r.Conn.LocalAddr(), - Protocol: allocation.UDP, - }) - if a == nil { - return fmt.Errorf("%w %v:%v", errNoAllocationFound, r.SrcAddr, r.Conn.LocalAddr()) - } - - channel := a.GetChannelByNumber(c.Number) - if channel == nil { - return fmt.Errorf("%w %x", errNoSuchChannelBind, uint16(c.Number)) - } - - l, err := a.RelaySocket.WriteTo(c.Data, channel.Peer) - if err != nil { - return fmt.Errorf("%w: %s", errFailedWriteSocket, err.Error()) - } else if l != len(c.Data) { - return fmt.Errorf("%w %d != %d (expected)", errShortWrite, l, len(c.Data)) - } - - return nil -} diff --git a/vendor/github.com/pion/turn/v2/internal/server/util.go b/vendor/github.com/pion/turn/v2/internal/server/util.go deleted file mode 100644 index c9a33921..00000000 --- a/vendor/github.com/pion/turn/v2/internal/server/util.go +++ /dev/null @@ -1,138 +0,0 @@ -package server - -import ( - "crypto/md5" //nolint:gosec,gci - "fmt" - "io" - "math/rand" - "net" - "strconv" - "time" - - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/proto" -) - -const ( - maximumAllocationLifetime = time.Hour // https://tools.ietf.org/html/rfc5766#section-6.2 defines 3600 seconds recommendation - nonceLifetime = time.Hour // https://tools.ietf.org/html/rfc5766#section-4 - -) - -func randSeq(n int) string { - letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - b := make([]rune, n) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] //nolint:gosec - } - return string(b) -} - -func buildNonce() (string, error) { - /* #nosec */ - h := md5.New() - if _, err := io.WriteString(h, strconv.FormatInt(time.Now().Unix(), 10)); err != nil { - return "", fmt.Errorf("%w: %v", errFailedToGenerateNonce, err) - } - if _, err := io.WriteString(h, strconv.FormatInt(rand.Int63(), 10)); err != nil { //nolint:gosec - return "", fmt.Errorf("%w: %v", errFailedToGenerateNonce, err) - } - return fmt.Sprintf("%x", h.Sum(nil)), nil -} - -func buildAndSend(conn net.PacketConn, dst net.Addr, attrs ...stun.Setter) error { - msg, err := stun.Build(attrs...) - if err != nil { - return err - } - _, err = conn.WriteTo(msg.Raw, dst) - return err -} - -// Send a STUN packet and return the original error to the caller -func buildAndSendErr(conn net.PacketConn, dst net.Addr, err error, attrs ...stun.Setter) error { - if sendErr := buildAndSend(conn, dst, attrs...); sendErr != nil { - err = fmt.Errorf("%w %v %v", errFailedToSendError, sendErr, err) - } - return err -} - -func buildMsg(transactionID [stun.TransactionIDSize]byte, msgType stun.MessageType, additional ...stun.Setter) []stun.Setter { - return append([]stun.Setter{&stun.Message{TransactionID: transactionID}, msgType}, additional...) -} - -func authenticateRequest(r Request, m *stun.Message, callingMethod stun.Method) (stun.MessageIntegrity, bool, error) { - respondWithNonce := func(responseCode stun.ErrorCode) (stun.MessageIntegrity, bool, error) { - nonce, err := buildNonce() - if err != nil { - return nil, false, err - } - - // Nonce has already been taken - if _, keyCollision := r.Nonces.LoadOrStore(nonce, time.Now()); keyCollision { - return nil, false, errDuplicatedNonce - } - - return nil, false, buildAndSend(r.Conn, r.SrcAddr, buildMsg(m.TransactionID, - stun.NewType(callingMethod, stun.ClassErrorResponse), - &stun.ErrorCodeAttribute{Code: responseCode}, - stun.NewNonce(nonce), - stun.NewRealm(r.Realm), - )...) - } - - if !m.Contains(stun.AttrMessageIntegrity) { - return respondWithNonce(stun.CodeUnauthorized) - } - - nonceAttr := &stun.Nonce{} - usernameAttr := &stun.Username{} - realmAttr := &stun.Realm{} - badRequestMsg := buildMsg(m.TransactionID, stun.NewType(callingMethod, stun.ClassErrorResponse), &stun.ErrorCodeAttribute{Code: stun.CodeBadRequest}) - - if err := nonceAttr.GetFrom(m); err != nil { - return nil, false, buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - // Assert Nonce exists and is not expired - nonceCreationTime, nonceFound := r.Nonces.Load(string(*nonceAttr)) - if !nonceFound { - r.Nonces.Delete(nonceAttr) - return respondWithNonce(stun.CodeStaleNonce) - } - - if timeValue, ok := nonceCreationTime.(time.Time); !ok || time.Since(timeValue) >= nonceLifetime { - r.Nonces.Delete(nonceAttr) - return respondWithNonce(stun.CodeStaleNonce) - } - - if err := realmAttr.GetFrom(m); err != nil { - return nil, false, buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } else if err := usernameAttr.GetFrom(m); err != nil { - return nil, false, buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - ourKey, ok := r.AuthHandler(usernameAttr.String(), realmAttr.String(), r.SrcAddr) - if !ok { - return nil, false, buildAndSendErr(r.Conn, r.SrcAddr, fmt.Errorf("%w %s", errNoSuchUser, usernameAttr.String()), badRequestMsg...) - } - - if err := stun.MessageIntegrity(ourKey).Check(m); err != nil { - return nil, false, buildAndSendErr(r.Conn, r.SrcAddr, err, badRequestMsg...) - } - - return stun.MessageIntegrity(ourKey), true, nil -} - -func allocationLifeTime(m *stun.Message) time.Duration { - lifetimeDuration := proto.DefaultLifetime - - var lifetime proto.Lifetime - if err := lifetime.GetFrom(m); err == nil { - if lifetime.Duration < maximumAllocationLifetime { - lifetimeDuration = lifetime.Duration - } - } - - return lifetimeDuration -} diff --git a/vendor/github.com/pion/turn/v2/lt_cred.go b/vendor/github.com/pion/turn/v2/lt_cred.go deleted file mode 100644 index d4e9ab56..00000000 --- a/vendor/github.com/pion/turn/v2/lt_cred.go +++ /dev/null @@ -1,56 +0,0 @@ -package turn - -import ( //nolint:gci - "crypto/hmac" - "crypto/sha1" //nolint:gosec,gci - "encoding/base64" - "net" - "strconv" - "time" - - "github.com/pion/logging" -) - -// GenerateLongTermCredentials can be used to create credentials valid for [duration] time -func GenerateLongTermCredentials(sharedSecret string, duration time.Duration) (string, string, error) { - t := time.Now().Add(duration).Unix() - username := strconv.FormatInt(t, 10) - password, err := longTermCredentials(username, sharedSecret) - return username, password, err -} - -func longTermCredentials(username string, sharedSecret string) (string, error) { - mac := hmac.New(sha1.New, []byte(sharedSecret)) - _, err := mac.Write([]byte(username)) - if err != nil { - return "", err // Not sure if this will ever happen - } - password := mac.Sum(nil) - return base64.StdEncoding.EncodeToString(password), nil -} - -// NewLongTermAuthHandler returns a turn.AuthAuthHandler used with Long Term (or Time Windowed) Credentials. -// https://tools.ietf.org/search/rfc5389#section-10.2 -func NewLongTermAuthHandler(sharedSecret string, l logging.LeveledLogger) AuthHandler { - if l == nil { - l = logging.NewDefaultLoggerFactory().NewLogger("turn") - } - return func(username, realm string, srcAddr net.Addr) (key []byte, ok bool) { - l.Tracef("Authentication username=%q realm=%q srcAddr=%v", username, realm, srcAddr) - t, err := strconv.Atoi(username) - if err != nil { - l.Errorf("Invalid time-windowed username %q", username) - return nil, false - } - if int64(t) < time.Now().Unix() { - l.Errorf("Expired time-windowed username %q", username) - return nil, false - } - password, err := longTermCredentials(username, sharedSecret) - if err != nil { - l.Error(err.Error()) - return nil, false - } - return GenerateAuthKey(username, realm, password), true - } -} diff --git a/vendor/github.com/pion/turn/v2/relay_address_generator_none.go b/vendor/github.com/pion/turn/v2/relay_address_generator_none.go deleted file mode 100644 index f453d099..00000000 --- a/vendor/github.com/pion/turn/v2/relay_address_generator_none.go +++ /dev/null @@ -1,51 +0,0 @@ -package turn - -import ( - "fmt" - "net" - "strconv" - - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" -) - -// RelayAddressGeneratorNone returns the listener with no modifications -type RelayAddressGeneratorNone struct { - // Address is passed to Listen/ListenPacket when creating the Relay - Address string - - Net transport.Net -} - -// Validate is called on server startup and confirms the RelayAddressGenerator is properly configured -func (r *RelayAddressGeneratorNone) Validate() error { - if r.Net == nil { - var err error - r.Net, err = stdnet.NewNet() - if err != nil { - return fmt.Errorf("failed to create network: %w", err) - } - } - - switch { - case r.Address == "": - return errListeningAddressInvalid - default: - return nil - } -} - -// AllocatePacketConn generates a new PacketConn to receive traffic on and the IP/Port to populate the allocation response with -func (r *RelayAddressGeneratorNone) AllocatePacketConn(network string, requestedPort int) (net.PacketConn, net.Addr, error) { - conn, err := r.Net.ListenPacket(network, r.Address+":"+strconv.Itoa(requestedPort)) - if err != nil { - return nil, nil, err - } - - return conn, conn.LocalAddr(), nil -} - -// AllocateConn generates a new Conn to receive traffic on and the IP/Port to populate the allocation response with -func (r *RelayAddressGeneratorNone) AllocateConn(network string, requestedPort int) (net.Conn, net.Addr, error) { - return nil, nil, errTODO -} diff --git a/vendor/github.com/pion/turn/v2/relay_address_generator_range.go b/vendor/github.com/pion/turn/v2/relay_address_generator_range.go deleted file mode 100644 index 48a0f2bb..00000000 --- a/vendor/github.com/pion/turn/v2/relay_address_generator_range.go +++ /dev/null @@ -1,105 +0,0 @@ -package turn - -import ( - "fmt" - "net" - - "github.com/pion/randutil" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" -) - -// RelayAddressGeneratorPortRange can be used to only allocate connections inside a defined port range. -// Similar to the RelayAddressGeneratorStatic a static ip address can be set. -type RelayAddressGeneratorPortRange struct { - // RelayAddress is the IP returned to the user when the relay is created - RelayAddress net.IP - - // MinPort the minimum port to allocate - MinPort uint16 - // MaxPort the maximum (inclusive) port to allocate - MaxPort uint16 - - // MaxRetries the amount of tries to allocate a random port in the defined range - MaxRetries int - - // Rand the random source of numbers - Rand randutil.MathRandomGenerator - - // Address is passed to Listen/ListenPacket when creating the Relay - Address string - - Net transport.Net -} - -// Validate is called on server startup and confirms the RelayAddressGenerator is properly configured -func (r *RelayAddressGeneratorPortRange) Validate() error { - if r.Net == nil { - var err error - r.Net, err = stdnet.NewNet() - if err != nil { - return fmt.Errorf("failed to create network: %w", err) - } - } - - if r.Rand == nil { - r.Rand = randutil.NewMathRandomGenerator() - } - - if r.MaxRetries == 0 { - r.MaxRetries = 10 - } - - switch { - case r.MinPort == 0: - return errMinPortNotZero - case r.MaxPort == 0: - return errMaxPortNotZero - case r.RelayAddress == nil: - return errRelayAddressInvalid - case r.Address == "": - return errListeningAddressInvalid - default: - return nil - } -} - -// AllocatePacketConn generates a new PacketConn to receive traffic on and the IP/Port to populate the allocation response with -func (r *RelayAddressGeneratorPortRange) AllocatePacketConn(network string, requestedPort int) (net.PacketConn, net.Addr, error) { - if requestedPort != 0 { - conn, err := r.Net.ListenPacket(network, fmt.Sprintf("%s:%d", r.Address, requestedPort)) - if err != nil { - return nil, nil, err - } - relayAddr, ok := conn.LocalAddr().(*net.UDPAddr) - if !ok { - return nil, nil, errNilConn - } - - relayAddr.IP = r.RelayAddress - return conn, relayAddr, nil - } - - for try := 0; try < r.MaxRetries; try++ { - port := r.MinPort + uint16(r.Rand.Intn(int((r.MaxPort+1)-r.MinPort))) - conn, err := r.Net.ListenPacket(network, fmt.Sprintf("%s:%d", r.Address, port)) - if err != nil { - continue - } - - relayAddr, ok := conn.LocalAddr().(*net.UDPAddr) - if !ok { - return nil, nil, errNilConn - } - - relayAddr.IP = r.RelayAddress - return conn, relayAddr, nil - } - - return nil, nil, errMaxRetriesExceeded -} - -// AllocateConn generates a new Conn to receive traffic on and the IP/Port to populate the allocation response with -func (r *RelayAddressGeneratorPortRange) AllocateConn(network string, requestedPort int) (net.Conn, net.Addr, error) { - return nil, nil, errTODO -} diff --git a/vendor/github.com/pion/turn/v2/relay_address_generator_static.go b/vendor/github.com/pion/turn/v2/relay_address_generator_static.go deleted file mode 100644 index ba2be9fd..00000000 --- a/vendor/github.com/pion/turn/v2/relay_address_generator_static.go +++ /dev/null @@ -1,65 +0,0 @@ -package turn - -import ( - "fmt" - "net" - "strconv" - - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/stdnet" -) - -// RelayAddressGeneratorStatic can be used to return static IP address each time a relay is created. -// This can be used when you have a single static IP address that you want to use -type RelayAddressGeneratorStatic struct { - // RelayAddress is the IP returned to the user when the relay is created - RelayAddress net.IP - - // Address is passed to Listen/ListenPacket when creating the Relay - Address string - - Net transport.Net -} - -// Validate is called on server startup and confirms the RelayAddressGenerator is properly configured -func (r *RelayAddressGeneratorStatic) Validate() error { - if r.Net == nil { - var err error - r.Net, err = stdnet.NewNet() - if err != nil { - return fmt.Errorf("failed to create network: %w", err) - } - } - - switch { - case r.RelayAddress == nil: - return errRelayAddressInvalid - case r.Address == "": - return errListeningAddressInvalid - default: - return nil - } -} - -// AllocatePacketConn generates a new PacketConn to receive traffic on and the IP/Port to populate the allocation response with -func (r *RelayAddressGeneratorStatic) AllocatePacketConn(network string, requestedPort int) (net.PacketConn, net.Addr, error) { - conn, err := r.Net.ListenPacket(network, r.Address+":"+strconv.Itoa(requestedPort)) - if err != nil { - return nil, nil, err - } - - // Replace actual listening IP with the user requested one of RelayAddressGeneratorStatic - relayAddr, ok := conn.LocalAddr().(*net.UDPAddr) - if !ok { - return nil, nil, errNilConn - } - - relayAddr.IP = r.RelayAddress - - return conn, relayAddr, nil -} - -// AllocateConn generates a new Conn to receive traffic on and the IP/Port to populate the allocation response with -func (r *RelayAddressGeneratorStatic) AllocateConn(network string, requestedPort int) (net.Conn, net.Addr, error) { - return nil, nil, errTODO -} diff --git a/vendor/github.com/pion/turn/v2/renovate.json b/vendor/github.com/pion/turn/v2/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/turn/v2/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/turn/v2/server.go b/vendor/github.com/pion/turn/v2/server.go deleted file mode 100644 index 3f57f9db..00000000 --- a/vendor/github.com/pion/turn/v2/server.go +++ /dev/null @@ -1,197 +0,0 @@ -// Package turn contains the public API for pion/turn, a toolkit for building TURN clients and servers -package turn - -import ( - "fmt" - "net" - "sync" - "time" - - "github.com/pion/logging" - "github.com/pion/turn/v2/internal/allocation" - "github.com/pion/turn/v2/internal/proto" - "github.com/pion/turn/v2/internal/server" -) - -const ( - defaultInboundMTU = 1600 -) - -// Server is an instance of the Pion TURN Server -type Server struct { - log logging.LeveledLogger - authHandler AuthHandler - realm string - channelBindTimeout time.Duration - nonces *sync.Map - - packetConnConfigs []PacketConnConfig - listenerConfigs []ListenerConfig - allocationManagers []*allocation.Manager - inboundMTU int -} - -// NewServer creates the Pion TURN server -// -//nolint:gocognit -func NewServer(config ServerConfig) (*Server, error) { - if err := config.validate(); err != nil { - return nil, err - } - - loggerFactory := config.LoggerFactory - if loggerFactory == nil { - loggerFactory = logging.NewDefaultLoggerFactory() - } - - mtu := defaultInboundMTU - if config.InboundMTU != 0 { - mtu = config.InboundMTU - } - - s := &Server{ - log: loggerFactory.NewLogger("turn"), - authHandler: config.AuthHandler, - realm: config.Realm, - channelBindTimeout: config.ChannelBindTimeout, - packetConnConfigs: config.PacketConnConfigs, - listenerConfigs: config.ListenerConfigs, - nonces: &sync.Map{}, - inboundMTU: mtu, - } - - if s.channelBindTimeout == 0 { - s.channelBindTimeout = proto.DefaultLifetime - } - - for _, cfg := range s.packetConnConfigs { - am, err := s.createAllocationManager(cfg.RelayAddressGenerator, cfg.PermissionHandler) - if err != nil { - return nil, fmt.Errorf("failed to create AllocationManager: %w", err) - } - - go s.readPacketConn(cfg, am) - } - - for _, cfg := range s.listenerConfigs { - am, err := s.createAllocationManager(cfg.RelayAddressGenerator, cfg.PermissionHandler) - if err != nil { - return nil, fmt.Errorf("failed to create AllocationManager: %w", err) - } - - go s.readListener(cfg, am) - } - - return s, nil -} - -// AllocationCount returns the number of active allocations. It can be used to drain the server before closing -func (s *Server) AllocationCount() int { - allocs := 0 - for _, am := range s.allocationManagers { - allocs += am.AllocationCount() - } - return allocs -} - -// Close stops the TURN Server. It cleans up any associated state and closes all connections it is managing -func (s *Server) Close() error { - var errors []error - - for _, cfg := range s.packetConnConfigs { - if err := cfg.PacketConn.Close(); err != nil { - errors = append(errors, err) - } - } - - for _, cfg := range s.listenerConfigs { - if err := cfg.Listener.Close(); err != nil { - errors = append(errors, err) - } - } - - if len(errors) == 0 { - return nil - } - - err := errFailedToClose - for _, e := range errors { - err = fmt.Errorf("%s; close error (%w) ", err, e) - } - - return err -} - -func (s *Server) readPacketConn(p PacketConnConfig, am *allocation.Manager) { - s.readLoop(p.PacketConn, am) - - if err := am.Close(); err != nil { - s.log.Errorf("Failed to close AllocationManager: %s", err) - } -} - -func (s *Server) readListener(l ListenerConfig, am *allocation.Manager) { - defer func() { - if err := am.Close(); err != nil { - s.log.Errorf("Failed to close AllocationManager: %s", err) - } - }() - - for { - conn, err := l.Listener.Accept() - if err != nil { - s.log.Debugf("Failed to accept: %s", err) - return - } - - go s.readLoop(NewSTUNConn(conn), am) - } -} - -func (s *Server) createAllocationManager(addrGenerator RelayAddressGenerator, handler PermissionHandler) (*allocation.Manager, error) { - if handler == nil { - handler = DefaultPermissionHandler - } - - am, err := allocation.NewManager(allocation.ManagerConfig{ - AllocatePacketConn: addrGenerator.AllocatePacketConn, - AllocateConn: addrGenerator.AllocateConn, - PermissionHandler: handler, - LeveledLogger: s.log, - }) - if err != nil { - return am, err - } - - s.allocationManagers = append(s.allocationManagers, am) - - return am, err -} - -func (s *Server) readLoop(p net.PacketConn, allocationManager *allocation.Manager) { - buf := make([]byte, s.inboundMTU) - for { - n, addr, err := p.ReadFrom(buf) - switch { - case err != nil: - s.log.Debugf("exit read loop on error: %s", err.Error()) - return - case n >= s.inboundMTU: - s.log.Debugf("Read bytes exceeded MTU, packet is possibly truncated") - } - - if err := server.HandleRequest(server.Request{ - Conn: p, - SrcAddr: addr, - Buff: buf[:n], - Log: s.log, - AuthHandler: s.authHandler, - Realm: s.realm, - AllocationManager: allocationManager, - ChannelBindTimeout: s.channelBindTimeout, - Nonces: s.nonces, - }); err != nil { - s.log.Errorf("error when handling datagram: %v", err) - } - } -} diff --git a/vendor/github.com/pion/turn/v2/server_config.go b/vendor/github.com/pion/turn/v2/server_config.go deleted file mode 100644 index 5487900d..00000000 --- a/vendor/github.com/pion/turn/v2/server_config.go +++ /dev/null @@ -1,142 +0,0 @@ -package turn - -import ( - "crypto/md5" //nolint:gosec,gci - "fmt" - "net" - "strings" - "time" - - "github.com/pion/logging" -) - -// RelayAddressGenerator is used to generate a RelayAddress when creating an allocation. -// You can use one of the provided ones or provide your own. -type RelayAddressGenerator interface { - // Validate confirms that the RelayAddressGenerator is properly initialized - Validate() error - - // Allocate a PacketConn (UDP) RelayAddress - AllocatePacketConn(network string, requestedPort int) (net.PacketConn, net.Addr, error) - - // Allocate a Conn (TCP) RelayAddress - AllocateConn(network string, requestedPort int) (net.Conn, net.Addr, error) -} - -// PermissionHandler is a callback to filter incoming CreatePermission and ChannelBindRequest -// requests based on the client IP address and port and the peer IP address the client intends to -// connect to. If the client is behind a NAT then the filter acts on the server reflexive -// ("mapped") address instead of the real client IP address and port. Note that TURN permissions -// are per-allocation and per-peer-IP-address, to mimic the address-restricted filtering mechanism -// of NATs that comply with [RFC4787], see https://tools.ietf.org/html/rfc5766#section-2.3. -type PermissionHandler func(clientAddr net.Addr, peerIP net.IP) (ok bool) - -// DefaultPermissionHandler is convince function that grants permission to all peers -func DefaultPermissionHandler(clientAddr net.Addr, peerIP net.IP) (ok bool) { - return true -} - -// PacketConnConfig is a single net.PacketConn to listen/write on. This will be used for UDP listeners -type PacketConnConfig struct { - PacketConn net.PacketConn - - // When an allocation is generated the RelayAddressGenerator - // creates the net.PacketConn and returns the IP/Port it is available at - RelayAddressGenerator RelayAddressGenerator - - // PermissionHandler is a callback to filter peer addresses. Can be set as nil, in which - // case the DefaultPermissionHandler is automatically instantiated to admit all peer - // connections - PermissionHandler PermissionHandler -} - -func (c *PacketConnConfig) validate() error { - if c.PacketConn == nil { - return errConnUnset - } - if c.RelayAddressGenerator == nil { - return errRelayAddressGeneratorUnset - } - - return c.RelayAddressGenerator.Validate() -} - -// ListenerConfig is a single net.Listener to accept connections on. This will be used for TCP, TLS and DTLS listeners -type ListenerConfig struct { - Listener net.Listener - - // When an allocation is generated the RelayAddressGenerator - // creates the net.PacketConn and returns the IP/Port it is available at - RelayAddressGenerator RelayAddressGenerator - - // PermissionHandler is a callback to filter peer addresses. Can be set as nil, in which - // case the DefaultPermissionHandler is automatically instantiated to admit all peer - // connections - PermissionHandler PermissionHandler -} - -func (c *ListenerConfig) validate() error { - if c.Listener == nil { - return errListenerUnset - } - - if c.RelayAddressGenerator == nil { - return errRelayAddressGeneratorUnset - } - - return c.RelayAddressGenerator.Validate() -} - -// AuthHandler is a callback used to handle incoming auth requests, allowing users to customize Pion TURN with custom behavior -type AuthHandler func(username, realm string, srcAddr net.Addr) (key []byte, ok bool) - -// GenerateAuthKey is a convenience function to easily generate keys in the format used by AuthHandler -func GenerateAuthKey(username, realm, password string) []byte { - // #nosec - h := md5.New() - fmt.Fprint(h, strings.Join([]string{username, realm, password}, ":")) - return h.Sum(nil) -} - -// ServerConfig configures the Pion TURN Server -type ServerConfig struct { - // PacketConnConfigs and ListenerConfigs are a list of all the turn listeners - // Each listener can have custom behavior around the creation of Relays - PacketConnConfigs []PacketConnConfig - ListenerConfigs []ListenerConfig - - // LoggerFactory must be set for logging from this server. - LoggerFactory logging.LoggerFactory - - // Realm sets the realm for this server - Realm string - - // AuthHandler is a callback used to handle incoming auth requests, allowing users to customize Pion TURN with custom behavior - AuthHandler AuthHandler - - // ChannelBindTimeout sets the lifetime of channel binding. Defaults to 10 minutes. - ChannelBindTimeout time.Duration - - // Sets the server inbound MTU(Maximum transmition unit). Defaults to 1600 bytes. - InboundMTU int -} - -func (s *ServerConfig) validate() error { - if len(s.PacketConnConfigs) == 0 && len(s.ListenerConfigs) == 0 { - return errNoAvailableConns - } - - for _, s := range s.PacketConnConfigs { - if err := s.validate(); err != nil { - return err - } - } - - for _, s := range s.ListenerConfigs { - if err := s.validate(); err != nil { - return err - } - } - - return nil -} diff --git a/vendor/github.com/pion/turn/v2/stun_conn.go b/vendor/github.com/pion/turn/v2/stun_conn.go deleted file mode 100644 index ca911ee4..00000000 --- a/vendor/github.com/pion/turn/v2/stun_conn.go +++ /dev/null @@ -1,124 +0,0 @@ -package turn - -import ( - "encoding/binary" - "errors" - "net" - "time" - - "github.com/pion/stun" - "github.com/pion/turn/v2/internal/proto" -) - -var ( - errInvalidTURNFrame = errors.New("data is not a valid TURN frame, no STUN or ChannelData found") - errIncompleteTURNFrame = errors.New("data contains incomplete STUN or TURN frame") -) - -// STUNConn wraps a net.Conn and implements -// net.PacketConn by being STUN aware and -// packetizing the stream -type STUNConn struct { - nextConn net.Conn - buff []byte -} - -const ( - stunHeaderSize = 20 - - channelDataLengthSize = 2 - channelDataNumberSize = channelDataLengthSize - channelDataHeaderSize = channelDataLengthSize + channelDataNumberSize - channelDataPadding = 4 -) - -// Given a buffer give the last offset of the TURN frame -// If the buffer isn't a valid STUN or ChannelData packet -// or the length doesn't match return false -func consumeSingleTURNFrame(p []byte) (int, error) { - // Too short to determine if ChannelData or STUN - if len(p) < 9 { - return 0, errIncompleteTURNFrame - } - - var datagramSize uint16 - switch { - case stun.IsMessage(p): - datagramSize = binary.BigEndian.Uint16(p[2:4]) + stunHeaderSize - case proto.ChannelNumber(binary.BigEndian.Uint16(p[0:2])).Valid(): - datagramSize = binary.BigEndian.Uint16(p[channelDataNumberSize:channelDataHeaderSize]) - if paddingOverflow := (datagramSize + channelDataPadding) % channelDataPadding; paddingOverflow != 0 { - datagramSize = (datagramSize + channelDataPadding) - paddingOverflow - } - - datagramSize += channelDataHeaderSize - case len(p) < stunHeaderSize: - return 0, errIncompleteTURNFrame - default: - return 0, errInvalidTURNFrame - } - - if len(p) < int(datagramSize) { - return 0, errIncompleteTURNFrame - } - - return int(datagramSize), nil -} - -// ReadFrom implements ReadFrom from net.PacketConn -func (s *STUNConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { - // First pass any buffered data from previous reads - n, err = consumeSingleTURNFrame(s.buff) - if errors.Is(err, errInvalidTURNFrame) { - return 0, nil, err - } else if err == nil { - copy(p, s.buff[:n]) - s.buff = s.buff[n:] - - return n, s.nextConn.RemoteAddr(), nil - } - - // Then read from the nextConn, appending to our buff - n, err = s.nextConn.Read(p) - if err != nil { - return 0, nil, err - } - - s.buff = append(s.buff, append([]byte{}, p[:n]...)...) - return s.ReadFrom(p) -} - -// WriteTo implements WriteTo from net.PacketConn -func (s *STUNConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { - return s.nextConn.Write(p) -} - -// Close implements Close from net.PacketConn -func (s *STUNConn) Close() error { - return s.nextConn.Close() -} - -// LocalAddr implements LocalAddr from net.PacketConn -func (s *STUNConn) LocalAddr() net.Addr { - return s.nextConn.LocalAddr() -} - -// SetDeadline implements SetDeadline from net.PacketConn -func (s *STUNConn) SetDeadline(t time.Time) error { - return s.nextConn.SetDeadline(t) -} - -// SetReadDeadline implements SetReadDeadline from net.PacketConn -func (s *STUNConn) SetReadDeadline(t time.Time) error { - return s.nextConn.SetReadDeadline(t) -} - -// SetWriteDeadline implements SetWriteDeadline from net.PacketConn -func (s *STUNConn) SetWriteDeadline(t time.Time) error { - return s.nextConn.SetWriteDeadline(t) -} - -// NewSTUNConn creates a STUNConn -func NewSTUNConn(nextConn net.Conn) *STUNConn { - return &STUNConn{nextConn: nextConn} -} diff --git a/vendor/github.com/pion/webrtc/v3/.codacy.yaml b/vendor/github.com/pion/webrtc/v3/.codacy.yaml deleted file mode 100644 index aa0b11b3..00000000 --- a/vendor/github.com/pion/webrtc/v3/.codacy.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -exclude_paths: - - examples/examples.json diff --git a/vendor/github.com/pion/webrtc/v3/.eslintrc.json b/vendor/github.com/pion/webrtc/v3/.eslintrc.json deleted file mode 100644 index a755cdbf..00000000 --- a/vendor/github.com/pion/webrtc/v3/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["standard"] -} diff --git a/vendor/github.com/pion/webrtc/v3/.gitignore b/vendor/github.com/pion/webrtc/v3/.gitignore deleted file mode 100644 index 6e2f206a..00000000 --- a/vendor/github.com/pion/webrtc/v3/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -### JetBrains IDE ### -##################### -.idea/ - -### Emacs Temporary Files ### -############################# -*~ - -### Folders ### -############### -bin/ -vendor/ -node_modules/ - -### Files ### -############# -*.ivf -*.ogg -tags -cover.out -*.sw[poe] -*.wasm -examples/sfu-ws/cert.pem -examples/sfu-ws/key.pem -wasm_exec.js diff --git a/vendor/github.com/pion/webrtc/v3/.golangci.yml b/vendor/github.com/pion/webrtc/v3/.golangci.yml deleted file mode 100644 index 4e3eddf4..00000000 --- a/vendor/github.com/pion/webrtc/v3/.golangci.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -linters-settings: - govet: - check-shadowing: true - misspell: - locale: US - exhaustive: - default-signifies-exhaustive: true - gomodguard: - blocked: - modules: - - github.com/pkg/errors: - recommendations: - - errors - forbidigo: - forbid: - - ^fmt.Print(f|ln)?$ - - ^log.(Panic|Fatal|Print)(f|ln)?$ - - ^os.Exit$ - - ^panic$ - - ^print(ln)?$ - -linters: - enable: - - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers - - bidichk # Checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - decorder # check declaration order and count of types, constants, variables and functions - - depguard # Go linter that checks if package imports are in a list of acceptable packages - - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) - - dupl # Tool for code clone detection - - durationcheck # check for two durations multiplied together - - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases - - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. - - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. - - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. - - exhaustive # check exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - forbidigo # Forbids identifiers - - forcetypeassert # finds forced type assertions - - gci # Gci control golang package import order and make it always deterministic. - - gochecknoglobals # Checks that no globals are present in Go code - - gochecknoinits # Checks that no init functions are present in Go code - - gocognit # Computes and checks the cognitive complexity of functions - - goconst # Finds repeated strings that could be replaced by a constant - - gocritic # The most opinionated Go source code linter - - godox # Tool for detection of FIXME, TODO and other comment keywords - - goerr113 # Golang linter to check the errors handling expressions - - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification - - gofumpt # Gofumpt checks whether code was gofumpt-ed. - - goheader # Checks is file header matches to pattern - - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports - - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. - - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. - - goprintffuncname # Checks that printf-like functions are named with `f` at the end - - gosec # Inspects source code for security problems - - gosimple # Linter for Go source code that specializes in simplifying a code - - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - - grouper # An analyzer to analyze expression groups. - - importas # Enforces consistent import aliases - - ineffassign # Detects when assignments to existing variables are not used - - misspell # Finds commonly misspelled English words in comments - - nakedret # Finds naked returns in functions greater than a specified function length - - nilerr # Finds the code that returns nil even if it checks that the error is not nil. - - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. - - noctx # noctx finds sending http request without context.Context - - predeclared # find code that shadows one of Go's predeclared identifiers - - revive # golint replacement, finds style mistakes - - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks - - stylecheck # Stylecheck is a replacement for golint - - tagliatelle # Checks the struct tags. - - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes - - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code - - unconvert # Remove unnecessary type conversions - - unparam # Reports unused function parameters - - unused # Checks Go code for unused constants, variables, functions and types - - wastedassign # wastedassign finds wasted assignment statements - - whitespace # Tool for detection of leading and trailing whitespace - disable: - - containedctx # containedctx is a linter that detects struct contained context.Context field - - cyclop # checks function and package cyclomatic complexity - - exhaustivestruct # Checks if all struct's fields are initialized - - funlen # Tool for detection of long functions - - gocyclo # Computes and checks the cyclomatic complexity of functions - - godot # Check if comments end in a period - - gomnd # An analyzer to detect magic numbers. - - ifshort # Checks that your code uses short syntax for if-statements whenever possible - - ireturn # Accept Interfaces, Return Concrete Types - - lll # Reports long lines - - maintidx # maintidx measures the maintainability index of each function. - - makezero # Finds slice declarations with non-zero initial length - - maligned # Tool to detect Go structs that would take less memory if their fields were sorted - - nestif # Reports deeply nested if statements - - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity - - nolintlint # Reports ill-formed or insufficient nolint directives - - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test - - prealloc # Finds slice declarations that could potentially be preallocated - - promlinter # Check Prometheus metrics naming via promlint - - rowserrcheck # checks whether Err of rows is checked successfully - - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. - - testpackage # linter that makes you use a separate _test package - - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - varnamelen # checks that the length of a variable's name matches its scope - - wrapcheck # Checks that errors returned from external packages are wrapped - - wsl # Whitespace Linter - Forces you to use empty lines! - -issues: - exclude-use-default: false - exclude-rules: - # Allow complex tests, better to be self contained - - path: _test\.go - linters: - - gocognit - - forbidigo - - # Allow complex main function in examples - - path: examples - text: "of func `main` is high" - linters: - - gocognit - - # Allow forbidden identifiers in examples - - path: examples - linters: - - forbidigo - - # Allow forbidden identifiers in CLI commands - - path: cmd - linters: - - forbidigo - -run: - skip-dirs-use-default: false diff --git a/vendor/github.com/pion/webrtc/v3/.goreleaser.yml b/vendor/github.com/pion/webrtc/v3/.goreleaser.yml deleted file mode 100644 index 30093e9d..00000000 --- a/vendor/github.com/pion/webrtc/v3/.goreleaser.yml +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -builds: -- skip: true diff --git a/vendor/github.com/pion/webrtc/v3/AUTHORS.txt b/vendor/github.com/pion/webrtc/v3/AUTHORS.txt deleted file mode 100644 index 4ebd9a22..00000000 --- a/vendor/github.com/pion/webrtc/v3/AUTHORS.txt +++ /dev/null @@ -1,214 +0,0 @@ -# Thank you to everyone that made Pion possible. If you are interested in contributing -# we would love to have you https://github.com/pion/webrtc/wiki/Contributing -# -# This file is auto generated, using git to list all individuals contributors. -# see https://github.com/pion/.goassets/blob/master/scripts/generate-authors.sh for the scripting -a-wing <1@233.email> -Aaron Boushley -Aaron France -Adam Kiss -Aditya Kumar -Adrian Cable -adwpc -aggresss -akil -Aleksandr Razumov -aler9 <46489434+aler9@users.noreply.github.com> -Alex Browne -Alex Harford -Alexey Khit -AlexWoo(武杰) -Ali Error -Andrew N. Shalaev -Antoine Baché -Antoine Baché -Anton -Artur Shellunts -Assad Obaid -Ato Araki -Atsushi Watanabe -backkem -baiyufei -Bao Nguyen -Ben Weitzman -Benny Daon -bkim -Bo Shi -boks1971 -Brendan Rius -brian -Bryan Phelps -Cameron Elliott -Cecylia Bocovich -Cedric Fung -cgojin -Chad Retz -chenkaiC4 -Chinmay Kousik -Chris Hiszpanski -Christopher Fry -Clayton McCray -cnderrauber -cyannuk -Daniele Sluijters -David Hamilton -David Zhao -David Zhao -david.s -Dean Sheather -decanus <7621705+decanus@users.noreply.github.com> -Denis -digitalix -donotanswer -earle -Egon Elbre -Eric Daniels -Eric Fontaine -feixiao -Forest Johnson -frank -funvit -Gabor Pongracz -Gareth Hayes -Guilherme -Hanjun Kim -Hendrik Hofstadt -Henry -Hongchao Ma -Hugo Arregui -Hugo Arregui -Ilya Mayorov -imalic3 -Ivan Egorov -JacobZwang <59858341+JacobZwang@users.noreply.github.com> -Jake B -Jamie Good -Jason -Jeff Tchang -jeremija -Jerko Steiner -Jerry Tao -jinleileiking -John Berthels -John Bradley -John Selbie -JooYoung -Jorropo -Josh Bleecher Snyder -juberti -Juliusz Chroboczek -Justin Okamoto -Justin Okamoto -Kevin Staunton-Lambert -Kevin Wang -Konstantin Chugalinskiy -Konstantin Itskov -krishna chiatanya -Kuzmin Vladimir -lawl -Len -Leslie Wang -lisa yan -Lukas Herman -Luke -Luke Curley -Luke S -Magnus Wahlstrand -Manish -Markus Tzoe -Marouane <6729798+nindolabs@users.noreply.github.com> -Marouane -Masahiro Nakamura <13937915+tsuu32@users.noreply.github.com> -Mathis Engelbart -Max Hawkins -mchlrhw <4028654+mchlrhw@users.noreply.github.com> -Michael MacDonald -Michael MacDonald -Michiel De Backker <38858977+backkem@users.noreply.github.com> -Mike Coleman -Mindgamesnl -mission-liao -mohammadne -mr-shitij <21.shitijagrawal@gmail.com> -mxmCherry -Nam V. Do -Nick Mykins -nindolabs <6729798+nindolabs@users.noreply.github.com> -Norman Rasmussen -notedit -o0olele -obasajujoshua31 -Oleg Kovalov -opennota -OrlandoCo -Pascal Benoit -pascal-ace <47424881+pascal-ace@users.noreply.github.com> -Patrice Ferlet -Patrick Lange -Patryk Rogalski -Pieere Pi -Pouget-Abadie -q191201771 <191201771@qq.com> -Quentin Renard -Rafael Viscarra -rahulnakre -Raphael Randschau -Raphael Randschau -Reese <3253971+figadore@users.noreply.github.com> -rob -rob-deutsch -Robert Eperjesi -Robin Raymond -Roman Romanenko -Roman Romanenko -ronan -Ryan Shumate -salmān aljammāz -Sam Lancia -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -Sean DuBois -Sean Knight -Sebastian Waisbrot -Sidney San Martín -Simon Eisenmann -simonacca-fotokite <47634061+simonacca-fotokite@users.noreply.github.com> -Simone Gotti -Slugalisk -Somers Matthews -soolaugust -spaceCh1mp -Steffen Vogel -stephanrotolante -streamer45 -Suhas Gaddam -Suzuki Takeo -sylba2050 -Tarrence van As -tarrencev -Thomas Miller -Tobias Fridén -Tomek -treyhakanson -Tristan Matthews -Twometer -Vicken Simonian -wattanakorn495 -Will Forcey -Will Watson -WofWca -Woodrow Douglass -xsbchen -Yoon SeungYong -Yuki Igarashi -yusuke -Yutaka Takeda -ZHENK -zigazeljko -Štefan Uram -박종훈 - -# List of contributors not appearing in Git history - diff --git a/vendor/github.com/pion/webrtc/v3/DESIGN.md b/vendor/github.com/pion/webrtc/v3/DESIGN.md deleted file mode 100644 index e22b08e3..00000000 --- a/vendor/github.com/pion/webrtc/v3/DESIGN.md +++ /dev/null @@ -1,43 +0,0 @@ -

- Design -

-WebRTC is a powerful, but complicated technology you can build amazing things with, it comes with a steep learning curve though. -Using WebRTC in the browser is easy, but outside the browser is more of a challenge. There are multiple libraries, and they all have -varying levels of quality. Most are also difficult to build, and depend on libraries that aren't available in repos or portable. - -Pion WebRTC aims to solve all that! Built in native Go you should be able to send and receive media and text from anywhere with minimal headache. -These are the design principals that drive Pion WebRTC and hopefully convince you it is worth a try. - -### Portable -Pion WebRTC is written in Go and extremely portable. Anywhere Golang runs, Pion WebRTC should work as well! Instead of dealing with complicated -cross-compiling of multiple libraries, you now can run anywhere with one `go build` - -### Flexible -When possible we leave all decisions to the user. When choice is possible (like what logging library is used) we defer to the developer. - -### Simple API -If you know how to use WebRTC in your browser, you know how to use Pion WebRTC. -We try our best just to duplicate the Javascript API, so your code can look the same everywhere. - -If this is your first time using WebRTC, don't worry! We have multiple [examples](https://github.com/pion/webrtc/tree/master/examples) and [GoDoc](https://pkg.go.dev/github.com/pion/webrtc/v3) - -### Bring your own media -Pion WebRTC doesn't make any assumptions about where your audio, video or text come from. You can use FFmpeg, GStreamer, MLT or just serve a video file. -This library only serves to transport, not create media. - -### Safe -Golang provides a great foundation to build safe network services. -Especially when running a networked service that is highly concurrent bugs can be devastating. - -### Readable -If code comes from an RFC we try to make sure everything is commented with a link to the spec. -This makes learning and debugging easier, this WebRTC library was written to also serve as a guide for others. - -### Tested -Every commit is tested via travis-ci Go provides fantastic facilities for testing, and more will be added as time goes on. - -### Shared libraries -Every Pion project is built using shared libraries, allowing others to review and reuse our libraries. - -### Community -The most important part of Pion is the community. This projects only exist because of individual contributions. We aim to be radically open and do everything we can to support those that make Pion possible. diff --git a/vendor/github.com/pion/webrtc/v3/LICENSE b/vendor/github.com/pion/webrtc/v3/LICENSE deleted file mode 100644 index 491caf6b..00000000 --- a/vendor/github.com/pion/webrtc/v3/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2023 The Pion community - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/pion/webrtc/v3/README.md b/vendor/github.com/pion/webrtc/v3/README.md deleted file mode 100644 index 80dd8c12..00000000 --- a/vendor/github.com/pion/webrtc/v3/README.md +++ /dev/null @@ -1,129 +0,0 @@ -

- Pion WebRTC -
- Pion WebRTC -
-

-

A pure Go implementation of the WebRTC API

-

- Pion WebRTC - Sourcegraph Widget - Slack Widget - Twitter Widget - -
- GitHub Workflow Status - Go Reference - Coverage Status - Go Report Card - License: MIT -

-
- -### Usage -[Go Modules](https://blog.golang.org/using-go-modules) are mandatory for using Pion WebRTC. So make sure you set `export GO111MODULE=on`, and explicitly specify `/v2` or `/v3` when importing. - - -**[example applications](examples/README.md)** contains code samples of common things people build with Pion WebRTC. - -**[example-webrtc-applications](https://github.com/pion/example-webrtc-applications)** contains more full featured examples that use 3rd party libraries. - -**[awesome-pion](https://github.com/pion/awesome-pion)** contains projects that have used Pion, and serve as real world examples of usage. - -**[GoDoc](https://pkg.go.dev/github.com/pion/webrtc/v3)** is an auto generated API reference. All our Public APIs are commented. - -**[FAQ](https://github.com/pion/webrtc/wiki/FAQ)** has answers to common questions. If you have a question not covered please ask in [Slack](https://pion.ly/slack) we are always looking to expand it. - -Now go build something awesome! Here are some **ideas** to get your creative juices flowing: -* Send a video file to multiple browser in real time for perfectly synchronized movie watching. -* Send a webcam on an embedded device to your browser with no additional server required! -* Securely send data between two servers, without using pub/sub. -* Record your webcam and do special effects server side. -* Build a conferencing application that processes audio/video and make decisions off of it. -* Remotely control a robots and stream its cameras in realtime. - -### Want to learn more about WebRTC? -Join our [Office Hours](https://github.com/pion/webrtc/wiki/OfficeHours). Come hang out, ask questions, get help debugging and -hear about the cool things being built with WebRTC. We also start every meeting with basic project planning. - -Check out [WebRTC for the Curious](https://webrtcforthecurious.com). A book about WebRTC in depth, not just about the APIs. -Learn the full details of ICE, SCTP, DTLS, SRTP, and how they work together to make up the WebRTC stack. - -This is also a great resource if you are trying to debug. Learn the tools of the trade and how to approach WebRTC issues. - -This book is vendor agnostic and will not have any Pion specific information. - -### Features -#### PeerConnection API -* Go implementation of [webrtc-pc](https://w3c.github.io/webrtc-pc/) and [webrtc-stats](https://www.w3.org/TR/webrtc-stats/) -* DataChannels -* Send/Receive audio and video -* Renegotiation -* Plan-B and Unified Plan -* [SettingEngine](https://pkg.go.dev/github.com/pion/webrtc/v3#SettingEngine) for Pion specific extensions - - -#### Connectivity -* Full ICE Agent -* ICE Restart -* Trickle ICE -* STUN -* TURN (UDP, TCP, DTLS and TLS) -* mDNS candidates - -#### DataChannels -* Ordered/Unordered -* Lossy/Lossless - -#### Media -* API with direct RTP/RTCP access -* Opus, PCM, H264, VP8 and VP9 packetizer -* API also allows developer to pass their own packetizer -* IVF, Ogg, H264 and Matroska provided for easy sending and saving -* [getUserMedia](https://github.com/pion/mediadevices) implementation (Requires Cgo) -* Easy integration with x264, libvpx, GStreamer and ffmpeg. -* [Simulcast](https://github.com/pion/webrtc/tree/master/examples/simulcast) -* [SVC](https://github.com/pion/rtp/blob/master/codecs/vp9_packet.go#L138) -* [NACK](https://github.com/pion/interceptor/pull/4) -* [Sender/Receiver Reports](https://github.com/pion/interceptor/tree/master/pkg/report) -* [Transport Wide Congestion Control Feedback](https://github.com/pion/interceptor/tree/master/pkg/twcc) -* [Bandwidth Estimation](https://github.com/pion/webrtc/tree/master/examples/bandwidth-estimation-from-disk) - -#### Security -* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 and TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA for DTLS v1.2 -* SRTP_AEAD_AES_256_GCM and SRTP_AES128_CM_HMAC_SHA1_80 for SRTP -* Hardware acceleration available for GCM suites - -#### Pure Go -* No Cgo usage -* Wide platform support - * Windows, macOS, Linux, FreeBSD - * iOS, Android - * [WASM](https://github.com/pion/webrtc/wiki/WebAssembly-Development-and-Testing) see [examples](examples/README.md#webassembly) - * 386, amd64, arm, mips, ppc64 -* Easy to build *Numbers generated on Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz* - * **Time to build examples/play-from-disk** - 0.66s user 0.20s system 306% cpu 0.279 total - * **Time to run entire test suite** - 25.60s user 9.40s system 45% cpu 1:16.69 total -* Tools to measure performance [provided](https://github.com/pion/rtsp-bench) - -### Roadmap -The library is in active development, please refer to the [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones. -We also maintain a list of [Big Ideas](https://github.com/pion/webrtc/wiki/Big-Ideas) these are things we want to build but don't have a clear plan or the resources yet. -If you are looking to get involved this is a great place to get started! We would also love to hear your ideas! Even if you can't implement it yourself, it could inspire others. - -### Sponsoring -Work on Pion's congestion control and bandwidth estimation was funded through the [User-Operated Internet](https://nlnet.nl/useroperated/) fund, a fund established by [NLnet](https://nlnet.nl/) made possible by financial support from the [PKT Community](https://pkt.cash/)/[The Network Steward](https://pkt.cash/network-steward) and stichting [Technology Commons Trust](https://technologycommons.org/). - -### Community -Pion has an active community on the [Slack](https://pion.ly/slack). - -Follow the [Pion Twitter](https://twitter.com/_pion) for project updates and important WebRTC news. - -We are always looking to support **your projects**. Please reach out if you have something to build! -If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly) - -### Contributing -Check out the [contributing wiki](https://github.com/pion/webrtc/wiki/Contributing) to join the group of amazing people making this project possible: [AUTHORS.txt](./AUTHORS.txt) - -### License -MIT License - see [LICENSE](LICENSE) for full text diff --git a/vendor/github.com/pion/webrtc/v3/api.go b/vendor/github.com/pion/webrtc/v3/api.go deleted file mode 100644 index 716be1f3..00000000 --- a/vendor/github.com/pion/webrtc/v3/api.go +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "github.com/pion/interceptor" - "github.com/pion/logging" -) - -// API allows configuration of a PeerConnection -// with APIs that are available in the standard. This -// lets you set custom behavior via the SettingEngine, configure -// codecs via the MediaEngine and define custom media behaviors via -// Interceptors. -type API struct { - settingEngine *SettingEngine - mediaEngine *MediaEngine - interceptorRegistry *interceptor.Registry - - interceptor interceptor.Interceptor // Generated per PeerConnection -} - -// NewAPI Creates a new API object for keeping semi-global settings to WebRTC objects -func NewAPI(options ...func(*API)) *API { - a := &API{ - interceptor: &interceptor.NoOp{}, - settingEngine: &SettingEngine{}, - mediaEngine: &MediaEngine{}, - interceptorRegistry: &interceptor.Registry{}, - } - - for _, o := range options { - o(a) - } - - if a.settingEngine.LoggerFactory == nil { - a.settingEngine.LoggerFactory = logging.NewDefaultLoggerFactory() - } - - return a -} - -// WithMediaEngine allows providing a MediaEngine to the API. -// Settings can be changed after passing the engine to an API. -// When a PeerConnection is created the MediaEngine is copied -// and no more changes can be made. -func WithMediaEngine(m *MediaEngine) func(a *API) { - return func(a *API) { - a.mediaEngine = m - if a.mediaEngine == nil { - a.mediaEngine = &MediaEngine{} - } - } -} - -// WithSettingEngine allows providing a SettingEngine to the API. -// Settings should not be changed after passing the engine to an API. -func WithSettingEngine(s SettingEngine) func(a *API) { - return func(a *API) { - a.settingEngine = &s - } -} - -// WithInterceptorRegistry allows providing Interceptors to the API. -// Settings should not be changed after passing the registry to an API. -func WithInterceptorRegistry(ir *interceptor.Registry) func(a *API) { - return func(a *API) { - a.interceptorRegistry = ir - if a.interceptorRegistry == nil { - a.interceptorRegistry = &interceptor.Registry{} - } - } -} diff --git a/vendor/github.com/pion/webrtc/v3/api_js.go b/vendor/github.com/pion/webrtc/v3/api_js.go deleted file mode 100644 index fe94bff1..00000000 --- a/vendor/github.com/pion/webrtc/v3/api_js.go +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -// API bundles the global funcions of the WebRTC and ORTC API. -type API struct { - settingEngine *SettingEngine -} - -// NewAPI Creates a new API object for keeping semi-global settings to WebRTC objects -func NewAPI(options ...func(*API)) *API { - a := &API{} - - for _, o := range options { - o(a) - } - - if a.settingEngine == nil { - a.settingEngine = &SettingEngine{} - } - - return a -} - -// WithSettingEngine allows providing a SettingEngine to the API. -// Settings should not be changed after passing the engine to an API. -func WithSettingEngine(s SettingEngine) func(a *API) { - return func(a *API) { - a.settingEngine = &s - } -} diff --git a/vendor/github.com/pion/webrtc/v3/atomicbool.go b/vendor/github.com/pion/webrtc/v3/atomicbool.go deleted file mode 100644 index cc6cdc1e..00000000 --- a/vendor/github.com/pion/webrtc/v3/atomicbool.go +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import "sync/atomic" - -type atomicBool struct { - val int32 -} - -func (b *atomicBool) set(value bool) { // nolint: unparam - var i int32 - if value { - i = 1 - } - - atomic.StoreInt32(&(b.val), i) -} - -func (b *atomicBool) get() bool { - return atomic.LoadInt32(&(b.val)) != 0 -} - -func (b *atomicBool) swap(value bool) bool { - var i int32 - if value { - i = 1 - } - return atomic.SwapInt32(&(b.val), i) != 0 -} diff --git a/vendor/github.com/pion/webrtc/v3/bundlepolicy.go b/vendor/github.com/pion/webrtc/v3/bundlepolicy.go deleted file mode 100644 index ea6dad5a..00000000 --- a/vendor/github.com/pion/webrtc/v3/bundlepolicy.go +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "encoding/json" -) - -// BundlePolicy affects which media tracks are negotiated if the remote -// endpoint is not bundle-aware, and what ICE candidates are gathered. If the -// remote endpoint is bundle-aware, all media tracks and data channels are -// bundled onto the same transport. -type BundlePolicy int - -const ( - // BundlePolicyBalanced indicates to gather ICE candidates for each - // media type in use (audio, video, and data). If the remote endpoint is - // not bundle-aware, negotiate only one audio and video track on separate - // transports. - BundlePolicyBalanced BundlePolicy = iota + 1 - - // BundlePolicyMaxCompat indicates to gather ICE candidates for each - // track. If the remote endpoint is not bundle-aware, negotiate all media - // tracks on separate transports. - BundlePolicyMaxCompat - - // BundlePolicyMaxBundle indicates to gather ICE candidates for only - // one track. If the remote endpoint is not bundle-aware, negotiate only - // one media track. - BundlePolicyMaxBundle -) - -// This is done this way because of a linter. -const ( - bundlePolicyBalancedStr = "balanced" - bundlePolicyMaxCompatStr = "max-compat" - bundlePolicyMaxBundleStr = "max-bundle" -) - -func newBundlePolicy(raw string) BundlePolicy { - switch raw { - case bundlePolicyBalancedStr: - return BundlePolicyBalanced - case bundlePolicyMaxCompatStr: - return BundlePolicyMaxCompat - case bundlePolicyMaxBundleStr: - return BundlePolicyMaxBundle - default: - return BundlePolicy(Unknown) - } -} - -func (t BundlePolicy) String() string { - switch t { - case BundlePolicyBalanced: - return bundlePolicyBalancedStr - case BundlePolicyMaxCompat: - return bundlePolicyMaxCompatStr - case BundlePolicyMaxBundle: - return bundlePolicyMaxBundleStr - default: - return ErrUnknownType.Error() - } -} - -// UnmarshalJSON parses the JSON-encoded data and stores the result -func (t *BundlePolicy) UnmarshalJSON(b []byte) error { - var val string - if err := json.Unmarshal(b, &val); err != nil { - return err - } - - *t = newBundlePolicy(val) - return nil -} - -// MarshalJSON returns the JSON encoding -func (t BundlePolicy) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} diff --git a/vendor/github.com/pion/webrtc/v3/certificate.go b/vendor/github.com/pion/webrtc/v3/certificate.go deleted file mode 100644 index 1d5631bc..00000000 --- a/vendor/github.com/pion/webrtc/v3/certificate.go +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/base64" - "encoding/pem" - "fmt" - "math/big" - "strings" - "time" - - "github.com/pion/dtls/v2/pkg/crypto/fingerprint" - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -// Certificate represents a x509Cert used to authenticate WebRTC communications. -type Certificate struct { - privateKey crypto.PrivateKey - x509Cert *x509.Certificate - statsID string -} - -// NewCertificate generates a new x509 compliant Certificate to be used -// by DTLS for encrypting data sent over the wire. This method differs from -// GenerateCertificate by allowing to specify a template x509.Certificate to -// be used in order to define certificate parameters. -func NewCertificate(key crypto.PrivateKey, tpl x509.Certificate) (*Certificate, error) { - var err error - var certDER []byte - switch sk := key.(type) { - case *rsa.PrivateKey: - pk := sk.Public() - tpl.SignatureAlgorithm = x509.SHA256WithRSA - certDER, err = x509.CreateCertificate(rand.Reader, &tpl, &tpl, pk, sk) - if err != nil { - return nil, &rtcerr.UnknownError{Err: err} - } - case *ecdsa.PrivateKey: - pk := sk.Public() - tpl.SignatureAlgorithm = x509.ECDSAWithSHA256 - certDER, err = x509.CreateCertificate(rand.Reader, &tpl, &tpl, pk, sk) - if err != nil { - return nil, &rtcerr.UnknownError{Err: err} - } - default: - return nil, &rtcerr.NotSupportedError{Err: ErrPrivateKeyType} - } - - cert, err := x509.ParseCertificate(certDER) - if err != nil { - return nil, &rtcerr.UnknownError{Err: err} - } - - return &Certificate{privateKey: key, x509Cert: cert, statsID: fmt.Sprintf("certificate-%d", time.Now().UnixNano())}, nil -} - -// Equals determines if two certificates are identical by comparing both the -// secretKeys and x509Certificates. -func (c Certificate) Equals(o Certificate) bool { - switch cSK := c.privateKey.(type) { - case *rsa.PrivateKey: - if oSK, ok := o.privateKey.(*rsa.PrivateKey); ok { - if cSK.N.Cmp(oSK.N) != 0 { - return false - } - return c.x509Cert.Equal(o.x509Cert) - } - return false - case *ecdsa.PrivateKey: - if oSK, ok := o.privateKey.(*ecdsa.PrivateKey); ok { - if cSK.X.Cmp(oSK.X) != 0 || cSK.Y.Cmp(oSK.Y) != 0 { - return false - } - return c.x509Cert.Equal(o.x509Cert) - } - return false - default: - return false - } -} - -// Expires returns the timestamp after which this certificate is no longer valid. -func (c Certificate) Expires() time.Time { - if c.x509Cert == nil { - return time.Time{} - } - return c.x509Cert.NotAfter -} - -// GetFingerprints returns the list of certificate fingerprints, one of which -// is computed with the digest algorithm used in the certificate signature. -func (c Certificate) GetFingerprints() ([]DTLSFingerprint, error) { - fingerprintAlgorithms := []crypto.Hash{crypto.SHA256} - res := make([]DTLSFingerprint, len(fingerprintAlgorithms)) - - i := 0 - for _, algo := range fingerprintAlgorithms { - name, err := fingerprint.StringFromHash(algo) - if err != nil { - // nolint - return nil, fmt.Errorf("%w: %v", ErrFailedToGenerateCertificateFingerprint, err) - } - value, err := fingerprint.Fingerprint(c.x509Cert, algo) - if err != nil { - // nolint - return nil, fmt.Errorf("%w: %v", ErrFailedToGenerateCertificateFingerprint, err) - } - res[i] = DTLSFingerprint{ - Algorithm: name, - Value: value, - } - } - - return res[:i+1], nil -} - -// GenerateCertificate causes the creation of an X.509 certificate and -// corresponding private key. -func GenerateCertificate(secretKey crypto.PrivateKey) (*Certificate, error) { - // Max random value, a 130-bits integer, i.e 2^130 - 1 - maxBigInt := new(big.Int) - /* #nosec */ - maxBigInt.Exp(big.NewInt(2), big.NewInt(130), nil).Sub(maxBigInt, big.NewInt(1)) - /* #nosec */ - serialNumber, err := rand.Int(rand.Reader, maxBigInt) - if err != nil { - return nil, &rtcerr.UnknownError{Err: err} - } - - return NewCertificate(secretKey, x509.Certificate{ - Issuer: pkix.Name{CommonName: generatedCertificateOrigin}, - NotBefore: time.Now().AddDate(0, 0, -1), - NotAfter: time.Now().AddDate(0, 1, -1), - SerialNumber: serialNumber, - Version: 2, - Subject: pkix.Name{CommonName: generatedCertificateOrigin}, - }) -} - -// CertificateFromX509 creates a new WebRTC Certificate from a given PrivateKey and Certificate -// -// This can be used if you want to share a certificate across multiple PeerConnections -func CertificateFromX509(privateKey crypto.PrivateKey, certificate *x509.Certificate) Certificate { - return Certificate{privateKey, certificate, fmt.Sprintf("certificate-%d", time.Now().UnixNano())} -} - -func (c Certificate) collectStats(report *statsReportCollector) error { - report.Collecting() - - fingerPrintAlgo, err := c.GetFingerprints() - if err != nil { - return err - } - - base64Certificate := base64.RawURLEncoding.EncodeToString(c.x509Cert.Raw) - - stats := CertificateStats{ - Timestamp: statsTimestampFrom(time.Now()), - Type: StatsTypeCertificate, - ID: c.statsID, - Fingerprint: fingerPrintAlgo[0].Value, - FingerprintAlgorithm: fingerPrintAlgo[0].Algorithm, - Base64Certificate: base64Certificate, - IssuerCertificateID: c.x509Cert.Issuer.String(), - } - - report.Collect(stats.ID, stats) - return nil -} - -// CertificateFromPEM creates a fresh certificate based on a string containing -// pem blocks fort the private key and x509 certificate -func CertificateFromPEM(pems string) (*Certificate, error) { - // decode & parse the certificate - block, more := pem.Decode([]byte(pems)) - if block == nil || block.Type != "CERTIFICATE" { - return nil, errCertificatePEMFormatError - } - certBytes := make([]byte, base64.StdEncoding.DecodedLen(len(block.Bytes))) - n, err := base64.StdEncoding.Decode(certBytes, block.Bytes) - if err != nil { - return nil, fmt.Errorf("failed to decode ceritifcate: %w", err) - } - cert, err := x509.ParseCertificate(certBytes[:n]) - if err != nil { - return nil, fmt.Errorf("failed parsing ceritifcate: %w", err) - } - // decode & parse the private key - block, _ = pem.Decode(more) - if block == nil || block.Type != "PRIVATE KEY" { - return nil, errCertificatePEMFormatError - } - privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) - if err != nil { - return nil, fmt.Errorf("unable to parse private key: %w", err) - } - x := CertificateFromX509(privateKey, cert) - return &x, nil -} - -// PEM returns the certificate encoded as two pem block: once for the X509 -// certificate and the other for the private key -func (c Certificate) PEM() (string, error) { - // First write the X509 certificate - var o strings.Builder - xcertBytes := make( - []byte, base64.StdEncoding.EncodedLen(len(c.x509Cert.Raw))) - base64.StdEncoding.Encode(xcertBytes, c.x509Cert.Raw) - err := pem.Encode(&o, &pem.Block{Type: "CERTIFICATE", Bytes: xcertBytes}) - if err != nil { - return "", fmt.Errorf("failed to pem encode the X certificate: %w", err) - } - // Next write the private key - privBytes, err := x509.MarshalPKCS8PrivateKey(c.privateKey) - if err != nil { - return "", fmt.Errorf("failed to marshal private key: %w", err) - } - err = pem.Encode(&o, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}) - if err != nil { - return "", fmt.Errorf("failed to encode private key: %w", err) - } - return o.String(), nil -} diff --git a/vendor/github.com/pion/webrtc/v3/codecov.yml b/vendor/github.com/pion/webrtc/v3/codecov.yml deleted file mode 100644 index 263e4d45..00000000 --- a/vendor/github.com/pion/webrtc/v3/codecov.yml +++ /dev/null @@ -1,22 +0,0 @@ -# -# DO NOT EDIT THIS FILE -# -# It is automatically copied from https://github.com/pion/.goassets repository. -# -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -coverage: - status: - project: - default: - # Allow decreasing 2% of total coverage to avoid noise. - threshold: 2% - patch: - default: - target: 70% - only_pulls: true - -ignore: - - "examples/*" - - "examples/**/*" diff --git a/vendor/github.com/pion/webrtc/v3/configuration.go b/vendor/github.com/pion/webrtc/v3/configuration.go deleted file mode 100644 index 90be318e..00000000 --- a/vendor/github.com/pion/webrtc/v3/configuration.go +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -// A Configuration defines how peer-to-peer communication via PeerConnection -// is established or re-established. -// Configurations may be set up once and reused across multiple connections. -// Configurations are treated as readonly. As long as they are unmodified, -// they are safe for concurrent use. -type Configuration struct { - // ICEServers defines a slice describing servers available to be used by - // ICE, such as STUN and TURN servers. - ICEServers []ICEServer `json:"iceServers,omitempty"` - - // ICETransportPolicy indicates which candidates the ICEAgent is allowed - // to use. - ICETransportPolicy ICETransportPolicy `json:"iceTransportPolicy,omitempty"` - - // BundlePolicy indicates which media-bundling policy to use when gathering - // ICE candidates. - BundlePolicy BundlePolicy `json:"bundlePolicy,omitempty"` - - // RTCPMuxPolicy indicates which rtcp-mux policy to use when gathering ICE - // candidates. - RTCPMuxPolicy RTCPMuxPolicy `json:"rtcpMuxPolicy,omitempty"` - - // PeerIdentity sets the target peer identity for the PeerConnection. - // The PeerConnection will not establish a connection to a remote peer - // unless it can be successfully authenticated with the provided name. - PeerIdentity string `json:"peerIdentity,omitempty"` - - // Certificates describes a set of certificates that the PeerConnection - // uses to authenticate. Valid values for this parameter are created - // through calls to the GenerateCertificate function. Although any given - // DTLS connection will use only one certificate, this attribute allows the - // caller to provide multiple certificates that support different - // algorithms. The final certificate will be selected based on the DTLS - // handshake, which establishes which certificates are allowed. The - // PeerConnection implementation selects which of the certificates is - // used for a given connection; how certificates are selected is outside - // the scope of this specification. If this value is absent, then a default - // set of certificates is generated for each PeerConnection instance. - Certificates []Certificate `json:"certificates,omitempty"` - - // ICECandidatePoolSize describes the size of the prefetched ICE pool. - ICECandidatePoolSize uint8 `json:"iceCandidatePoolSize,omitempty"` - - // SDPSemantics controls the type of SDP offers accepted by and - // SDP answers generated by the PeerConnection. - SDPSemantics SDPSemantics `json:"sdpSemantics,omitempty"` -} diff --git a/vendor/github.com/pion/webrtc/v3/configuration_common.go b/vendor/github.com/pion/webrtc/v3/configuration_common.go deleted file mode 100644 index a3acdf5b..00000000 --- a/vendor/github.com/pion/webrtc/v3/configuration_common.go +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import "strings" - -// getICEServers side-steps the strict parsing mode of the ice package -// (as defined in https://tools.ietf.org/html/rfc7064) by copying and then -// stripping any erroneous queries from "stun(s):" URLs before parsing. -func (c Configuration) getICEServers() []ICEServer { - iceServers := append([]ICEServer{}, c.ICEServers...) - - for iceServersIndex := range iceServers { - iceServers[iceServersIndex].URLs = append([]string{}, iceServers[iceServersIndex].URLs...) - - for urlsIndex, rawURL := range iceServers[iceServersIndex].URLs { - if strings.HasPrefix(rawURL, "stun") { - // strip the query from "stun(s):" if present - parts := strings.Split(rawURL, "?") - rawURL = parts[0] - } - iceServers[iceServersIndex].URLs[urlsIndex] = rawURL - } - } - return iceServers -} diff --git a/vendor/github.com/pion/webrtc/v3/configuration_js.go b/vendor/github.com/pion/webrtc/v3/configuration_js.go deleted file mode 100644 index 097085f9..00000000 --- a/vendor/github.com/pion/webrtc/v3/configuration_js.go +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -// Configuration defines a set of parameters to configure how the -// peer-to-peer communication via PeerConnection is established or -// re-established. -type Configuration struct { - // ICEServers defines a slice describing servers available to be used by - // ICE, such as STUN and TURN servers. - ICEServers []ICEServer - - // ICETransportPolicy indicates which candidates the ICEAgent is allowed - // to use. - ICETransportPolicy ICETransportPolicy - - // BundlePolicy indicates which media-bundling policy to use when gathering - // ICE candidates. - BundlePolicy BundlePolicy - - // RTCPMuxPolicy indicates which rtcp-mux policy to use when gathering ICE - // candidates. - RTCPMuxPolicy RTCPMuxPolicy - - // PeerIdentity sets the target peer identity for the PeerConnection. - // The PeerConnection will not establish a connection to a remote peer - // unless it can be successfully authenticated with the provided name. - PeerIdentity string - - // Certificates are not supported in the JavaScript/Wasm bindings. - // Certificates []Certificate - - // ICECandidatePoolSize describes the size of the prefetched ICE pool. - ICECandidatePoolSize uint8 -} diff --git a/vendor/github.com/pion/webrtc/v3/constants.go b/vendor/github.com/pion/webrtc/v3/constants.go deleted file mode 100644 index 94ba7849..00000000 --- a/vendor/github.com/pion/webrtc/v3/constants.go +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import "github.com/pion/dtls/v2" - -const ( - // Unknown defines default public constant to use for "enum" like struct - // comparisons when no value was defined. - Unknown = iota - unknownStr = "unknown" - - // Equal to UDP MTU - receiveMTU = 1460 - - // simulcastProbeCount is the amount of RTP Packets - // that handleUndeclaredSSRC will read and try to dispatch from - // mid and rid values - simulcastProbeCount = 10 - - // simulcastMaxProbeRoutines is how many active routines can be used to probe - // If the total amount of incoming SSRCes exceeds this new requests will be ignored - simulcastMaxProbeRoutines = 25 - - mediaSectionApplication = "application" - - sdpAttributeRid = "rid" - - rtpOutboundMTU = 1200 - - rtpPayloadTypeBitmask = 0x7F - - incomingUnhandledRTPSsrc = "Incoming unhandled RTP ssrc(%d), OnTrack will not be fired. %v" - - generatedCertificateOrigin = "WebRTC" - - sdesRepairRTPStreamIDURI = "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id" -) - -func defaultSrtpProtectionProfiles() []dtls.SRTPProtectionProfile { - return []dtls.SRTPProtectionProfile{dtls.SRTP_AEAD_AES_256_GCM, dtls.SRTP_AEAD_AES_128_GCM, dtls.SRTP_AES128_CM_HMAC_SHA1_80} -} diff --git a/vendor/github.com/pion/webrtc/v3/datachannel.go b/vendor/github.com/pion/webrtc/v3/datachannel.go deleted file mode 100644 index 9c9154c8..00000000 --- a/vendor/github.com/pion/webrtc/v3/datachannel.go +++ /dev/null @@ -1,631 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "errors" - "fmt" - "io" - "math" - "sync" - "sync/atomic" - "time" - - "github.com/pion/datachannel" - "github.com/pion/logging" - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -const dataChannelBufferSize = math.MaxUint16 // message size limit for Chromium -var errSCTPNotEstablished = errors.New("SCTP not established") - -// DataChannel represents a WebRTC DataChannel -// The DataChannel interface represents a network channel -// which can be used for bidirectional peer-to-peer transfers of arbitrary data -type DataChannel struct { - mu sync.RWMutex - - statsID string - label string - ordered bool - maxPacketLifeTime *uint16 - maxRetransmits *uint16 - protocol string - negotiated bool - id *uint16 - readyState atomic.Value // DataChannelState - bufferedAmountLowThreshold uint64 - detachCalled bool - - // The binaryType represents attribute MUST, on getting, return the value to - // which it was last set. On setting, if the new value is either the string - // "blob" or the string "arraybuffer", then set the IDL attribute to this - // new value. Otherwise, throw a SyntaxError. When an DataChannel object - // is created, the binaryType attribute MUST be initialized to the string - // "blob". This attribute controls how binary data is exposed to scripts. - // binaryType string - - onMessageHandler func(DataChannelMessage) - openHandlerOnce sync.Once - onOpenHandler func() - dialHandlerOnce sync.Once - onDialHandler func() - onCloseHandler func() - onBufferedAmountLow func() - onErrorHandler func(error) - - sctpTransport *SCTPTransport - dataChannel *datachannel.DataChannel - - // A reference to the associated api object used by this datachannel - api *API - log logging.LeveledLogger -} - -// NewDataChannel creates a new DataChannel. -// This constructor is part of the ORTC API. It is not -// meant to be used together with the basic WebRTC API. -func (api *API) NewDataChannel(transport *SCTPTransport, params *DataChannelParameters) (*DataChannel, error) { - d, err := api.newDataChannel(params, nil, api.settingEngine.LoggerFactory.NewLogger("ortc")) - if err != nil { - return nil, err - } - - err = d.open(transport) - if err != nil { - return nil, err - } - - return d, nil -} - -// newDataChannel is an internal constructor for the data channel used to -// create the DataChannel object before the networking is set up. -func (api *API) newDataChannel(params *DataChannelParameters, sctpTransport *SCTPTransport, log logging.LeveledLogger) (*DataChannel, error) { - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #5) - if len(params.Label) > 65535 { - return nil, &rtcerr.TypeError{Err: ErrStringSizeLimit} - } - - d := &DataChannel{ - sctpTransport: sctpTransport, - statsID: fmt.Sprintf("DataChannel-%d", time.Now().UnixNano()), - label: params.Label, - protocol: params.Protocol, - negotiated: params.Negotiated, - id: params.ID, - ordered: params.Ordered, - maxPacketLifeTime: params.MaxPacketLifeTime, - maxRetransmits: params.MaxRetransmits, - api: api, - log: log, - } - - d.setReadyState(DataChannelStateConnecting) - return d, nil -} - -// open opens the datachannel over the sctp transport -func (d *DataChannel) open(sctpTransport *SCTPTransport) error { - association := sctpTransport.association() - if association == nil { - return errSCTPNotEstablished - } - - d.mu.Lock() - if d.sctpTransport != nil { // already open - d.mu.Unlock() - return nil - } - d.sctpTransport = sctpTransport - var channelType datachannel.ChannelType - var reliabilityParameter uint32 - - switch { - case d.maxPacketLifeTime == nil && d.maxRetransmits == nil: - if d.ordered { - channelType = datachannel.ChannelTypeReliable - } else { - channelType = datachannel.ChannelTypeReliableUnordered - } - - case d.maxRetransmits != nil: - reliabilityParameter = uint32(*d.maxRetransmits) - if d.ordered { - channelType = datachannel.ChannelTypePartialReliableRexmit - } else { - channelType = datachannel.ChannelTypePartialReliableRexmitUnordered - } - default: - reliabilityParameter = uint32(*d.maxPacketLifeTime) - if d.ordered { - channelType = datachannel.ChannelTypePartialReliableTimed - } else { - channelType = datachannel.ChannelTypePartialReliableTimedUnordered - } - } - - cfg := &datachannel.Config{ - ChannelType: channelType, - Priority: datachannel.ChannelPriorityNormal, - ReliabilityParameter: reliabilityParameter, - Label: d.label, - Protocol: d.protocol, - Negotiated: d.negotiated, - LoggerFactory: d.api.settingEngine.LoggerFactory, - } - - if d.id == nil { - // avoid holding lock when generating ID, since id generation locks - d.mu.Unlock() - var dcID *uint16 - err := d.sctpTransport.generateAndSetDataChannelID(d.sctpTransport.dtlsTransport.role(), &dcID) - if err != nil { - return err - } - d.mu.Lock() - d.id = dcID - } - dc, err := datachannel.Dial(association, *d.id, cfg) - if err != nil { - d.mu.Unlock() - return err - } - - // bufferedAmountLowThreshold and onBufferedAmountLow might be set earlier - dc.SetBufferedAmountLowThreshold(d.bufferedAmountLowThreshold) - dc.OnBufferedAmountLow(d.onBufferedAmountLow) - d.mu.Unlock() - - d.onDial() - d.handleOpen(dc, false, d.negotiated) - return nil -} - -// Transport returns the SCTPTransport instance the DataChannel is sending over. -func (d *DataChannel) Transport() *SCTPTransport { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.sctpTransport -} - -// After onOpen is complete check that the user called detach -// and provide an error message if the call was missed -func (d *DataChannel) checkDetachAfterOpen() { - d.mu.RLock() - defer d.mu.RUnlock() - - if d.api.settingEngine.detach.DataChannels && !d.detachCalled { - d.log.Warn("webrtc.DetachDataChannels() enabled but didn't Detach, call Detach from OnOpen") - } -} - -// OnOpen sets an event handler which is invoked when -// the underlying data transport has been established (or re-established). -func (d *DataChannel) OnOpen(f func()) { - d.mu.Lock() - d.openHandlerOnce = sync.Once{} - d.onOpenHandler = f - d.mu.Unlock() - - if d.ReadyState() == DataChannelStateOpen { - // If the data channel is already open, call the handler immediately. - go d.openHandlerOnce.Do(func() { - f() - d.checkDetachAfterOpen() - }) - } -} - -func (d *DataChannel) onOpen() { - d.mu.RLock() - handler := d.onOpenHandler - d.mu.RUnlock() - - if handler != nil { - go d.openHandlerOnce.Do(func() { - handler() - d.checkDetachAfterOpen() - }) - } -} - -// OnDial sets an event handler which is invoked when the -// peer has been dialed, but before said peer has responsed -func (d *DataChannel) OnDial(f func()) { - d.mu.Lock() - d.dialHandlerOnce = sync.Once{} - d.onDialHandler = f - d.mu.Unlock() - - if d.ReadyState() == DataChannelStateOpen { - // If the data channel is already open, call the handler immediately. - go d.dialHandlerOnce.Do(f) - } -} - -func (d *DataChannel) onDial() { - d.mu.RLock() - handler := d.onDialHandler - d.mu.RUnlock() - - if handler != nil { - go d.dialHandlerOnce.Do(handler) - } -} - -// OnClose sets an event handler which is invoked when -// the underlying data transport has been closed. -func (d *DataChannel) OnClose(f func()) { - d.mu.Lock() - defer d.mu.Unlock() - d.onCloseHandler = f -} - -func (d *DataChannel) onClose() { - d.mu.RLock() - handler := d.onCloseHandler - d.mu.RUnlock() - - if handler != nil { - go handler() - } -} - -// OnMessage sets an event handler which is invoked on a binary -// message arrival over the sctp transport from a remote peer. -// OnMessage can currently receive messages up to 16384 bytes -// in size. Check out the detach API if you want to use larger -// message sizes. Note that browser support for larger messages -// is also limited. -func (d *DataChannel) OnMessage(f func(msg DataChannelMessage)) { - d.mu.Lock() - defer d.mu.Unlock() - d.onMessageHandler = f -} - -func (d *DataChannel) onMessage(msg DataChannelMessage) { - d.mu.RLock() - handler := d.onMessageHandler - d.mu.RUnlock() - - if handler == nil { - return - } - handler(msg) -} - -func (d *DataChannel) handleOpen(dc *datachannel.DataChannel, isRemote, isAlreadyNegotiated bool) { - d.mu.Lock() - d.dataChannel = dc - d.mu.Unlock() - d.setReadyState(DataChannelStateOpen) - - // Fire the OnOpen handler immediately not using pion/datachannel - // * detached datachannels have no read loop, the user needs to read and query themselves - // * remote datachannels should fire OnOpened. This isn't spec compliant, but we can't break behavior yet - // * already negotiated datachannels should fire OnOpened - if d.api.settingEngine.detach.DataChannels || isRemote || isAlreadyNegotiated { - // bufferedAmountLowThreshold and onBufferedAmountLow might be set earlier - d.dataChannel.SetBufferedAmountLowThreshold(d.bufferedAmountLowThreshold) - d.dataChannel.OnBufferedAmountLow(d.onBufferedAmountLow) - d.onOpen() - } else { - dc.OnOpen(func() { - d.onOpen() - }) - } - - d.mu.Lock() - defer d.mu.Unlock() - - if !d.api.settingEngine.detach.DataChannels { - go d.readLoop() - } -} - -// OnError sets an event handler which is invoked when -// the underlying data transport cannot be read. -func (d *DataChannel) OnError(f func(err error)) { - d.mu.Lock() - defer d.mu.Unlock() - d.onErrorHandler = f -} - -func (d *DataChannel) onError(err error) { - d.mu.RLock() - handler := d.onErrorHandler - d.mu.RUnlock() - - if handler != nil { - go handler(err) - } -} - -// See https://github.com/pion/webrtc/issues/1516 -// nolint:gochecknoglobals -var rlBufPool = sync.Pool{New: func() interface{} { - return make([]byte, dataChannelBufferSize) -}} - -func (d *DataChannel) readLoop() { - for { - buffer := rlBufPool.Get().([]byte) //nolint:forcetypeassert - n, isString, err := d.dataChannel.ReadDataChannel(buffer) - if err != nil { - rlBufPool.Put(buffer) // nolint:staticcheck - d.setReadyState(DataChannelStateClosed) - if !errors.Is(err, io.EOF) { - d.onError(err) - } - d.onClose() - return - } - - m := DataChannelMessage{Data: make([]byte, n), IsString: isString} - copy(m.Data, buffer[:n]) - // The 'staticcheck' pragma is a false positive on the part of the CI linter. - rlBufPool.Put(buffer) // nolint:staticcheck - - // NB: Why was DataChannelMessage not passed as a pointer value? - d.onMessage(m) // nolint:staticcheck - } -} - -// Send sends the binary message to the DataChannel peer -func (d *DataChannel) Send(data []byte) error { - err := d.ensureOpen() - if err != nil { - return err - } - - _, err = d.dataChannel.WriteDataChannel(data, false) - return err -} - -// SendText sends the text message to the DataChannel peer -func (d *DataChannel) SendText(s string) error { - err := d.ensureOpen() - if err != nil { - return err - } - - _, err = d.dataChannel.WriteDataChannel([]byte(s), true) - return err -} - -func (d *DataChannel) ensureOpen() error { - d.mu.RLock() - defer d.mu.RUnlock() - if d.ReadyState() != DataChannelStateOpen { - return io.ErrClosedPipe - } - return nil -} - -// Detach allows you to detach the underlying datachannel. This provides -// an idiomatic API to work with, however it disables the OnMessage callback. -// Before calling Detach you have to enable this behavior by calling -// webrtc.DetachDataChannels(). Combining detached and normal data channels -// is not supported. -// Please refer to the data-channels-detach example and the -// pion/datachannel documentation for the correct way to handle the -// resulting DataChannel object. -func (d *DataChannel) Detach() (datachannel.ReadWriteCloser, error) { - d.mu.Lock() - defer d.mu.Unlock() - - if !d.api.settingEngine.detach.DataChannels { - return nil, errDetachNotEnabled - } - - if d.dataChannel == nil { - return nil, errDetachBeforeOpened - } - - d.detachCalled = true - - return d.dataChannel, nil -} - -// Close Closes the DataChannel. It may be called regardless of whether -// the DataChannel object was created by this peer or the remote peer. -func (d *DataChannel) Close() error { - d.mu.Lock() - haveSctpTransport := d.dataChannel != nil - d.mu.Unlock() - - if d.ReadyState() == DataChannelStateClosed { - return nil - } - - d.setReadyState(DataChannelStateClosing) - if !haveSctpTransport { - return nil - } - - return d.dataChannel.Close() -} - -// Label represents a label that can be used to distinguish this -// DataChannel object from other DataChannel objects. Scripts are -// allowed to create multiple DataChannel objects with the same label. -func (d *DataChannel) Label() string { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.label -} - -// Ordered returns true if the DataChannel is ordered, and false if -// out-of-order delivery is allowed. -func (d *DataChannel) Ordered() bool { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.ordered -} - -// MaxPacketLifeTime represents the length of the time window (msec) during -// which transmissions and retransmissions may occur in unreliable mode. -func (d *DataChannel) MaxPacketLifeTime() *uint16 { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.maxPacketLifeTime -} - -// MaxRetransmits represents the maximum number of retransmissions that are -// attempted in unreliable mode. -func (d *DataChannel) MaxRetransmits() *uint16 { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.maxRetransmits -} - -// Protocol represents the name of the sub-protocol used with this -// DataChannel. -func (d *DataChannel) Protocol() string { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.protocol -} - -// Negotiated represents whether this DataChannel was negotiated by the -// application (true), or not (false). -func (d *DataChannel) Negotiated() bool { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.negotiated -} - -// ID represents the ID for this DataChannel. The value is initially -// null, which is what will be returned if the ID was not provided at -// channel creation time, and the DTLS role of the SCTP transport has not -// yet been negotiated. Otherwise, it will return the ID that was either -// selected by the script or generated. After the ID is set to a non-null -// value, it will not change. -func (d *DataChannel) ID() *uint16 { - d.mu.RLock() - defer d.mu.RUnlock() - - return d.id -} - -// ReadyState represents the state of the DataChannel object. -func (d *DataChannel) ReadyState() DataChannelState { - if v, ok := d.readyState.Load().(DataChannelState); ok { - return v - } - return DataChannelState(0) -} - -// BufferedAmount represents the number of bytes of application data -// (UTF-8 text and binary data) that have been queued using send(). Even -// though the data transmission can occur in parallel, the returned value -// MUST NOT be decreased before the current task yielded back to the event -// loop to prevent race conditions. The value does not include framing -// overhead incurred by the protocol, or buffering done by the operating -// system or network hardware. The value of BufferedAmount slot will only -// increase with each call to the send() method as long as the ReadyState is -// open; however, BufferedAmount does not reset to zero once the channel -// closes. -func (d *DataChannel) BufferedAmount() uint64 { - d.mu.RLock() - defer d.mu.RUnlock() - - if d.dataChannel == nil { - return 0 - } - return d.dataChannel.BufferedAmount() -} - -// BufferedAmountLowThreshold represents the threshold at which the -// bufferedAmount is considered to be low. When the bufferedAmount decreases -// from above this threshold to equal or below it, the bufferedamountlow -// event fires. BufferedAmountLowThreshold is initially zero on each new -// DataChannel, but the application may change its value at any time. -// The threshold is set to 0 by default. -func (d *DataChannel) BufferedAmountLowThreshold() uint64 { - d.mu.RLock() - defer d.mu.RUnlock() - - if d.dataChannel == nil { - return d.bufferedAmountLowThreshold - } - return d.dataChannel.BufferedAmountLowThreshold() -} - -// SetBufferedAmountLowThreshold is used to update the threshold. -// See BufferedAmountLowThreshold(). -func (d *DataChannel) SetBufferedAmountLowThreshold(th uint64) { - d.mu.Lock() - defer d.mu.Unlock() - - d.bufferedAmountLowThreshold = th - - if d.dataChannel != nil { - d.dataChannel.SetBufferedAmountLowThreshold(th) - } -} - -// OnBufferedAmountLow sets an event handler which is invoked when -// the number of bytes of outgoing data becomes lower than the -// BufferedAmountLowThreshold. -func (d *DataChannel) OnBufferedAmountLow(f func()) { - d.mu.Lock() - defer d.mu.Unlock() - - d.onBufferedAmountLow = f - if d.dataChannel != nil { - d.dataChannel.OnBufferedAmountLow(f) - } -} - -func (d *DataChannel) getStatsID() string { - d.mu.Lock() - defer d.mu.Unlock() - return d.statsID -} - -func (d *DataChannel) collectStats(collector *statsReportCollector) { - collector.Collecting() - - d.mu.Lock() - defer d.mu.Unlock() - - stats := DataChannelStats{ - Timestamp: statsTimestampNow(), - Type: StatsTypeDataChannel, - ID: d.statsID, - Label: d.label, - Protocol: d.protocol, - // TransportID string `json:"transportId"` - State: d.ReadyState(), - } - - if d.id != nil { - stats.DataChannelIdentifier = int32(*d.id) - } - - if d.dataChannel != nil { - stats.MessagesSent = d.dataChannel.MessagesSent() - stats.BytesSent = d.dataChannel.BytesSent() - stats.MessagesReceived = d.dataChannel.MessagesReceived() - stats.BytesReceived = d.dataChannel.BytesReceived() - } - - collector.Collect(stats.ID, stats) -} - -func (d *DataChannel) setReadyState(r DataChannelState) { - d.readyState.Store(r) -} diff --git a/vendor/github.com/pion/webrtc/v3/datachannel_js.go b/vendor/github.com/pion/webrtc/v3/datachannel_js.go deleted file mode 100644 index a34ab6ef..00000000 --- a/vendor/github.com/pion/webrtc/v3/datachannel_js.go +++ /dev/null @@ -1,323 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import ( - "fmt" - "syscall/js" - - "github.com/pion/datachannel" -) - -const dataChannelBufferSize = 16384 // Lowest common denominator among browsers - -// DataChannel represents a WebRTC DataChannel -// The DataChannel interface represents a network channel -// which can be used for bidirectional peer-to-peer transfers of arbitrary data -type DataChannel struct { - // Pointer to the underlying JavaScript RTCPeerConnection object. - underlying js.Value - - // Keep track of handlers/callbacks so we can call Release as required by the - // syscall/js API. Initially nil. - onOpenHandler *js.Func - onCloseHandler *js.Func - onMessageHandler *js.Func - onBufferedAmountLow *js.Func - - // A reference to the associated api object used by this datachannel - api *API -} - -// OnOpen sets an event handler which is invoked when -// the underlying data transport has been established (or re-established). -func (d *DataChannel) OnOpen(f func()) { - if d.onOpenHandler != nil { - oldHandler := d.onOpenHandler - defer oldHandler.Release() - } - onOpenHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go f() - return js.Undefined() - }) - d.onOpenHandler = &onOpenHandler - d.underlying.Set("onopen", onOpenHandler) -} - -// OnClose sets an event handler which is invoked when -// the underlying data transport has been closed. -func (d *DataChannel) OnClose(f func()) { - if d.onCloseHandler != nil { - oldHandler := d.onCloseHandler - defer oldHandler.Release() - } - onCloseHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go f() - return js.Undefined() - }) - d.onCloseHandler = &onCloseHandler - d.underlying.Set("onclose", onCloseHandler) -} - -// OnMessage sets an event handler which is invoked on a binary message arrival -// from a remote peer. Note that browsers may place limitations on message size. -func (d *DataChannel) OnMessage(f func(msg DataChannelMessage)) { - if d.onMessageHandler != nil { - oldHandler := d.onMessageHandler - defer oldHandler.Release() - } - onMessageHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - // pion/webrtc/projects/15 - data := args[0].Get("data") - go func() { - // valueToDataChannelMessage may block when handling 'Blob' data - // so we need to call it from a new routine. See: - // https://pkg.go.dev/syscall/js#FuncOf - msg := valueToDataChannelMessage(data) - f(msg) - }() - return js.Undefined() - }) - d.onMessageHandler = &onMessageHandler - d.underlying.Set("onmessage", onMessageHandler) -} - -// Send sends the binary message to the DataChannel peer -func (d *DataChannel) Send(data []byte) (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - array := js.Global().Get("Uint8Array").New(len(data)) - js.CopyBytesToJS(array, data) - d.underlying.Call("send", array) - return nil -} - -// SendText sends the text message to the DataChannel peer -func (d *DataChannel) SendText(s string) (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - d.underlying.Call("send", s) - return nil -} - -// Detach allows you to detach the underlying datachannel. This provides -// an idiomatic API to work with, however it disables the OnMessage callback. -// Before calling Detach you have to enable this behavior by calling -// webrtc.DetachDataChannels(). Combining detached and normal data channels -// is not supported. -// Please reffer to the data-channels-detach example and the -// pion/datachannel documentation for the correct way to handle the -// resulting DataChannel object. -func (d *DataChannel) Detach() (datachannel.ReadWriteCloser, error) { - if !d.api.settingEngine.detach.DataChannels { - return nil, fmt.Errorf("enable detaching by calling webrtc.DetachDataChannels()") - } - - detached := newDetachedDataChannel(d) - return detached, nil -} - -// Close Closes the DataChannel. It may be called regardless of whether -// the DataChannel object was created by this peer or the remote peer. -func (d *DataChannel) Close() (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - - d.underlying.Call("close") - - // Release any handlers as required by the syscall/js API. - if d.onOpenHandler != nil { - d.onOpenHandler.Release() - } - if d.onCloseHandler != nil { - d.onCloseHandler.Release() - } - if d.onMessageHandler != nil { - d.onMessageHandler.Release() - } - if d.onBufferedAmountLow != nil { - d.onBufferedAmountLow.Release() - } - - return nil -} - -// Label represents a label that can be used to distinguish this -// DataChannel object from other DataChannel objects. Scripts are -// allowed to create multiple DataChannel objects with the same label. -func (d *DataChannel) Label() string { - return d.underlying.Get("label").String() -} - -// Ordered represents if the DataChannel is ordered, and false if -// out-of-order delivery is allowed. -func (d *DataChannel) Ordered() bool { - ordered := d.underlying.Get("ordered") - if ordered.IsUndefined() { - return true // default is true - } - return ordered.Bool() -} - -// MaxPacketLifeTime represents the length of the time window (msec) during -// which transmissions and retransmissions may occur in unreliable mode. -func (d *DataChannel) MaxPacketLifeTime() *uint16 { - if !d.underlying.Get("maxPacketLifeTime").IsUndefined() { - return valueToUint16Pointer(d.underlying.Get("maxPacketLifeTime")) - } - - // See https://bugs.chromium.org/p/chromium/issues/detail?id=696681 - // Chrome calls this "maxRetransmitTime" - return valueToUint16Pointer(d.underlying.Get("maxRetransmitTime")) -} - -// MaxRetransmits represents the maximum number of retransmissions that are -// attempted in unreliable mode. -func (d *DataChannel) MaxRetransmits() *uint16 { - return valueToUint16Pointer(d.underlying.Get("maxRetransmits")) -} - -// Protocol represents the name of the sub-protocol used with this -// DataChannel. -func (d *DataChannel) Protocol() string { - return d.underlying.Get("protocol").String() -} - -// Negotiated represents whether this DataChannel was negotiated by the -// application (true), or not (false). -func (d *DataChannel) Negotiated() bool { - return d.underlying.Get("negotiated").Bool() -} - -// ID represents the ID for this DataChannel. The value is initially -// null, which is what will be returned if the ID was not provided at -// channel creation time. Otherwise, it will return the ID that was either -// selected by the script or generated. After the ID is set to a non-null -// value, it will not change. -func (d *DataChannel) ID() *uint16 { - return valueToUint16Pointer(d.underlying.Get("id")) -} - -// ReadyState represents the state of the DataChannel object. -func (d *DataChannel) ReadyState() DataChannelState { - return newDataChannelState(d.underlying.Get("readyState").String()) -} - -// BufferedAmount represents the number of bytes of application data -// (UTF-8 text and binary data) that have been queued using send(). Even -// though the data transmission can occur in parallel, the returned value -// MUST NOT be decreased before the current task yielded back to the event -// loop to prevent race conditions. The value does not include framing -// overhead incurred by the protocol, or buffering done by the operating -// system or network hardware. The value of BufferedAmount slot will only -// increase with each call to the send() method as long as the ReadyState is -// open; however, BufferedAmount does not reset to zero once the channel -// closes. -func (d *DataChannel) BufferedAmount() uint64 { - return uint64(d.underlying.Get("bufferedAmount").Int()) -} - -// BufferedAmountLowThreshold represents the threshold at which the -// bufferedAmount is considered to be low. When the bufferedAmount decreases -// from above this threshold to equal or below it, the bufferedamountlow -// event fires. BufferedAmountLowThreshold is initially zero on each new -// DataChannel, but the application may change its value at any time. -func (d *DataChannel) BufferedAmountLowThreshold() uint64 { - return uint64(d.underlying.Get("bufferedAmountLowThreshold").Int()) -} - -// SetBufferedAmountLowThreshold is used to update the threshold. -// See BufferedAmountLowThreshold(). -func (d *DataChannel) SetBufferedAmountLowThreshold(th uint64) { - d.underlying.Set("bufferedAmountLowThreshold", th) -} - -// OnBufferedAmountLow sets an event handler which is invoked when -// the number of bytes of outgoing data becomes lower than the -// BufferedAmountLowThreshold. -func (d *DataChannel) OnBufferedAmountLow(f func()) { - if d.onBufferedAmountLow != nil { - oldHandler := d.onBufferedAmountLow - defer oldHandler.Release() - } - onBufferedAmountLow := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go f() - return js.Undefined() - }) - d.onBufferedAmountLow = &onBufferedAmountLow - d.underlying.Set("onbufferedamountlow", onBufferedAmountLow) -} - -// valueToDataChannelMessage converts the given value to a DataChannelMessage. -// val should be obtained from MessageEvent.data where MessageEvent is received -// via the RTCDataChannel.onmessage callback. -func valueToDataChannelMessage(val js.Value) DataChannelMessage { - // If val is of type string, the conversion is straightforward. - if val.Type() == js.TypeString { - return DataChannelMessage{ - IsString: true, - Data: []byte(val.String()), - } - } - - // For other types, we need to first determine val.constructor.name. - constructorName := val.Get("constructor").Get("name").String() - var data []byte - switch constructorName { - case "Uint8Array": - // We can easily convert Uint8Array to []byte - data = uint8ArrayValueToBytes(val) - case "Blob": - // Convert the Blob to an ArrayBuffer and then convert the ArrayBuffer - // to a Uint8Array. - // See: https://developer.mozilla.org/en-US/docs/Web/API/Blob - - // The JavaScript API for reading from the Blob is asynchronous. We use a - // channel to signal when reading is done. - reader := js.Global().Get("FileReader").New() - doneChan := make(chan struct{}) - reader.Call("addEventListener", "loadend", js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go func() { - // Signal that the FileReader is done reading/loading by sending through - // the doneChan. - doneChan <- struct{}{} - }() - return js.Undefined() - })) - - reader.Call("readAsArrayBuffer", val) - - // Wait for the FileReader to finish reading/loading. - <-doneChan - - // At this point buffer.result is a typed array, which we know how to - // handle. - buffer := reader.Get("result") - uint8Array := js.Global().Get("Uint8Array").New(buffer) - data = uint8ArrayValueToBytes(uint8Array) - default: - // Assume we have an ArrayBufferView type which we can convert to a - // Uint8Array in JavaScript. - // See: https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView - uint8Array := js.Global().Get("Uint8Array").New(val) - data = uint8ArrayValueToBytes(uint8Array) - } - - return DataChannelMessage{ - IsString: false, - Data: data, - } -} diff --git a/vendor/github.com/pion/webrtc/v3/datachannel_js_detach.go b/vendor/github.com/pion/webrtc/v3/datachannel_js_detach.go deleted file mode 100644 index 691e9d4c..00000000 --- a/vendor/github.com/pion/webrtc/v3/datachannel_js_detach.go +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import ( - "errors" -) - -type detachedDataChannel struct { - dc *DataChannel - - read chan DataChannelMessage - done chan struct{} -} - -func newDetachedDataChannel(dc *DataChannel) *detachedDataChannel { - read := make(chan DataChannelMessage) - done := make(chan struct{}) - - // Wire up callbacks - dc.OnMessage(func(msg DataChannelMessage) { - read <- msg // pion/webrtc/projects/15 - }) - - // pion/webrtc/projects/15 - - return &detachedDataChannel{ - dc: dc, - read: read, - done: done, - } -} - -func (c *detachedDataChannel) Read(p []byte) (int, error) { - n, _, err := c.ReadDataChannel(p) - return n, err -} - -func (c *detachedDataChannel) ReadDataChannel(p []byte) (int, bool, error) { - select { - case <-c.done: - return 0, false, errors.New("Reader closed") - case msg := <-c.read: - n := copy(p, msg.Data) - if n < len(msg.Data) { - return n, msg.IsString, errors.New("Read buffer to small") - } - return n, msg.IsString, nil - } -} - -func (c *detachedDataChannel) Write(p []byte) (n int, err error) { - return c.WriteDataChannel(p, false) -} - -func (c *detachedDataChannel) WriteDataChannel(p []byte, isString bool) (n int, err error) { - if isString { - err = c.dc.SendText(string(p)) - return len(p), err - } - - err = c.dc.Send(p) - - return len(p), err -} - -func (c *detachedDataChannel) Close() error { - close(c.done) - - return c.dc.Close() -} diff --git a/vendor/github.com/pion/webrtc/v3/datachannelinit.go b/vendor/github.com/pion/webrtc/v3/datachannelinit.go deleted file mode 100644 index b1775b7c..00000000 --- a/vendor/github.com/pion/webrtc/v3/datachannelinit.go +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// DataChannelInit can be used to configure properties of the underlying -// channel such as data reliability. -type DataChannelInit struct { - // Ordered indicates if data is allowed to be delivered out of order. The - // default value of true, guarantees that data will be delivered in order. - Ordered *bool - - // MaxPacketLifeTime limits the time (in milliseconds) during which the - // channel will transmit or retransmit data if not acknowledged. This value - // may be clamped if it exceeds the maximum value supported. - MaxPacketLifeTime *uint16 - - // MaxRetransmits limits the number of times a channel will retransmit data - // if not successfully delivered. This value may be clamped if it exceeds - // the maximum value supported. - MaxRetransmits *uint16 - - // Protocol describes the subprotocol name used for this channel. - Protocol *string - - // Negotiated describes if the data channel is created by the local peer or - // the remote peer. The default value of false tells the user agent to - // announce the channel in-band and instruct the other peer to dispatch a - // corresponding DataChannel. If set to true, it is up to the application - // to negotiate the channel and create an DataChannel with the same id - // at the other peer. - Negotiated *bool - - // ID overrides the default selection of ID for this channel. - ID *uint16 -} diff --git a/vendor/github.com/pion/webrtc/v3/datachannelmessage.go b/vendor/github.com/pion/webrtc/v3/datachannelmessage.go deleted file mode 100644 index ba12199f..00000000 --- a/vendor/github.com/pion/webrtc/v3/datachannelmessage.go +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// DataChannelMessage represents a message received from the -// data channel. IsString will be set to true if the incoming -// message is of the string type. Otherwise the message is of -// a binary type. -type DataChannelMessage struct { - IsString bool - Data []byte -} diff --git a/vendor/github.com/pion/webrtc/v3/datachannelparameters.go b/vendor/github.com/pion/webrtc/v3/datachannelparameters.go deleted file mode 100644 index 9b4f7efc..00000000 --- a/vendor/github.com/pion/webrtc/v3/datachannelparameters.go +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// DataChannelParameters describes the configuration of the DataChannel. -type DataChannelParameters struct { - Label string `json:"label"` - Protocol string `json:"protocol"` - ID *uint16 `json:"id"` - Ordered bool `json:"ordered"` - MaxPacketLifeTime *uint16 `json:"maxPacketLifeTime"` - MaxRetransmits *uint16 `json:"maxRetransmits"` - Negotiated bool `json:"negotiated"` -} diff --git a/vendor/github.com/pion/webrtc/v3/datachannelstate.go b/vendor/github.com/pion/webrtc/v3/datachannelstate.go deleted file mode 100644 index b2a85aae..00000000 --- a/vendor/github.com/pion/webrtc/v3/datachannelstate.go +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// DataChannelState indicates the state of a data channel. -type DataChannelState int - -const ( - // DataChannelStateConnecting indicates that the data channel is being - // established. This is the initial state of DataChannel, whether created - // with CreateDataChannel, or dispatched as a part of an DataChannelEvent. - DataChannelStateConnecting DataChannelState = iota + 1 - - // DataChannelStateOpen indicates that the underlying data transport is - // established and communication is possible. - DataChannelStateOpen - - // DataChannelStateClosing indicates that the procedure to close down the - // underlying data transport has started. - DataChannelStateClosing - - // DataChannelStateClosed indicates that the underlying data transport - // has been closed or could not be established. - DataChannelStateClosed -) - -// This is done this way because of a linter. -const ( - dataChannelStateConnectingStr = "connecting" - dataChannelStateOpenStr = "open" - dataChannelStateClosingStr = "closing" - dataChannelStateClosedStr = "closed" -) - -func newDataChannelState(raw string) DataChannelState { - switch raw { - case dataChannelStateConnectingStr: - return DataChannelStateConnecting - case dataChannelStateOpenStr: - return DataChannelStateOpen - case dataChannelStateClosingStr: - return DataChannelStateClosing - case dataChannelStateClosedStr: - return DataChannelStateClosed - default: - return DataChannelState(Unknown) - } -} - -func (t DataChannelState) String() string { - switch t { - case DataChannelStateConnecting: - return dataChannelStateConnectingStr - case DataChannelStateOpen: - return dataChannelStateOpenStr - case DataChannelStateClosing: - return dataChannelStateClosingStr - case DataChannelStateClosed: - return dataChannelStateClosedStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/dtlsfingerprint.go b/vendor/github.com/pion/webrtc/v3/dtlsfingerprint.go deleted file mode 100644 index b0d06148..00000000 --- a/vendor/github.com/pion/webrtc/v3/dtlsfingerprint.go +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// DTLSFingerprint specifies the hash function algorithm and certificate -// fingerprint as described in https://tools.ietf.org/html/rfc4572. -type DTLSFingerprint struct { - // Algorithm specifies one of the the hash function algorithms defined in - // the 'Hash function Textual Names' registry. - Algorithm string `json:"algorithm"` - - // Value specifies the value of the certificate fingerprint in lowercase - // hex string as expressed utilizing the syntax of 'fingerprint' in - // https://tools.ietf.org/html/rfc4572#section-5. - Value string `json:"value"` -} diff --git a/vendor/github.com/pion/webrtc/v3/dtlsparameters.go b/vendor/github.com/pion/webrtc/v3/dtlsparameters.go deleted file mode 100644 index 1dfa42a2..00000000 --- a/vendor/github.com/pion/webrtc/v3/dtlsparameters.go +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// DTLSParameters holds information relating to DTLS configuration. -type DTLSParameters struct { - Role DTLSRole `json:"role"` - Fingerprints []DTLSFingerprint `json:"fingerprints"` -} diff --git a/vendor/github.com/pion/webrtc/v3/dtlsrole.go b/vendor/github.com/pion/webrtc/v3/dtlsrole.go deleted file mode 100644 index 9cee581d..00000000 --- a/vendor/github.com/pion/webrtc/v3/dtlsrole.go +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "github.com/pion/sdp/v3" -) - -// DTLSRole indicates the role of the DTLS transport. -type DTLSRole byte - -const ( - // DTLSRoleAuto defines the DTLS role is determined based on - // the resolved ICE role: the ICE controlled role acts as the DTLS - // client and the ICE controlling role acts as the DTLS server. - DTLSRoleAuto DTLSRole = iota + 1 - - // DTLSRoleClient defines the DTLS client role. - DTLSRoleClient - - // DTLSRoleServer defines the DTLS server role. - DTLSRoleServer -) - -const ( - // https://tools.ietf.org/html/rfc5763 - /* - The answerer MUST use either a - setup attribute value of setup:active or setup:passive. Note that - if the answerer uses setup:passive, then the DTLS handshake will - not begin until the answerer is received, which adds additional - latency. setup:active allows the answer and the DTLS handshake to - occur in parallel. Thus, setup:active is RECOMMENDED. - */ - defaultDtlsRoleAnswer = DTLSRoleClient - /* - The endpoint that is the offerer MUST use the setup attribute - value of setup:actpass and be prepared to receive a client_hello - before it receives the answer. - */ - defaultDtlsRoleOffer = DTLSRoleAuto -) - -func (r DTLSRole) String() string { - switch r { - case DTLSRoleAuto: - return "auto" - case DTLSRoleClient: - return "client" - case DTLSRoleServer: - return "server" - default: - return unknownStr - } -} - -// Iterate a SessionDescription from a remote to determine if an explicit -// role can been determined from it. The decision is made from the first role we we parse. -// If no role can be found we return DTLSRoleAuto -func dtlsRoleFromRemoteSDP(sessionDescription *sdp.SessionDescription) DTLSRole { - if sessionDescription == nil { - return DTLSRoleAuto - } - - for _, mediaSection := range sessionDescription.MediaDescriptions { - for _, attribute := range mediaSection.Attributes { - if attribute.Key == "setup" { - switch attribute.Value { - case sdp.ConnectionRoleActive.String(): - return DTLSRoleClient - case sdp.ConnectionRolePassive.String(): - return DTLSRoleServer - default: - return DTLSRoleAuto - } - } - } - } - - return DTLSRoleAuto -} - -func connectionRoleFromDtlsRole(d DTLSRole) sdp.ConnectionRole { - switch d { - case DTLSRoleClient: - return sdp.ConnectionRoleActive - case DTLSRoleServer: - return sdp.ConnectionRolePassive - case DTLSRoleAuto: - return sdp.ConnectionRoleActpass - default: - return sdp.ConnectionRole(0) - } -} diff --git a/vendor/github.com/pion/webrtc/v3/dtlstransport.go b/vendor/github.com/pion/webrtc/v3/dtlstransport.go deleted file mode 100644 index df3472cf..00000000 --- a/vendor/github.com/pion/webrtc/v3/dtlstransport.go +++ /dev/null @@ -1,513 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/pion/dtls/v2" - "github.com/pion/dtls/v2/pkg/crypto/fingerprint" - "github.com/pion/interceptor" - "github.com/pion/logging" - "github.com/pion/rtcp" - "github.com/pion/srtp/v2" - "github.com/pion/webrtc/v3/internal/mux" - "github.com/pion/webrtc/v3/internal/util" - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -// DTLSTransport allows an application access to information about the DTLS -// transport over which RTP and RTCP packets are sent and received by -// RTPSender and RTPReceiver, as well other data such as SCTP packets sent -// and received by data channels. -type DTLSTransport struct { - lock sync.RWMutex - - iceTransport *ICETransport - certificates []Certificate - remoteParameters DTLSParameters - remoteCertificate []byte - state DTLSTransportState - srtpProtectionProfile srtp.ProtectionProfile - - onStateChangeHandler func(DTLSTransportState) - - conn *dtls.Conn - - srtpSession, srtcpSession atomic.Value - srtpEndpoint, srtcpEndpoint *mux.Endpoint - simulcastStreams []*srtp.ReadStreamSRTP - srtpReady chan struct{} - - dtlsMatcher mux.MatchFunc - - api *API - log logging.LeveledLogger -} - -// NewDTLSTransport creates a new DTLSTransport. -// This constructor is part of the ORTC API. It is not -// meant to be used together with the basic WebRTC API. -func (api *API) NewDTLSTransport(transport *ICETransport, certificates []Certificate) (*DTLSTransport, error) { - t := &DTLSTransport{ - iceTransport: transport, - api: api, - state: DTLSTransportStateNew, - dtlsMatcher: mux.MatchDTLS, - srtpReady: make(chan struct{}), - log: api.settingEngine.LoggerFactory.NewLogger("DTLSTransport"), - } - - if len(certificates) > 0 { - now := time.Now() - for _, x509Cert := range certificates { - if !x509Cert.Expires().IsZero() && now.After(x509Cert.Expires()) { - return nil, &rtcerr.InvalidAccessError{Err: ErrCertificateExpired} - } - t.certificates = append(t.certificates, x509Cert) - } - } else { - sk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, &rtcerr.UnknownError{Err: err} - } - certificate, err := GenerateCertificate(sk) - if err != nil { - return nil, err - } - t.certificates = []Certificate{*certificate} - } - - return t, nil -} - -// ICETransport returns the currently-configured *ICETransport or nil -// if one has not been configured -func (t *DTLSTransport) ICETransport() *ICETransport { - t.lock.RLock() - defer t.lock.RUnlock() - return t.iceTransport -} - -// onStateChange requires the caller holds the lock -func (t *DTLSTransport) onStateChange(state DTLSTransportState) { - t.state = state - handler := t.onStateChangeHandler - if handler != nil { - handler(state) - } -} - -// OnStateChange sets a handler that is fired when the DTLS -// connection state changes. -func (t *DTLSTransport) OnStateChange(f func(DTLSTransportState)) { - t.lock.Lock() - defer t.lock.Unlock() - t.onStateChangeHandler = f -} - -// State returns the current dtls transport state. -func (t *DTLSTransport) State() DTLSTransportState { - t.lock.RLock() - defer t.lock.RUnlock() - return t.state -} - -// WriteRTCP sends a user provided RTCP packet to the connected peer. If no peer is connected the -// packet is discarded. -func (t *DTLSTransport) WriteRTCP(pkts []rtcp.Packet) (int, error) { - raw, err := rtcp.Marshal(pkts) - if err != nil { - return 0, err - } - - srtcpSession, err := t.getSRTCPSession() - if err != nil { - return 0, err - } - - writeStream, err := srtcpSession.OpenWriteStream() - if err != nil { - // nolint - return 0, fmt.Errorf("%w: %v", errPeerConnWriteRTCPOpenWriteStream, err) - } - - return writeStream.Write(raw) -} - -// GetLocalParameters returns the DTLS parameters of the local DTLSTransport upon construction. -func (t *DTLSTransport) GetLocalParameters() (DTLSParameters, error) { - fingerprints := []DTLSFingerprint{} - - for _, c := range t.certificates { - prints, err := c.GetFingerprints() - if err != nil { - return DTLSParameters{}, err - } - - fingerprints = append(fingerprints, prints...) - } - - return DTLSParameters{ - Role: DTLSRoleAuto, // always returns the default role - Fingerprints: fingerprints, - }, nil -} - -// GetRemoteCertificate returns the certificate chain in use by the remote side -// returns an empty list prior to selection of the remote certificate -func (t *DTLSTransport) GetRemoteCertificate() []byte { - t.lock.RLock() - defer t.lock.RUnlock() - return t.remoteCertificate -} - -func (t *DTLSTransport) startSRTP() error { - srtpConfig := &srtp.Config{ - Profile: t.srtpProtectionProfile, - BufferFactory: t.api.settingEngine.BufferFactory, - LoggerFactory: t.api.settingEngine.LoggerFactory, - } - if t.api.settingEngine.replayProtection.SRTP != nil { - srtpConfig.RemoteOptions = append( - srtpConfig.RemoteOptions, - srtp.SRTPReplayProtection(*t.api.settingEngine.replayProtection.SRTP), - ) - } - - if t.api.settingEngine.disableSRTPReplayProtection { - srtpConfig.RemoteOptions = append( - srtpConfig.RemoteOptions, - srtp.SRTPNoReplayProtection(), - ) - } - - if t.api.settingEngine.replayProtection.SRTCP != nil { - srtpConfig.RemoteOptions = append( - srtpConfig.RemoteOptions, - srtp.SRTCPReplayProtection(*t.api.settingEngine.replayProtection.SRTCP), - ) - } - - if t.api.settingEngine.disableSRTCPReplayProtection { - srtpConfig.RemoteOptions = append( - srtpConfig.RemoteOptions, - srtp.SRTCPNoReplayProtection(), - ) - } - - connState := t.conn.ConnectionState() - err := srtpConfig.ExtractSessionKeysFromDTLS(&connState, t.role() == DTLSRoleClient) - if err != nil { - // nolint - return fmt.Errorf("%w: %v", errDtlsKeyExtractionFailed, err) - } - - srtpSession, err := srtp.NewSessionSRTP(t.srtpEndpoint, srtpConfig) - if err != nil { - // nolint - return fmt.Errorf("%w: %v", errFailedToStartSRTP, err) - } - - srtcpSession, err := srtp.NewSessionSRTCP(t.srtcpEndpoint, srtpConfig) - if err != nil { - // nolint - return fmt.Errorf("%w: %v", errFailedToStartSRTCP, err) - } - - t.srtpSession.Store(srtpSession) - t.srtcpSession.Store(srtcpSession) - close(t.srtpReady) - return nil -} - -func (t *DTLSTransport) getSRTPSession() (*srtp.SessionSRTP, error) { - if value, ok := t.srtpSession.Load().(*srtp.SessionSRTP); ok { - return value, nil - } - - return nil, errDtlsTransportNotStarted -} - -func (t *DTLSTransport) getSRTCPSession() (*srtp.SessionSRTCP, error) { - if value, ok := t.srtcpSession.Load().(*srtp.SessionSRTCP); ok { - return value, nil - } - - return nil, errDtlsTransportNotStarted -} - -func (t *DTLSTransport) role() DTLSRole { - // If remote has an explicit role use the inverse - switch t.remoteParameters.Role { - case DTLSRoleClient: - return DTLSRoleServer - case DTLSRoleServer: - return DTLSRoleClient - default: - } - - // If SettingEngine has an explicit role - switch t.api.settingEngine.answeringDTLSRole { - case DTLSRoleServer: - return DTLSRoleServer - case DTLSRoleClient: - return DTLSRoleClient - default: - } - - // Remote was auto and no explicit role was configured via SettingEngine - if t.iceTransport.Role() == ICERoleControlling { - return DTLSRoleServer - } - return defaultDtlsRoleAnswer -} - -// Start DTLS transport negotiation with the parameters of the remote DTLS transport -func (t *DTLSTransport) Start(remoteParameters DTLSParameters) error { - // Take lock and prepare connection, we must not hold the lock - // when connecting - prepareTransport := func() (DTLSRole, *dtls.Config, error) { - t.lock.Lock() - defer t.lock.Unlock() - - if err := t.ensureICEConn(); err != nil { - return DTLSRole(0), nil, err - } - - if t.state != DTLSTransportStateNew { - return DTLSRole(0), nil, &rtcerr.InvalidStateError{Err: fmt.Errorf("%w: %s", errInvalidDTLSStart, t.state)} - } - - t.srtpEndpoint = t.iceTransport.newEndpoint(mux.MatchSRTP) - t.srtcpEndpoint = t.iceTransport.newEndpoint(mux.MatchSRTCP) - t.remoteParameters = remoteParameters - - cert := t.certificates[0] - t.onStateChange(DTLSTransportStateConnecting) - - return t.role(), &dtls.Config{ - Certificates: []tls.Certificate{ - { - Certificate: [][]byte{cert.x509Cert.Raw}, - PrivateKey: cert.privateKey, - }, - }, - SRTPProtectionProfiles: func() []dtls.SRTPProtectionProfile { - if len(t.api.settingEngine.srtpProtectionProfiles) > 0 { - return t.api.settingEngine.srtpProtectionProfiles - } - - return defaultSrtpProtectionProfiles() - }(), - ClientAuth: dtls.RequireAnyClientCert, - LoggerFactory: t.api.settingEngine.LoggerFactory, - InsecureSkipVerify: !t.api.settingEngine.dtls.disableInsecureSkipVerify, - }, nil - } - - var dtlsConn *dtls.Conn - dtlsEndpoint := t.iceTransport.newEndpoint(mux.MatchDTLS) - role, dtlsConfig, err := prepareTransport() - if err != nil { - return err - } - - if t.api.settingEngine.replayProtection.DTLS != nil { - dtlsConfig.ReplayProtectionWindow = int(*t.api.settingEngine.replayProtection.DTLS) - } - - if t.api.settingEngine.dtls.clientAuth != nil { - dtlsConfig.ClientAuth = *t.api.settingEngine.dtls.clientAuth - } - - dtlsConfig.FlightInterval = t.api.settingEngine.dtls.retransmissionInterval - dtlsConfig.InsecureSkipVerifyHello = t.api.settingEngine.dtls.insecureSkipHelloVerify - dtlsConfig.EllipticCurves = t.api.settingEngine.dtls.ellipticCurves - dtlsConfig.ConnectContextMaker = t.api.settingEngine.dtls.connectContextMaker - dtlsConfig.ExtendedMasterSecret = t.api.settingEngine.dtls.extendedMasterSecret - dtlsConfig.ClientCAs = t.api.settingEngine.dtls.clientCAs - dtlsConfig.RootCAs = t.api.settingEngine.dtls.rootCAs - - // Connect as DTLS Client/Server, function is blocking and we - // must not hold the DTLSTransport lock - if role == DTLSRoleClient { - dtlsConn, err = dtls.Client(dtlsEndpoint, dtlsConfig) - } else { - dtlsConn, err = dtls.Server(dtlsEndpoint, dtlsConfig) - } - - // Re-take the lock, nothing beyond here is blocking - t.lock.Lock() - defer t.lock.Unlock() - - if err != nil { - t.onStateChange(DTLSTransportStateFailed) - return err - } - - srtpProfile, ok := dtlsConn.SelectedSRTPProtectionProfile() - if !ok { - t.onStateChange(DTLSTransportStateFailed) - return ErrNoSRTPProtectionProfile - } - - switch srtpProfile { - case dtls.SRTP_AEAD_AES_128_GCM: - t.srtpProtectionProfile = srtp.ProtectionProfileAeadAes128Gcm - case dtls.SRTP_AEAD_AES_256_GCM: - t.srtpProtectionProfile = srtp.ProtectionProfileAeadAes256Gcm - case dtls.SRTP_AES128_CM_HMAC_SHA1_80: - t.srtpProtectionProfile = srtp.ProtectionProfileAes128CmHmacSha1_80 - default: - t.onStateChange(DTLSTransportStateFailed) - return ErrNoSRTPProtectionProfile - } - - // Check the fingerprint if a certificate was exchanged - remoteCerts := dtlsConn.ConnectionState().PeerCertificates - if len(remoteCerts) == 0 { - t.onStateChange(DTLSTransportStateFailed) - return errNoRemoteCertificate - } - t.remoteCertificate = remoteCerts[0] - - if !t.api.settingEngine.disableCertificateFingerprintVerification { - parsedRemoteCert, err := x509.ParseCertificate(t.remoteCertificate) - if err != nil { - if closeErr := dtlsConn.Close(); closeErr != nil { - t.log.Error(err.Error()) - } - - t.onStateChange(DTLSTransportStateFailed) - return err - } - - if err = t.validateFingerPrint(parsedRemoteCert); err != nil { - if closeErr := dtlsConn.Close(); closeErr != nil { - t.log.Error(err.Error()) - } - - t.onStateChange(DTLSTransportStateFailed) - return err - } - } - - t.conn = dtlsConn - t.onStateChange(DTLSTransportStateConnected) - - return t.startSRTP() -} - -// Stop stops and closes the DTLSTransport object. -func (t *DTLSTransport) Stop() error { - t.lock.Lock() - defer t.lock.Unlock() - - // Try closing everything and collect the errors - var closeErrs []error - - if srtpSession, err := t.getSRTPSession(); err == nil && srtpSession != nil { - closeErrs = append(closeErrs, srtpSession.Close()) - } - - if srtcpSession, err := t.getSRTCPSession(); err == nil && srtcpSession != nil { - closeErrs = append(closeErrs, srtcpSession.Close()) - } - - for i := range t.simulcastStreams { - closeErrs = append(closeErrs, t.simulcastStreams[i].Close()) - } - - if t.conn != nil { - // dtls connection may be closed on sctp close. - if err := t.conn.Close(); err != nil && !errors.Is(err, dtls.ErrConnClosed) { - closeErrs = append(closeErrs, err) - } - } - t.onStateChange(DTLSTransportStateClosed) - return util.FlattenErrs(closeErrs) -} - -func (t *DTLSTransport) validateFingerPrint(remoteCert *x509.Certificate) error { - for _, fp := range t.remoteParameters.Fingerprints { - hashAlgo, err := fingerprint.HashFromString(fp.Algorithm) - if err != nil { - return err - } - - remoteValue, err := fingerprint.Fingerprint(remoteCert, hashAlgo) - if err != nil { - return err - } - - if strings.EqualFold(remoteValue, fp.Value) { - return nil - } - } - - return errNoMatchingCertificateFingerprint -} - -func (t *DTLSTransport) ensureICEConn() error { - if t.iceTransport == nil { - return errICEConnectionNotStarted - } - - return nil -} - -func (t *DTLSTransport) storeSimulcastStream(s *srtp.ReadStreamSRTP) { - t.lock.Lock() - defer t.lock.Unlock() - - t.simulcastStreams = append(t.simulcastStreams, s) -} - -func (t *DTLSTransport) streamsForSSRC(ssrc SSRC, streamInfo interceptor.StreamInfo) (*srtp.ReadStreamSRTP, interceptor.RTPReader, *srtp.ReadStreamSRTCP, interceptor.RTCPReader, error) { - srtpSession, err := t.getSRTPSession() - if err != nil { - return nil, nil, nil, nil, err - } - - rtpReadStream, err := srtpSession.OpenReadStream(uint32(ssrc)) - if err != nil { - return nil, nil, nil, nil, err - } - - rtpInterceptor := t.api.interceptor.BindRemoteStream(&streamInfo, interceptor.RTPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) { - n, err = rtpReadStream.Read(in) - return n, a, err - })) - - srtcpSession, err := t.getSRTCPSession() - if err != nil { - return nil, nil, nil, nil, err - } - - rtcpReadStream, err := srtcpSession.OpenReadStream(uint32(ssrc)) - if err != nil { - return nil, nil, nil, nil, err - } - - rtcpInterceptor := t.api.interceptor.BindRTCPReader(interceptor.RTPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) { - n, err = rtcpReadStream.Read(in) - return n, a, err - })) - - return rtpReadStream, rtpInterceptor, rtcpReadStream, rtcpInterceptor, nil -} diff --git a/vendor/github.com/pion/webrtc/v3/dtlstransport_js.go b/vendor/github.com/pion/webrtc/v3/dtlstransport_js.go deleted file mode 100644 index bc3444e5..00000000 --- a/vendor/github.com/pion/webrtc/v3/dtlstransport_js.go +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import "syscall/js" - -// DTLSTransport allows an application access to information about the DTLS -// transport over which RTP and RTCP packets are sent and received by -// RTPSender and RTPReceiver, as well other data such as SCTP packets sent -// and received by data channels. -type DTLSTransport struct { - // Pointer to the underlying JavaScript DTLSTransport object. - underlying js.Value -} - -// ICETransport returns the currently-configured *ICETransport or nil -// if one has not been configured -func (r *DTLSTransport) ICETransport() *ICETransport { - underlying := r.underlying.Get("iceTransport") - if underlying.IsNull() || underlying.IsUndefined() { - return nil - } - - return &ICETransport{ - underlying: underlying, - } -} diff --git a/vendor/github.com/pion/webrtc/v3/dtlstransportstate.go b/vendor/github.com/pion/webrtc/v3/dtlstransportstate.go deleted file mode 100644 index f986e22c..00000000 --- a/vendor/github.com/pion/webrtc/v3/dtlstransportstate.go +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// DTLSTransportState indicates the DTLS transport establishment state. -type DTLSTransportState int - -const ( - // DTLSTransportStateNew indicates that DTLS has not started negotiating - // yet. - DTLSTransportStateNew DTLSTransportState = iota + 1 - - // DTLSTransportStateConnecting indicates that DTLS is in the process of - // negotiating a secure connection and verifying the remote fingerprint. - DTLSTransportStateConnecting - - // DTLSTransportStateConnected indicates that DTLS has completed - // negotiation of a secure connection and verified the remote fingerprint. - DTLSTransportStateConnected - - // DTLSTransportStateClosed indicates that the transport has been closed - // intentionally as the result of receipt of a close_notify alert, or - // calling close(). - DTLSTransportStateClosed - - // DTLSTransportStateFailed indicates that the transport has failed as - // the result of an error (such as receipt of an error alert or failure to - // validate the remote fingerprint). - DTLSTransportStateFailed -) - -// This is done this way because of a linter. -const ( - dtlsTransportStateNewStr = "new" - dtlsTransportStateConnectingStr = "connecting" - dtlsTransportStateConnectedStr = "connected" - dtlsTransportStateClosedStr = "closed" - dtlsTransportStateFailedStr = "failed" -) - -func newDTLSTransportState(raw string) DTLSTransportState { - switch raw { - case dtlsTransportStateNewStr: - return DTLSTransportStateNew - case dtlsTransportStateConnectingStr: - return DTLSTransportStateConnecting - case dtlsTransportStateConnectedStr: - return DTLSTransportStateConnected - case dtlsTransportStateClosedStr: - return DTLSTransportStateClosed - case dtlsTransportStateFailedStr: - return DTLSTransportStateFailed - default: - return DTLSTransportState(Unknown) - } -} - -func (t DTLSTransportState) String() string { - switch t { - case DTLSTransportStateNew: - return dtlsTransportStateNewStr - case DTLSTransportStateConnecting: - return dtlsTransportStateConnectingStr - case DTLSTransportStateConnected: - return dtlsTransportStateConnectedStr - case DTLSTransportStateClosed: - return dtlsTransportStateClosedStr - case DTLSTransportStateFailed: - return dtlsTransportStateFailedStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/errors.go b/vendor/github.com/pion/webrtc/v3/errors.go deleted file mode 100644 index 009e91dd..00000000 --- a/vendor/github.com/pion/webrtc/v3/errors.go +++ /dev/null @@ -1,249 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "errors" -) - -var ( - // ErrUnknownType indicates an error with Unknown info. - ErrUnknownType = errors.New("unknown") - - // ErrConnectionClosed indicates an operation executed after connection - // has already been closed. - ErrConnectionClosed = errors.New("connection closed") - - // ErrDataChannelNotOpen indicates an operation executed when the data - // channel is not (yet) open. - ErrDataChannelNotOpen = errors.New("data channel not open") - - // ErrCertificateExpired indicates that an x509 certificate has expired. - ErrCertificateExpired = errors.New("x509Cert expired") - - // ErrNoTurnCredentials indicates that a TURN server URL was provided - // without required credentials. - ErrNoTurnCredentials = errors.New("turn server credentials required") - - // ErrTurnCredentials indicates that provided TURN credentials are partial - // or malformed. - ErrTurnCredentials = errors.New("invalid turn server credentials") - - // ErrExistingTrack indicates that a track already exists. - ErrExistingTrack = errors.New("track already exists") - - // ErrPrivateKeyType indicates that a particular private key encryption - // chosen to generate a certificate is not supported. - ErrPrivateKeyType = errors.New("private key type not supported") - - // ErrModifyingPeerIdentity indicates that an attempt to modify - // PeerIdentity was made after PeerConnection has been initialized. - ErrModifyingPeerIdentity = errors.New("peerIdentity cannot be modified") - - // ErrModifyingCertificates indicates that an attempt to modify - // Certificates was made after PeerConnection has been initialized. - ErrModifyingCertificates = errors.New("certificates cannot be modified") - - // ErrModifyingBundlePolicy indicates that an attempt to modify - // BundlePolicy was made after PeerConnection has been initialized. - ErrModifyingBundlePolicy = errors.New("bundle policy cannot be modified") - - // ErrModifyingRTCPMuxPolicy indicates that an attempt to modify - // RTCPMuxPolicy was made after PeerConnection has been initialized. - ErrModifyingRTCPMuxPolicy = errors.New("rtcp mux policy cannot be modified") - - // ErrModifyingICECandidatePoolSize indicates that an attempt to modify - // ICECandidatePoolSize was made after PeerConnection has been initialized. - ErrModifyingICECandidatePoolSize = errors.New("ice candidate pool size cannot be modified") - - // ErrStringSizeLimit indicates that the character size limit of string is - // exceeded. The limit is hardcoded to 65535 according to specifications. - ErrStringSizeLimit = errors.New("data channel label exceeds size limit") - - // ErrMaxDataChannelID indicates that the maximum number ID that could be - // specified for a data channel has been exceeded. - ErrMaxDataChannelID = errors.New("maximum number ID for datachannel specified") - - // ErrNegotiatedWithoutID indicates that an attempt to create a data channel - // was made while setting the negotiated option to true without providing - // the negotiated channel ID. - ErrNegotiatedWithoutID = errors.New("negotiated set without channel id") - - // ErrRetransmitsOrPacketLifeTime indicates that an attempt to create a data - // channel was made with both options MaxPacketLifeTime and MaxRetransmits - // set together. Such configuration is not supported by the specification - // and is mutually exclusive. - ErrRetransmitsOrPacketLifeTime = errors.New("both MaxPacketLifeTime and MaxRetransmits was set") - - // ErrCodecNotFound is returned when a codec search to the Media Engine fails - ErrCodecNotFound = errors.New("codec not found") - - // ErrNoRemoteDescription indicates that an operation was rejected because - // the remote description is not set - ErrNoRemoteDescription = errors.New("remote description is not set") - - // ErrIncorrectSDPSemantics indicates that the PeerConnection was configured to - // generate SDP Answers with different SDP Semantics than the received Offer - ErrIncorrectSDPSemantics = errors.New("remote SessionDescription semantics does not match configuration") - - // ErrIncorrectSignalingState indicates that the signaling state of PeerConnection is not correct - ErrIncorrectSignalingState = errors.New("operation can not be run in current signaling state") - - // ErrProtocolTooLarge indicates that value given for a DataChannelInit protocol is - // longer then 65535 bytes - ErrProtocolTooLarge = errors.New("protocol is larger then 65535 bytes") - - // ErrSenderNotCreatedByConnection indicates RemoveTrack was called with a RtpSender not created - // by this PeerConnection - ErrSenderNotCreatedByConnection = errors.New("RtpSender not created by this PeerConnection") - - // ErrSessionDescriptionNoFingerprint indicates SetRemoteDescription was called with a SessionDescription that has no - // fingerprint - ErrSessionDescriptionNoFingerprint = errors.New("SetRemoteDescription called with no fingerprint") - - // ErrSessionDescriptionInvalidFingerprint indicates SetRemoteDescription was called with a SessionDescription that - // has an invalid fingerprint - ErrSessionDescriptionInvalidFingerprint = errors.New("SetRemoteDescription called with an invalid fingerprint") - - // ErrSessionDescriptionConflictingFingerprints indicates SetRemoteDescription was called with a SessionDescription that - // has an conflicting fingerprints - ErrSessionDescriptionConflictingFingerprints = errors.New("SetRemoteDescription called with multiple conflicting fingerprint") - - // ErrSessionDescriptionMissingIceUfrag indicates SetRemoteDescription was called with a SessionDescription that - // is missing an ice-ufrag value - ErrSessionDescriptionMissingIceUfrag = errors.New("SetRemoteDescription called with no ice-ufrag") - - // ErrSessionDescriptionMissingIcePwd indicates SetRemoteDescription was called with a SessionDescription that - // is missing an ice-pwd value - ErrSessionDescriptionMissingIcePwd = errors.New("SetRemoteDescription called with no ice-pwd") - - // ErrSessionDescriptionConflictingIceUfrag indicates SetRemoteDescription was called with a SessionDescription that - // contains multiple conflicting ice-ufrag values - ErrSessionDescriptionConflictingIceUfrag = errors.New("SetRemoteDescription called with multiple conflicting ice-ufrag values") - - // ErrSessionDescriptionConflictingIcePwd indicates SetRemoteDescription was called with a SessionDescription that - // contains multiple conflicting ice-pwd values - ErrSessionDescriptionConflictingIcePwd = errors.New("SetRemoteDescription called with multiple conflicting ice-pwd values") - - // ErrNoSRTPProtectionProfile indicates that the DTLS handshake completed and no SRTP Protection Profile was chosen - ErrNoSRTPProtectionProfile = errors.New("DTLS Handshake completed and no SRTP Protection Profile was chosen") - - // ErrFailedToGenerateCertificateFingerprint indicates that we failed to generate the fingerprint used for comparing certificates - ErrFailedToGenerateCertificateFingerprint = errors.New("failed to generate certificate fingerprint") - - // ErrNoCodecsAvailable indicates that operation isn't possible because the MediaEngine has no codecs available - ErrNoCodecsAvailable = errors.New("operation failed no codecs are available") - - // ErrUnsupportedCodec indicates the remote peer doesn't support the requested codec - ErrUnsupportedCodec = errors.New("unable to start track, codec is not supported by remote") - - // ErrSenderWithNoCodecs indicates that a RTPSender was created without any codecs. To send media the MediaEngine needs at - // least one configured codec. - ErrSenderWithNoCodecs = errors.New("unable to populate media section, RTPSender created with no codecs") - - // ErrRTPSenderNewTrackHasIncorrectKind indicates that the new track is of a different kind than the previous/original - ErrRTPSenderNewTrackHasIncorrectKind = errors.New("new track must be of the same kind as previous") - - // ErrRTPSenderNewTrackHasIncorrectEnvelope indicates that the new track has a different envelope than the previous/original - ErrRTPSenderNewTrackHasIncorrectEnvelope = errors.New("new track must have the same envelope as previous") - - // ErrUnbindFailed indicates that a TrackLocal was not able to be unbind - ErrUnbindFailed = errors.New("failed to unbind TrackLocal from PeerConnection") - - // ErrNoPayloaderForCodec indicates that the requested codec does not have a payloader - ErrNoPayloaderForCodec = errors.New("the requested codec does not have a payloader") - - // ErrRegisterHeaderExtensionInvalidDirection indicates that a extension was registered with a direction besides `sendonly` or `recvonly` - ErrRegisterHeaderExtensionInvalidDirection = errors.New("a header extension must be registered as 'recvonly', 'sendonly' or both") - - // ErrSimulcastProbeOverflow indicates that too many Simulcast probe streams are in flight and the requested SSRC was ignored - ErrSimulcastProbeOverflow = errors.New("simulcast probe limit has been reached, new SSRC has been discarded") - - errDetachNotEnabled = errors.New("enable detaching by calling webrtc.DetachDataChannels()") - errDetachBeforeOpened = errors.New("datachannel not opened yet, try calling Detach from OnOpen") - errDtlsTransportNotStarted = errors.New("the DTLS transport has not started yet") - errDtlsKeyExtractionFailed = errors.New("failed extracting keys from DTLS for SRTP") - errFailedToStartSRTP = errors.New("failed to start SRTP") - errFailedToStartSRTCP = errors.New("failed to start SRTCP") - errInvalidDTLSStart = errors.New("attempted to start DTLSTransport that is not in new state") - errNoRemoteCertificate = errors.New("peer didn't provide certificate via DTLS") - errIdentityProviderNotImplemented = errors.New("identity provider is not implemented") - errNoMatchingCertificateFingerprint = errors.New("remote certificate does not match any fingerprint") - - errICEConnectionNotStarted = errors.New("ICE connection not started") - errICECandidateTypeUnknown = errors.New("unknown candidate type") - errICEInvalidConvertCandidateType = errors.New("cannot convert ice.CandidateType into webrtc.ICECandidateType, invalid type") - errICEAgentNotExist = errors.New("ICEAgent does not exist") - errICECandiatesCoversionFailed = errors.New("unable to convert ICE candidates to ICECandidates") - errICERoleUnknown = errors.New("unknown ICE Role") - errICEProtocolUnknown = errors.New("unknown protocol") - errICEGathererNotStarted = errors.New("gatherer not started") - - errNetworkTypeUnknown = errors.New("unknown network type") - - errSDPDoesNotMatchOffer = errors.New("new sdp does not match previous offer") - errSDPDoesNotMatchAnswer = errors.New("new sdp does not match previous answer") - errPeerConnSDPTypeInvalidValue = errors.New("provided value is not a valid enum value of type SDPType") - errPeerConnStateChangeInvalid = errors.New("invalid state change op") - errPeerConnStateChangeUnhandled = errors.New("unhandled state change op") - errPeerConnSDPTypeInvalidValueSetLocalDescription = errors.New("invalid SDP type supplied to SetLocalDescription()") - errPeerConnRemoteDescriptionWithoutMidValue = errors.New("remoteDescription contained media section without mid value") - errPeerConnRemoteDescriptionNil = errors.New("remoteDescription has not been set yet") - errPeerConnSingleMediaSectionHasExplicitSSRC = errors.New("single media section has an explicit SSRC") - errPeerConnRemoteSSRCAddTransceiver = errors.New("could not add transceiver for remote SSRC") - errPeerConnSimulcastMidRTPExtensionRequired = errors.New("mid RTP Extensions required for Simulcast") - errPeerConnSimulcastStreamIDRTPExtensionRequired = errors.New("stream id RTP Extensions required for Simulcast") - errPeerConnSimulcastIncomingSSRCFailed = errors.New("incoming SSRC failed Simulcast probing") - errPeerConnAddTransceiverFromKindOnlyAcceptsOne = errors.New("AddTransceiverFromKind only accepts one RTPTransceiverInit") - errPeerConnAddTransceiverFromTrackOnlyAcceptsOne = errors.New("AddTransceiverFromTrack only accepts one RTPTransceiverInit") - errPeerConnAddTransceiverFromKindSupport = errors.New("AddTransceiverFromKind currently only supports recvonly") - errPeerConnAddTransceiverFromTrackSupport = errors.New("AddTransceiverFromTrack currently only supports sendonly and sendrecv") - errPeerConnSetIdentityProviderNotImplemented = errors.New("TODO SetIdentityProvider") - errPeerConnWriteRTCPOpenWriteStream = errors.New("WriteRTCP failed to open WriteStream") - errPeerConnTranscieverMidNil = errors.New("cannot find transceiver with mid") - - errRTPReceiverDTLSTransportNil = errors.New("DTLSTransport must not be nil") - errRTPReceiverReceiveAlreadyCalled = errors.New("Receive has already been called") - errRTPReceiverWithSSRCTrackStreamNotFound = errors.New("unable to find stream for Track with SSRC") - errRTPReceiverForRIDTrackStreamNotFound = errors.New("no trackStreams found for RID") - - errRTPSenderTrackNil = errors.New("Track must not be nil") - errRTPSenderDTLSTransportNil = errors.New("DTLSTransport must not be nil") - errRTPSenderSendAlreadyCalled = errors.New("Send has already been called") - errRTPSenderStopped = errors.New("Sender has already been stopped") - errRTPSenderTrackRemoved = errors.New("Sender Track has been removed or replaced to nil") - errRTPSenderRidNil = errors.New("Sender cannot add encoding as rid is empty") - errRTPSenderNoBaseEncoding = errors.New("Sender cannot add encoding as there is no base track") - errRTPSenderBaseEncodingMismatch = errors.New("Sender cannot add encoding as provided track does not match base track") - errRTPSenderRIDCollision = errors.New("Sender cannot encoding due to RID collision") - errRTPSenderNoTrackForRID = errors.New("Sender does not have track for RID") - - errRTPTransceiverCannotChangeMid = errors.New("errRTPSenderTrackNil") - errRTPTransceiverSetSendingInvalidState = errors.New("invalid state change in RTPTransceiver.setSending") - errRTPTransceiverCodecUnsupported = errors.New("unsupported codec type by this transceiver") - - errSCTPTransportDTLS = errors.New("DTLS not established") - - errSDPZeroTransceivers = errors.New("addTransceiverSDP() called with 0 transceivers") - errSDPMediaSectionMediaDataChanInvalid = errors.New("invalid Media Section. Media + DataChannel both enabled") - errSDPMediaSectionMultipleTrackInvalid = errors.New("invalid Media Section. Can not have multiple tracks in one MediaSection in UnifiedPlan") - - errSettingEngineSetAnsweringDTLSRole = errors.New("SetAnsweringDTLSRole must DTLSRoleClient or DTLSRoleServer") - - errSignalingStateCannotRollback = errors.New("can't rollback from stable state") - errSignalingStateProposedTransitionInvalid = errors.New("invalid proposed signaling state transition") - - errStatsICECandidateStateInvalid = errors.New("cannot convert to StatsICECandidatePairStateSucceeded invalid ice candidate state") - - errInvalidICECredentialTypeString = errors.New("invalid ICECredentialType") - errInvalidICEServer = errors.New("invalid ICEServer") - - errICETransportNotInNew = errors.New("ICETransport can only be called in ICETransportStateNew") - - errCertificatePEMFormatError = errors.New("bad Certificate PEM format") - - errRTPTooShort = errors.New("not long enough to be a RTP Packet") - - errExcessiveRetries = errors.New("excessive retries in CreateOffer") -) diff --git a/vendor/github.com/pion/webrtc/v3/gathering_complete_promise.go b/vendor/github.com/pion/webrtc/v3/gathering_complete_promise.go deleted file mode 100644 index 12d3170d..00000000 --- a/vendor/github.com/pion/webrtc/v3/gathering_complete_promise.go +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "context" -) - -// GatheringCompletePromise is a Pion specific helper function that returns a channel that is closed when gathering is complete. -// This function may be helpful in cases where you are unable to trickle your ICE Candidates. -// -// It is better to not use this function, and instead trickle candidates. If you use this function you will see longer connection startup times. -// When the call is connected you will see no impact however. -func GatheringCompletePromise(pc *PeerConnection) (gatherComplete <-chan struct{}) { - gatheringComplete, done := context.WithCancel(context.Background()) - - // It's possible to miss the GatherComplete event since setGatherCompleteHandler is an atomic operation and the - // promise might have been created after the gathering is finished. Therefore, we need to check if the ICE gathering - // state has changed to complete so that we don't block the caller forever. - pc.setGatherCompleteHandler(func() { done() }) - if pc.ICEGatheringState() == ICEGatheringStateComplete { - done() - } - - return gatheringComplete.Done() -} diff --git a/vendor/github.com/pion/webrtc/v3/ice_go.go b/vendor/github.com/pion/webrtc/v3/ice_go.go deleted file mode 100644 index 9adcefbb..00000000 --- a/vendor/github.com/pion/webrtc/v3/ice_go.go +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -// NewICETransport creates a new NewICETransport. -// This constructor is part of the ORTC API. It is not -// meant to be used together with the basic WebRTC API. -func (api *API) NewICETransport(gatherer *ICEGatherer) *ICETransport { - return NewICETransport(gatherer, api.settingEngine.LoggerFactory) -} diff --git a/vendor/github.com/pion/webrtc/v3/icecandidate.go b/vendor/github.com/pion/webrtc/v3/icecandidate.go deleted file mode 100644 index fa0b6809..00000000 --- a/vendor/github.com/pion/webrtc/v3/icecandidate.go +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "fmt" - - "github.com/pion/ice/v2" -) - -// ICECandidate represents a ice candidate -type ICECandidate struct { - statsID string - Foundation string `json:"foundation"` - Priority uint32 `json:"priority"` - Address string `json:"address"` - Protocol ICEProtocol `json:"protocol"` - Port uint16 `json:"port"` - Typ ICECandidateType `json:"type"` - Component uint16 `json:"component"` - RelatedAddress string `json:"relatedAddress"` - RelatedPort uint16 `json:"relatedPort"` - TCPType string `json:"tcpType"` -} - -// Conversion for package ice - -func newICECandidatesFromICE(iceCandidates []ice.Candidate) ([]ICECandidate, error) { - candidates := []ICECandidate{} - - for _, i := range iceCandidates { - c, err := newICECandidateFromICE(i) - if err != nil { - return nil, err - } - candidates = append(candidates, c) - } - - return candidates, nil -} - -func newICECandidateFromICE(i ice.Candidate) (ICECandidate, error) { - typ, err := convertTypeFromICE(i.Type()) - if err != nil { - return ICECandidate{}, err - } - protocol, err := NewICEProtocol(i.NetworkType().NetworkShort()) - if err != nil { - return ICECandidate{}, err - } - - c := ICECandidate{ - statsID: i.ID(), - Foundation: i.Foundation(), - Priority: i.Priority(), - Address: i.Address(), - Protocol: protocol, - Port: uint16(i.Port()), - Component: i.Component(), - Typ: typ, - TCPType: i.TCPType().String(), - } - - if i.RelatedAddress() != nil { - c.RelatedAddress = i.RelatedAddress().Address - c.RelatedPort = uint16(i.RelatedAddress().Port) - } - - return c, nil -} - -func (c ICECandidate) toICE() (ice.Candidate, error) { - candidateID := c.statsID - switch c.Typ { - case ICECandidateTypeHost: - config := ice.CandidateHostConfig{ - CandidateID: candidateID, - Network: c.Protocol.String(), - Address: c.Address, - Port: int(c.Port), - Component: c.Component, - TCPType: ice.NewTCPType(c.TCPType), - Foundation: c.Foundation, - Priority: c.Priority, - } - return ice.NewCandidateHost(&config) - case ICECandidateTypeSrflx: - config := ice.CandidateServerReflexiveConfig{ - CandidateID: candidateID, - Network: c.Protocol.String(), - Address: c.Address, - Port: int(c.Port), - Component: c.Component, - Foundation: c.Foundation, - Priority: c.Priority, - RelAddr: c.RelatedAddress, - RelPort: int(c.RelatedPort), - } - return ice.NewCandidateServerReflexive(&config) - case ICECandidateTypePrflx: - config := ice.CandidatePeerReflexiveConfig{ - CandidateID: candidateID, - Network: c.Protocol.String(), - Address: c.Address, - Port: int(c.Port), - Component: c.Component, - Foundation: c.Foundation, - Priority: c.Priority, - RelAddr: c.RelatedAddress, - RelPort: int(c.RelatedPort), - } - return ice.NewCandidatePeerReflexive(&config) - case ICECandidateTypeRelay: - config := ice.CandidateRelayConfig{ - CandidateID: candidateID, - Network: c.Protocol.String(), - Address: c.Address, - Port: int(c.Port), - Component: c.Component, - Foundation: c.Foundation, - Priority: c.Priority, - RelAddr: c.RelatedAddress, - RelPort: int(c.RelatedPort), - } - return ice.NewCandidateRelay(&config) - default: - return nil, fmt.Errorf("%w: %s", errICECandidateTypeUnknown, c.Typ) - } -} - -func convertTypeFromICE(t ice.CandidateType) (ICECandidateType, error) { - switch t { - case ice.CandidateTypeHost: - return ICECandidateTypeHost, nil - case ice.CandidateTypeServerReflexive: - return ICECandidateTypeSrflx, nil - case ice.CandidateTypePeerReflexive: - return ICECandidateTypePrflx, nil - case ice.CandidateTypeRelay: - return ICECandidateTypeRelay, nil - default: - return ICECandidateType(t), fmt.Errorf("%w: %s", errICECandidateTypeUnknown, t) - } -} - -func (c ICECandidate) String() string { - ic, err := c.toICE() - if err != nil { - return fmt.Sprintf("%#v failed to convert to ICE: %s", c, err) - } - return ic.String() -} - -// ToJSON returns an ICECandidateInit -// as indicated by the spec https://w3c.github.io/webrtc-pc/#dom-rtcicecandidate-tojson -func (c ICECandidate) ToJSON() ICECandidateInit { - zeroVal := uint16(0) - emptyStr := "" - candidateStr := "" - - candidate, err := c.toICE() - if err == nil { - candidateStr = candidate.Marshal() - } - - return ICECandidateInit{ - Candidate: fmt.Sprintf("candidate:%s", candidateStr), - SDPMid: &emptyStr, - SDPMLineIndex: &zeroVal, - } -} diff --git a/vendor/github.com/pion/webrtc/v3/icecandidateinit.go b/vendor/github.com/pion/webrtc/v3/icecandidateinit.go deleted file mode 100644 index 30ad93c0..00000000 --- a/vendor/github.com/pion/webrtc/v3/icecandidateinit.go +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// ICECandidateInit is used to serialize ice candidates -type ICECandidateInit struct { - Candidate string `json:"candidate"` - SDPMid *string `json:"sdpMid"` - SDPMLineIndex *uint16 `json:"sdpMLineIndex"` - UsernameFragment *string `json:"usernameFragment"` -} diff --git a/vendor/github.com/pion/webrtc/v3/icecandidatepair.go b/vendor/github.com/pion/webrtc/v3/icecandidatepair.go deleted file mode 100644 index b87884bc..00000000 --- a/vendor/github.com/pion/webrtc/v3/icecandidatepair.go +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import "fmt" - -// ICECandidatePair represents an ICE Candidate pair -type ICECandidatePair struct { - statsID string - Local *ICECandidate - Remote *ICECandidate -} - -func newICECandidatePairStatsID(localID, remoteID string) string { - return fmt.Sprintf("%s-%s", localID, remoteID) -} - -func (p *ICECandidatePair) String() string { - return fmt.Sprintf("(local) %s <-> (remote) %s", p.Local, p.Remote) -} - -// NewICECandidatePair returns an initialized *ICECandidatePair -// for the given pair of ICECandidate instances -func NewICECandidatePair(local, remote *ICECandidate) *ICECandidatePair { - statsID := newICECandidatePairStatsID(local.statsID, remote.statsID) - return &ICECandidatePair{ - statsID: statsID, - Local: local, - Remote: remote, - } -} diff --git a/vendor/github.com/pion/webrtc/v3/icecandidatetype.go b/vendor/github.com/pion/webrtc/v3/icecandidatetype.go deleted file mode 100644 index a274c45d..00000000 --- a/vendor/github.com/pion/webrtc/v3/icecandidatetype.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "fmt" - - "github.com/pion/ice/v2" -) - -// ICECandidateType represents the type of the ICE candidate used. -type ICECandidateType int - -const ( - // ICECandidateTypeHost indicates that the candidate is of Host type as - // described in https://tools.ietf.org/html/rfc8445#section-5.1.1.1. A - // candidate obtained by binding to a specific port from an IP address on - // the host. This includes IP addresses on physical interfaces and logical - // ones, such as ones obtained through VPNs. - ICECandidateTypeHost ICECandidateType = iota + 1 - - // ICECandidateTypeSrflx indicates the the candidate is of Server - // Reflexive type as described - // https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A candidate type - // whose IP address and port are a binding allocated by a NAT for an ICE - // agent after it sends a packet through the NAT to a server, such as a - // STUN server. - ICECandidateTypeSrflx - - // ICECandidateTypePrflx indicates that the candidate is of Peer - // Reflexive type. A candidate type whose IP address and port are a binding - // allocated by a NAT for an ICE agent after it sends a packet through the - // NAT to its peer. - ICECandidateTypePrflx - - // ICECandidateTypeRelay indicates the the candidate is of Relay type as - // described in https://tools.ietf.org/html/rfc8445#section-5.1.1.2. A - // candidate type obtained from a relay server, such as a TURN server. - ICECandidateTypeRelay -) - -// This is done this way because of a linter. -const ( - iceCandidateTypeHostStr = "host" - iceCandidateTypeSrflxStr = "srflx" - iceCandidateTypePrflxStr = "prflx" - iceCandidateTypeRelayStr = "relay" -) - -// NewICECandidateType takes a string and converts it into ICECandidateType -func NewICECandidateType(raw string) (ICECandidateType, error) { - switch raw { - case iceCandidateTypeHostStr: - return ICECandidateTypeHost, nil - case iceCandidateTypeSrflxStr: - return ICECandidateTypeSrflx, nil - case iceCandidateTypePrflxStr: - return ICECandidateTypePrflx, nil - case iceCandidateTypeRelayStr: - return ICECandidateTypeRelay, nil - default: - return ICECandidateType(Unknown), fmt.Errorf("%w: %s", errICECandidateTypeUnknown, raw) - } -} - -func (t ICECandidateType) String() string { - switch t { - case ICECandidateTypeHost: - return iceCandidateTypeHostStr - case ICECandidateTypeSrflx: - return iceCandidateTypeSrflxStr - case ICECandidateTypePrflx: - return iceCandidateTypePrflxStr - case ICECandidateTypeRelay: - return iceCandidateTypeRelayStr - default: - return ErrUnknownType.Error() - } -} - -func getCandidateType(candidateType ice.CandidateType) (ICECandidateType, error) { - switch candidateType { - case ice.CandidateTypeHost: - return ICECandidateTypeHost, nil - case ice.CandidateTypeServerReflexive: - return ICECandidateTypeSrflx, nil - case ice.CandidateTypePeerReflexive: - return ICECandidateTypePrflx, nil - case ice.CandidateTypeRelay: - return ICECandidateTypeRelay, nil - default: - // NOTE: this should never happen[tm] - err := fmt.Errorf("%w: %s", errICEInvalidConvertCandidateType, candidateType.String()) - return ICECandidateType(Unknown), err - } -} diff --git a/vendor/github.com/pion/webrtc/v3/icecomponent.go b/vendor/github.com/pion/webrtc/v3/icecomponent.go deleted file mode 100644 index c65a893d..00000000 --- a/vendor/github.com/pion/webrtc/v3/icecomponent.go +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// ICEComponent describes if the ice transport is used for RTP -// (or RTCP multiplexing). -type ICEComponent int - -const ( - // ICEComponentRTP indicates that the ICE Transport is used for RTP (or - // RTCP multiplexing), as defined in - // https://tools.ietf.org/html/rfc5245#section-4.1.1.1. Protocols - // multiplexed with RTP (e.g. data channel) share its component ID. This - // represents the component-id value 1 when encoded in candidate-attribute. - ICEComponentRTP ICEComponent = iota + 1 - - // ICEComponentRTCP indicates that the ICE Transport is used for RTCP as - // defined by https://tools.ietf.org/html/rfc5245#section-4.1.1.1. This - // represents the component-id value 2 when encoded in candidate-attribute. - ICEComponentRTCP -) - -// This is done this way because of a linter. -const ( - iceComponentRTPStr = "rtp" - iceComponentRTCPStr = "rtcp" -) - -func newICEComponent(raw string) ICEComponent { - switch raw { - case iceComponentRTPStr: - return ICEComponentRTP - case iceComponentRTCPStr: - return ICEComponentRTCP - default: - return ICEComponent(Unknown) - } -} - -func (t ICEComponent) String() string { - switch t { - case ICEComponentRTP: - return iceComponentRTPStr - case ICEComponentRTCP: - return iceComponentRTCPStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/iceconnectionstate.go b/vendor/github.com/pion/webrtc/v3/iceconnectionstate.go deleted file mode 100644 index e52e1328..00000000 --- a/vendor/github.com/pion/webrtc/v3/iceconnectionstate.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// ICEConnectionState indicates signaling state of the ICE Connection. -type ICEConnectionState int - -const ( - // ICEConnectionStateNew indicates that any of the ICETransports are - // in the "new" state and none of them are in the "checking", "disconnected" - // or "failed" state, or all ICETransports are in the "closed" state, or - // there are no transports. - ICEConnectionStateNew ICEConnectionState = iota + 1 - - // ICEConnectionStateChecking indicates that any of the ICETransports - // are in the "checking" state and none of them are in the "disconnected" - // or "failed" state. - ICEConnectionStateChecking - - // ICEConnectionStateConnected indicates that all ICETransports are - // in the "connected", "completed" or "closed" state and at least one of - // them is in the "connected" state. - ICEConnectionStateConnected - - // ICEConnectionStateCompleted indicates that all ICETransports are - // in the "completed" or "closed" state and at least one of them is in the - // "completed" state. - ICEConnectionStateCompleted - - // ICEConnectionStateDisconnected indicates that any of the - // ICETransports are in the "disconnected" state and none of them are - // in the "failed" state. - ICEConnectionStateDisconnected - - // ICEConnectionStateFailed indicates that any of the ICETransports - // are in the "failed" state. - ICEConnectionStateFailed - - // ICEConnectionStateClosed indicates that the PeerConnection's - // isClosed is true. - ICEConnectionStateClosed -) - -// This is done this way because of a linter. -const ( - iceConnectionStateNewStr = "new" - iceConnectionStateCheckingStr = "checking" - iceConnectionStateConnectedStr = "connected" - iceConnectionStateCompletedStr = "completed" - iceConnectionStateDisconnectedStr = "disconnected" - iceConnectionStateFailedStr = "failed" - iceConnectionStateClosedStr = "closed" -) - -// NewICEConnectionState takes a string and converts it to ICEConnectionState -func NewICEConnectionState(raw string) ICEConnectionState { - switch raw { - case iceConnectionStateNewStr: - return ICEConnectionStateNew - case iceConnectionStateCheckingStr: - return ICEConnectionStateChecking - case iceConnectionStateConnectedStr: - return ICEConnectionStateConnected - case iceConnectionStateCompletedStr: - return ICEConnectionStateCompleted - case iceConnectionStateDisconnectedStr: - return ICEConnectionStateDisconnected - case iceConnectionStateFailedStr: - return ICEConnectionStateFailed - case iceConnectionStateClosedStr: - return ICEConnectionStateClosed - default: - return ICEConnectionState(Unknown) - } -} - -func (c ICEConnectionState) String() string { - switch c { - case ICEConnectionStateNew: - return iceConnectionStateNewStr - case ICEConnectionStateChecking: - return iceConnectionStateCheckingStr - case ICEConnectionStateConnected: - return iceConnectionStateConnectedStr - case ICEConnectionStateCompleted: - return iceConnectionStateCompletedStr - case ICEConnectionStateDisconnected: - return iceConnectionStateDisconnectedStr - case ICEConnectionStateFailed: - return iceConnectionStateFailedStr - case ICEConnectionStateClosed: - return iceConnectionStateClosedStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/icecredentialtype.go b/vendor/github.com/pion/webrtc/v3/icecredentialtype.go deleted file mode 100644 index 5d704a9b..00000000 --- a/vendor/github.com/pion/webrtc/v3/icecredentialtype.go +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "encoding/json" - "fmt" -) - -// ICECredentialType indicates the type of credentials used to connect to -// an ICE server. -type ICECredentialType int - -const ( - // ICECredentialTypePassword describes username and password based - // credentials as described in https://tools.ietf.org/html/rfc5389. - ICECredentialTypePassword ICECredentialType = iota - - // ICECredentialTypeOauth describes token based credential as described - // in https://tools.ietf.org/html/rfc7635. - ICECredentialTypeOauth -) - -// This is done this way because of a linter. -const ( - iceCredentialTypePasswordStr = "password" - iceCredentialTypeOauthStr = "oauth" -) - -func newICECredentialType(raw string) (ICECredentialType, error) { - switch raw { - case iceCredentialTypePasswordStr: - return ICECredentialTypePassword, nil - case iceCredentialTypeOauthStr: - return ICECredentialTypeOauth, nil - default: - return ICECredentialTypePassword, errInvalidICECredentialTypeString - } -} - -func (t ICECredentialType) String() string { - switch t { - case ICECredentialTypePassword: - return iceCredentialTypePasswordStr - case ICECredentialTypeOauth: - return iceCredentialTypeOauthStr - default: - return ErrUnknownType.Error() - } -} - -// UnmarshalJSON parses the JSON-encoded data and stores the result -func (t *ICECredentialType) UnmarshalJSON(b []byte) error { - var val string - if err := json.Unmarshal(b, &val); err != nil { - return err - } - - tmp, err := newICECredentialType(val) - if err != nil { - return fmt.Errorf("%w: (%s)", err, val) - } - - *t = tmp - return nil -} - -// MarshalJSON returns the JSON encoding -func (t ICECredentialType) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} diff --git a/vendor/github.com/pion/webrtc/v3/icegatherer.go b/vendor/github.com/pion/webrtc/v3/icegatherer.go deleted file mode 100644 index cf12b420..00000000 --- a/vendor/github.com/pion/webrtc/v3/icegatherer.go +++ /dev/null @@ -1,391 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "fmt" - "sync" - "sync/atomic" - - "github.com/pion/ice/v2" - "github.com/pion/logging" - "github.com/pion/stun" -) - -// ICEGatherer gathers local host, server reflexive and relay -// candidates, as well as enabling the retrieval of local Interactive -// Connectivity Establishment (ICE) parameters which can be -// exchanged in signaling. -type ICEGatherer struct { - lock sync.RWMutex - log logging.LeveledLogger - state ICEGathererState - - validatedServers []*stun.URI - gatherPolicy ICETransportPolicy - - agent *ice.Agent - - onLocalCandidateHandler atomic.Value // func(candidate *ICECandidate) - onStateChangeHandler atomic.Value // func(state ICEGathererState) - - // Used for GatheringCompletePromise - onGatheringCompleteHandler atomic.Value // func() - - api *API -} - -// NewICEGatherer creates a new NewICEGatherer. -// This constructor is part of the ORTC API. It is not -// meant to be used together with the basic WebRTC API. -func (api *API) NewICEGatherer(opts ICEGatherOptions) (*ICEGatherer, error) { - var validatedServers []*stun.URI - if len(opts.ICEServers) > 0 { - for _, server := range opts.ICEServers { - url, err := server.urls() - if err != nil { - return nil, err - } - validatedServers = append(validatedServers, url...) - } - } - - return &ICEGatherer{ - state: ICEGathererStateNew, - gatherPolicy: opts.ICEGatherPolicy, - validatedServers: validatedServers, - api: api, - log: api.settingEngine.LoggerFactory.NewLogger("ice"), - }, nil -} - -func (g *ICEGatherer) createAgent() error { - g.lock.Lock() - defer g.lock.Unlock() - - if g.agent != nil || g.State() != ICEGathererStateNew { - return nil - } - - candidateTypes := []ice.CandidateType{} - if g.api.settingEngine.candidates.ICELite { - candidateTypes = append(candidateTypes, ice.CandidateTypeHost) - } else if g.gatherPolicy == ICETransportPolicyRelay { - candidateTypes = append(candidateTypes, ice.CandidateTypeRelay) - } - - var nat1To1CandiTyp ice.CandidateType - switch g.api.settingEngine.candidates.NAT1To1IPCandidateType { - case ICECandidateTypeHost: - nat1To1CandiTyp = ice.CandidateTypeHost - case ICECandidateTypeSrflx: - nat1To1CandiTyp = ice.CandidateTypeServerReflexive - default: - nat1To1CandiTyp = ice.CandidateTypeUnspecified - } - - mDNSMode := g.api.settingEngine.candidates.MulticastDNSMode - if mDNSMode != ice.MulticastDNSModeDisabled && mDNSMode != ice.MulticastDNSModeQueryAndGather { - // If enum is in state we don't recognized default to MulticastDNSModeQueryOnly - mDNSMode = ice.MulticastDNSModeQueryOnly - } - - config := &ice.AgentConfig{ - Lite: g.api.settingEngine.candidates.ICELite, - Urls: g.validatedServers, - PortMin: g.api.settingEngine.ephemeralUDP.PortMin, - PortMax: g.api.settingEngine.ephemeralUDP.PortMax, - DisconnectedTimeout: g.api.settingEngine.timeout.ICEDisconnectedTimeout, - FailedTimeout: g.api.settingEngine.timeout.ICEFailedTimeout, - KeepaliveInterval: g.api.settingEngine.timeout.ICEKeepaliveInterval, - LoggerFactory: g.api.settingEngine.LoggerFactory, - CandidateTypes: candidateTypes, - HostAcceptanceMinWait: g.api.settingEngine.timeout.ICEHostAcceptanceMinWait, - SrflxAcceptanceMinWait: g.api.settingEngine.timeout.ICESrflxAcceptanceMinWait, - PrflxAcceptanceMinWait: g.api.settingEngine.timeout.ICEPrflxAcceptanceMinWait, - RelayAcceptanceMinWait: g.api.settingEngine.timeout.ICERelayAcceptanceMinWait, - InterfaceFilter: g.api.settingEngine.candidates.InterfaceFilter, - IPFilter: g.api.settingEngine.candidates.IPFilter, - NAT1To1IPs: g.api.settingEngine.candidates.NAT1To1IPs, - NAT1To1IPCandidateType: nat1To1CandiTyp, - IncludeLoopback: g.api.settingEngine.candidates.IncludeLoopbackCandidate, - Net: g.api.settingEngine.net, - MulticastDNSMode: mDNSMode, - MulticastDNSHostName: g.api.settingEngine.candidates.MulticastDNSHostName, - LocalUfrag: g.api.settingEngine.candidates.UsernameFragment, - LocalPwd: g.api.settingEngine.candidates.Password, - TCPMux: g.api.settingEngine.iceTCPMux, - UDPMux: g.api.settingEngine.iceUDPMux, - ProxyDialer: g.api.settingEngine.iceProxyDialer, - } - - requestedNetworkTypes := g.api.settingEngine.candidates.ICENetworkTypes - if len(requestedNetworkTypes) == 0 { - requestedNetworkTypes = supportedNetworkTypes() - } - - for _, typ := range requestedNetworkTypes { - config.NetworkTypes = append(config.NetworkTypes, ice.NetworkType(typ)) - } - - agent, err := ice.NewAgent(config) - if err != nil { - return err - } - - g.agent = agent - return nil -} - -// Gather ICE candidates. -func (g *ICEGatherer) Gather() error { - if err := g.createAgent(); err != nil { - return err - } - - agent := g.getAgent() - // it is possible agent had just been closed - if agent == nil { - return fmt.Errorf("%w: unable to gather", errICEAgentNotExist) - } - - g.setState(ICEGathererStateGathering) - if err := agent.OnCandidate(func(candidate ice.Candidate) { - onLocalCandidateHandler := func(*ICECandidate) {} - if handler, ok := g.onLocalCandidateHandler.Load().(func(candidate *ICECandidate)); ok && handler != nil { - onLocalCandidateHandler = handler - } - - onGatheringCompleteHandler := func() {} - if handler, ok := g.onGatheringCompleteHandler.Load().(func()); ok && handler != nil { - onGatheringCompleteHandler = handler - } - - if candidate != nil { - c, err := newICECandidateFromICE(candidate) - if err != nil { - g.log.Warnf("Failed to convert ice.Candidate: %s", err) - return - } - onLocalCandidateHandler(&c) - } else { - g.setState(ICEGathererStateComplete) - - onGatheringCompleteHandler() - onLocalCandidateHandler(nil) - } - }); err != nil { - return err - } - return agent.GatherCandidates() -} - -// Close prunes all local candidates, and closes the ports. -func (g *ICEGatherer) Close() error { - g.lock.Lock() - defer g.lock.Unlock() - - if g.agent == nil { - return nil - } else if err := g.agent.Close(); err != nil { - return err - } - - g.agent = nil - g.setState(ICEGathererStateClosed) - - return nil -} - -// GetLocalParameters returns the ICE parameters of the ICEGatherer. -func (g *ICEGatherer) GetLocalParameters() (ICEParameters, error) { - if err := g.createAgent(); err != nil { - return ICEParameters{}, err - } - - agent := g.getAgent() - // it is possible agent had just been closed - if agent == nil { - return ICEParameters{}, fmt.Errorf("%w: unable to get local parameters", errICEAgentNotExist) - } - - frag, pwd, err := agent.GetLocalUserCredentials() - if err != nil { - return ICEParameters{}, err - } - - return ICEParameters{ - UsernameFragment: frag, - Password: pwd, - ICELite: false, - }, nil -} - -// GetLocalCandidates returns the sequence of valid local candidates associated with the ICEGatherer. -func (g *ICEGatherer) GetLocalCandidates() ([]ICECandidate, error) { - if err := g.createAgent(); err != nil { - return nil, err - } - - agent := g.getAgent() - // it is possible agent had just been closed - if agent == nil { - return nil, fmt.Errorf("%w: unable to get local candidates", errICEAgentNotExist) - } - - iceCandidates, err := agent.GetLocalCandidates() - if err != nil { - return nil, err - } - - return newICECandidatesFromICE(iceCandidates) -} - -// OnLocalCandidate sets an event handler which fires when a new local ICE candidate is available -// Take note that the handler will be called with a nil pointer when gathering is finished. -func (g *ICEGatherer) OnLocalCandidate(f func(*ICECandidate)) { - g.onLocalCandidateHandler.Store(f) -} - -// OnStateChange fires any time the ICEGatherer changes -func (g *ICEGatherer) OnStateChange(f func(ICEGathererState)) { - g.onStateChangeHandler.Store(f) -} - -// State indicates the current state of the ICE gatherer. -func (g *ICEGatherer) State() ICEGathererState { - return atomicLoadICEGathererState(&g.state) -} - -func (g *ICEGatherer) setState(s ICEGathererState) { - atomicStoreICEGathererState(&g.state, s) - - if handler, ok := g.onStateChangeHandler.Load().(func(state ICEGathererState)); ok && handler != nil { - handler(s) - } -} - -func (g *ICEGatherer) getAgent() *ice.Agent { - g.lock.RLock() - defer g.lock.RUnlock() - return g.agent -} - -func (g *ICEGatherer) collectStats(collector *statsReportCollector) { - agent := g.getAgent() - if agent == nil { - return - } - - collector.Collecting() - go func(collector *statsReportCollector, agent *ice.Agent) { - for _, candidatePairStats := range agent.GetCandidatePairsStats() { - collector.Collecting() - - state, err := toStatsICECandidatePairState(candidatePairStats.State) - if err != nil { - g.log.Error(err.Error()) - } - - pairID := newICECandidatePairStatsID(candidatePairStats.LocalCandidateID, - candidatePairStats.RemoteCandidateID) - - stats := ICECandidatePairStats{ - Timestamp: statsTimestampFrom(candidatePairStats.Timestamp), - Type: StatsTypeCandidatePair, - ID: pairID, - // TransportID: - LocalCandidateID: candidatePairStats.LocalCandidateID, - RemoteCandidateID: candidatePairStats.RemoteCandidateID, - State: state, - Nominated: candidatePairStats.Nominated, - PacketsSent: candidatePairStats.PacketsSent, - PacketsReceived: candidatePairStats.PacketsReceived, - BytesSent: candidatePairStats.BytesSent, - BytesReceived: candidatePairStats.BytesReceived, - LastPacketSentTimestamp: statsTimestampFrom(candidatePairStats.LastPacketSentTimestamp), - LastPacketReceivedTimestamp: statsTimestampFrom(candidatePairStats.LastPacketReceivedTimestamp), - FirstRequestTimestamp: statsTimestampFrom(candidatePairStats.FirstRequestTimestamp), - LastRequestTimestamp: statsTimestampFrom(candidatePairStats.LastRequestTimestamp), - LastResponseTimestamp: statsTimestampFrom(candidatePairStats.LastResponseTimestamp), - TotalRoundTripTime: candidatePairStats.TotalRoundTripTime, - CurrentRoundTripTime: candidatePairStats.CurrentRoundTripTime, - AvailableOutgoingBitrate: candidatePairStats.AvailableOutgoingBitrate, - AvailableIncomingBitrate: candidatePairStats.AvailableIncomingBitrate, - CircuitBreakerTriggerCount: candidatePairStats.CircuitBreakerTriggerCount, - RequestsReceived: candidatePairStats.RequestsReceived, - RequestsSent: candidatePairStats.RequestsSent, - ResponsesReceived: candidatePairStats.ResponsesReceived, - ResponsesSent: candidatePairStats.ResponsesSent, - RetransmissionsReceived: candidatePairStats.RetransmissionsReceived, - RetransmissionsSent: candidatePairStats.RetransmissionsSent, - ConsentRequestsSent: candidatePairStats.ConsentRequestsSent, - ConsentExpiredTimestamp: statsTimestampFrom(candidatePairStats.ConsentExpiredTimestamp), - } - collector.Collect(stats.ID, stats) - } - - for _, candidateStats := range agent.GetLocalCandidatesStats() { - collector.Collecting() - - networkType, err := getNetworkType(candidateStats.NetworkType) - if err != nil { - g.log.Error(err.Error()) - } - - candidateType, err := getCandidateType(candidateStats.CandidateType) - if err != nil { - g.log.Error(err.Error()) - } - - stats := ICECandidateStats{ - Timestamp: statsTimestampFrom(candidateStats.Timestamp), - ID: candidateStats.ID, - Type: StatsTypeLocalCandidate, - NetworkType: networkType, - IP: candidateStats.IP, - Port: int32(candidateStats.Port), - Protocol: networkType.Protocol(), - CandidateType: candidateType, - Priority: int32(candidateStats.Priority), - URL: candidateStats.URL, - RelayProtocol: candidateStats.RelayProtocol, - Deleted: candidateStats.Deleted, - } - collector.Collect(stats.ID, stats) - } - - for _, candidateStats := range agent.GetRemoteCandidatesStats() { - collector.Collecting() - networkType, err := getNetworkType(candidateStats.NetworkType) - if err != nil { - g.log.Error(err.Error()) - } - - candidateType, err := getCandidateType(candidateStats.CandidateType) - if err != nil { - g.log.Error(err.Error()) - } - - stats := ICECandidateStats{ - Timestamp: statsTimestampFrom(candidateStats.Timestamp), - ID: candidateStats.ID, - Type: StatsTypeRemoteCandidate, - NetworkType: networkType, - IP: candidateStats.IP, - Port: int32(candidateStats.Port), - Protocol: networkType.Protocol(), - CandidateType: candidateType, - Priority: int32(candidateStats.Priority), - URL: candidateStats.URL, - RelayProtocol: candidateStats.RelayProtocol, - } - collector.Collect(stats.ID, stats) - } - collector.Done() - }(collector, agent) -} diff --git a/vendor/github.com/pion/webrtc/v3/icegathererstate.go b/vendor/github.com/pion/webrtc/v3/icegathererstate.go deleted file mode 100644 index b90acd33..00000000 --- a/vendor/github.com/pion/webrtc/v3/icegathererstate.go +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "sync/atomic" -) - -// ICEGathererState represents the current state of the ICE gatherer. -type ICEGathererState uint32 - -const ( - // ICEGathererStateNew indicates object has been created but - // gather() has not been called. - ICEGathererStateNew ICEGathererState = iota + 1 - - // ICEGathererStateGathering indicates gather() has been called, - // and the ICEGatherer is in the process of gathering candidates. - ICEGathererStateGathering - - // ICEGathererStateComplete indicates the ICEGatherer has completed gathering. - ICEGathererStateComplete - - // ICEGathererStateClosed indicates the closed state can only be entered - // when the ICEGatherer has been closed intentionally by calling close(). - ICEGathererStateClosed -) - -func (s ICEGathererState) String() string { - switch s { - case ICEGathererStateNew: - return "new" - case ICEGathererStateGathering: - return "gathering" - case ICEGathererStateComplete: - return "complete" - case ICEGathererStateClosed: - return "closed" - default: - return unknownStr - } -} - -func atomicStoreICEGathererState(state *ICEGathererState, newState ICEGathererState) { - atomic.StoreUint32((*uint32)(state), uint32(newState)) -} - -func atomicLoadICEGathererState(state *ICEGathererState) ICEGathererState { - return ICEGathererState(atomic.LoadUint32((*uint32)(state))) -} diff --git a/vendor/github.com/pion/webrtc/v3/icegatheringstate.go b/vendor/github.com/pion/webrtc/v3/icegatheringstate.go deleted file mode 100644 index 1925dddb..00000000 --- a/vendor/github.com/pion/webrtc/v3/icegatheringstate.go +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// ICEGatheringState describes the state of the candidate gathering process. -type ICEGatheringState int - -const ( - // ICEGatheringStateNew indicates that any of the ICETransports are - // in the "new" gathering state and none of the transports are in the - // "gathering" state, or there are no transports. - ICEGatheringStateNew ICEGatheringState = iota + 1 - - // ICEGatheringStateGathering indicates that any of the ICETransports - // are in the "gathering" state. - ICEGatheringStateGathering - - // ICEGatheringStateComplete indicates that at least one ICETransport - // exists, and all ICETransports are in the "completed" gathering state. - ICEGatheringStateComplete -) - -// This is done this way because of a linter. -const ( - iceGatheringStateNewStr = "new" - iceGatheringStateGatheringStr = "gathering" - iceGatheringStateCompleteStr = "complete" -) - -// NewICEGatheringState takes a string and converts it to ICEGatheringState -func NewICEGatheringState(raw string) ICEGatheringState { - switch raw { - case iceGatheringStateNewStr: - return ICEGatheringStateNew - case iceGatheringStateGatheringStr: - return ICEGatheringStateGathering - case iceGatheringStateCompleteStr: - return ICEGatheringStateComplete - default: - return ICEGatheringState(Unknown) - } -} - -func (t ICEGatheringState) String() string { - switch t { - case ICEGatheringStateNew: - return iceGatheringStateNewStr - case ICEGatheringStateGathering: - return iceGatheringStateGatheringStr - case ICEGatheringStateComplete: - return iceGatheringStateCompleteStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/icegatheroptions.go b/vendor/github.com/pion/webrtc/v3/icegatheroptions.go deleted file mode 100644 index cca356fc..00000000 --- a/vendor/github.com/pion/webrtc/v3/icegatheroptions.go +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// ICEGatherOptions provides options relating to the gathering of ICE candidates. -type ICEGatherOptions struct { - ICEServers []ICEServer - ICEGatherPolicy ICETransportPolicy -} diff --git a/vendor/github.com/pion/webrtc/v3/icemux.go b/vendor/github.com/pion/webrtc/v3/icemux.go deleted file mode 100644 index 1bae3131..00000000 --- a/vendor/github.com/pion/webrtc/v3/icemux.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "net" - - "github.com/pion/ice/v2" - "github.com/pion/logging" -) - -// NewICETCPMux creates a new instance of ice.TCPMuxDefault. It enables use of -// passive ICE TCP candidates. -func NewICETCPMux(logger logging.LeveledLogger, listener net.Listener, readBufferSize int) ice.TCPMux { - return ice.NewTCPMuxDefault(ice.TCPMuxParams{ - Listener: listener, - Logger: logger, - ReadBufferSize: readBufferSize, - }) -} - -// NewICEUDPMux creates a new instance of ice.UDPMuxDefault. It allows many PeerConnections to be served -// by a single UDP Port. -func NewICEUDPMux(logger logging.LeveledLogger, udpConn net.PacketConn) ice.UDPMux { - return ice.NewUDPMuxDefault(ice.UDPMuxParams{ - UDPConn: udpConn, - Logger: logger, - }) -} diff --git a/vendor/github.com/pion/webrtc/v3/iceparameters.go b/vendor/github.com/pion/webrtc/v3/iceparameters.go deleted file mode 100644 index 459ec600..00000000 --- a/vendor/github.com/pion/webrtc/v3/iceparameters.go +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// ICEParameters includes the ICE username fragment -// and password and other ICE-related parameters. -type ICEParameters struct { - UsernameFragment string `json:"usernameFragment"` - Password string `json:"password"` - ICELite bool `json:"iceLite"` -} diff --git a/vendor/github.com/pion/webrtc/v3/iceprotocol.go b/vendor/github.com/pion/webrtc/v3/iceprotocol.go deleted file mode 100644 index 3582b683..00000000 --- a/vendor/github.com/pion/webrtc/v3/iceprotocol.go +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "fmt" - "strings" -) - -// ICEProtocol indicates the transport protocol type that is used in the -// ice.URL structure. -type ICEProtocol int - -const ( - // ICEProtocolUDP indicates the URL uses a UDP transport. - ICEProtocolUDP ICEProtocol = iota + 1 - - // ICEProtocolTCP indicates the URL uses a TCP transport. - ICEProtocolTCP -) - -// This is done this way because of a linter. -const ( - iceProtocolUDPStr = "udp" - iceProtocolTCPStr = "tcp" -) - -// NewICEProtocol takes a string and converts it to ICEProtocol -func NewICEProtocol(raw string) (ICEProtocol, error) { - switch { - case strings.EqualFold(iceProtocolUDPStr, raw): - return ICEProtocolUDP, nil - case strings.EqualFold(iceProtocolTCPStr, raw): - return ICEProtocolTCP, nil - default: - return ICEProtocol(Unknown), fmt.Errorf("%w: %s", errICEProtocolUnknown, raw) - } -} - -func (t ICEProtocol) String() string { - switch t { - case ICEProtocolUDP: - return iceProtocolUDPStr - case ICEProtocolTCP: - return iceProtocolTCPStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/icerole.go b/vendor/github.com/pion/webrtc/v3/icerole.go deleted file mode 100644 index 99268bac..00000000 --- a/vendor/github.com/pion/webrtc/v3/icerole.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// ICERole describes the role ice.Agent is playing in selecting the -// preferred the candidate pair. -type ICERole int - -const ( - // ICERoleControlling indicates that the ICE agent that is responsible - // for selecting the final choice of candidate pairs and signaling them - // through STUN and an updated offer, if needed. In any session, one agent - // is always controlling. The other is the controlled agent. - ICERoleControlling ICERole = iota + 1 - - // ICERoleControlled indicates that an ICE agent that waits for the - // controlling agent to select the final choice of candidate pairs. - ICERoleControlled -) - -// This is done this way because of a linter. -const ( - iceRoleControllingStr = "controlling" - iceRoleControlledStr = "controlled" -) - -func newICERole(raw string) ICERole { - switch raw { - case iceRoleControllingStr: - return ICERoleControlling - case iceRoleControlledStr: - return ICERoleControlled - default: - return ICERole(Unknown) - } -} - -func (t ICERole) String() string { - switch t { - case ICERoleControlling: - return iceRoleControllingStr - case ICERoleControlled: - return iceRoleControlledStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/iceserver.go b/vendor/github.com/pion/webrtc/v3/iceserver.go deleted file mode 100644 index 35d231fd..00000000 --- a/vendor/github.com/pion/webrtc/v3/iceserver.go +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "encoding/json" - - "github.com/pion/stun" - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -// ICEServer describes a single STUN and TURN server that can be used by -// the ICEAgent to establish a connection with a peer. -type ICEServer struct { - URLs []string `json:"urls"` - Username string `json:"username,omitempty"` - Credential interface{} `json:"credential,omitempty"` - CredentialType ICECredentialType `json:"credentialType,omitempty"` -} - -func (s ICEServer) parseURL(i int) (*stun.URI, error) { - return stun.ParseURI(s.URLs[i]) -} - -func (s ICEServer) validate() error { - _, err := s.urls() - return err -} - -func (s ICEServer) urls() ([]*stun.URI, error) { - urls := []*stun.URI{} - - for i := range s.URLs { - url, err := s.parseURL(i) - if err != nil { - return nil, &rtcerr.InvalidAccessError{Err: err} - } - - if url.Scheme == stun.SchemeTypeTURN || url.Scheme == stun.SchemeTypeTURNS { - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.2) - if s.Username == "" || s.Credential == nil { - return nil, &rtcerr.InvalidAccessError{Err: ErrNoTurnCredentials} - } - url.Username = s.Username - - switch s.CredentialType { - case ICECredentialTypePassword: - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.3) - password, ok := s.Credential.(string) - if !ok { - return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredentials} - } - url.Password = password - - case ICECredentialTypeOauth: - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.4) - if _, ok := s.Credential.(OAuthCredential); !ok { - return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredentials} - } - - default: - return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredentials} - } - } - - urls = append(urls, url) - } - - return urls, nil -} - -func iceserverUnmarshalUrls(val interface{}) (*[]string, error) { - s, ok := val.([]interface{}) - if !ok { - return nil, errInvalidICEServer - } - out := make([]string, len(s)) - for idx, url := range s { - out[idx], ok = url.(string) - if !ok { - return nil, errInvalidICEServer - } - } - return &out, nil -} - -func iceserverUnmarshalOauth(val interface{}) (*OAuthCredential, error) { - c, ok := val.(map[string]interface{}) - if !ok { - return nil, errInvalidICEServer - } - MACKey, ok := c["MACKey"].(string) - if !ok { - return nil, errInvalidICEServer - } - AccessToken, ok := c["AccessToken"].(string) - if !ok { - return nil, errInvalidICEServer - } - return &OAuthCredential{ - MACKey: MACKey, - AccessToken: AccessToken, - }, nil -} - -func (s *ICEServer) iceserverUnmarshalFields(m map[string]interface{}) error { - if val, ok := m["urls"]; ok { - u, err := iceserverUnmarshalUrls(val) - if err != nil { - return err - } - s.URLs = *u - } else { - s.URLs = []string{} - } - - if val, ok := m["username"]; ok { - s.Username, ok = val.(string) - if !ok { - return errInvalidICEServer - } - } - if val, ok := m["credentialType"]; ok { - ct, ok := val.(string) - if !ok { - return errInvalidICEServer - } - tpe, err := newICECredentialType(ct) - if err != nil { - return err - } - s.CredentialType = tpe - } else { - s.CredentialType = ICECredentialTypePassword - } - if val, ok := m["credential"]; ok { - switch s.CredentialType { - case ICECredentialTypePassword: - s.Credential = val - case ICECredentialTypeOauth: - c, err := iceserverUnmarshalOauth(val) - if err != nil { - return err - } - s.Credential = *c - default: - return errInvalidICECredentialTypeString - } - } - return nil -} - -// UnmarshalJSON parses the JSON-encoded data and stores the result -func (s *ICEServer) UnmarshalJSON(b []byte) error { - var tmp interface{} - err := json.Unmarshal(b, &tmp) - if err != nil { - return err - } - if m, ok := tmp.(map[string]interface{}); ok { - return s.iceserverUnmarshalFields(m) - } - return errInvalidICEServer -} - -// MarshalJSON returns the JSON encoding -func (s ICEServer) MarshalJSON() ([]byte, error) { - m := make(map[string]interface{}) - m["urls"] = s.URLs - if s.Username != "" { - m["username"] = s.Username - } - if s.Credential != nil { - m["credential"] = s.Credential - } - m["credentialType"] = s.CredentialType - return json.Marshal(m) -} diff --git a/vendor/github.com/pion/webrtc/v3/iceserver_js.go b/vendor/github.com/pion/webrtc/v3/iceserver_js.go deleted file mode 100644 index e4061fa5..00000000 --- a/vendor/github.com/pion/webrtc/v3/iceserver_js.go +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import ( - "errors" - - "github.com/pion/ice/v2" -) - -// ICEServer describes a single STUN and TURN server that can be used by -// the ICEAgent to establish a connection with a peer. -type ICEServer struct { - URLs []string - Username string - // Note: TURN is not supported in the WASM bindings yet - Credential interface{} - CredentialType ICECredentialType -} - -func (s ICEServer) parseURL(i int) (*ice.URL, error) { - return ice.ParseURL(s.URLs[i]) -} - -func (s ICEServer) validate() ([]*ice.URL, error) { - urls := []*ice.URL{} - - for i := range s.URLs { - url, err := s.parseURL(i) - if err != nil { - return nil, err - } - - if url.Scheme == ice.SchemeTypeTURN || url.Scheme == ice.SchemeTypeTURNS { - return nil, errors.New("TURN is not currently supported in the JavaScript/Wasm bindings") - } - - urls = append(urls, url) - } - - return urls, nil -} diff --git a/vendor/github.com/pion/webrtc/v3/icetransport.go b/vendor/github.com/pion/webrtc/v3/icetransport.go deleted file mode 100644 index f3b6925c..00000000 --- a/vendor/github.com/pion/webrtc/v3/icetransport.go +++ /dev/null @@ -1,376 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "context" - "fmt" - "sync" - "sync/atomic" - "time" - - "github.com/pion/ice/v2" - "github.com/pion/logging" - "github.com/pion/webrtc/v3/internal/mux" -) - -// ICETransport allows an application access to information about the ICE -// transport over which packets are sent and received. -type ICETransport struct { - lock sync.RWMutex - - role ICERole - - onConnectionStateChangeHandler atomic.Value // func(ICETransportState) - internalOnConnectionStateChangeHandler atomic.Value // func(ICETransportState) - onSelectedCandidatePairChangeHandler atomic.Value // func(*ICECandidatePair) - - state atomic.Value // ICETransportState - - gatherer *ICEGatherer - conn *ice.Conn - mux *mux.Mux - - ctx context.Context - ctxCancel func() - - loggerFactory logging.LoggerFactory - - log logging.LeveledLogger -} - -// GetSelectedCandidatePair returns the selected candidate pair on which packets are sent -// if there is no selected pair nil is returned -func (t *ICETransport) GetSelectedCandidatePair() (*ICECandidatePair, error) { - agent := t.gatherer.getAgent() - if agent == nil { - return nil, nil //nolint:nilnil - } - - icePair, err := agent.GetSelectedCandidatePair() - if icePair == nil || err != nil { - return nil, err - } - - local, err := newICECandidateFromICE(icePair.Local) - if err != nil { - return nil, err - } - - remote, err := newICECandidateFromICE(icePair.Remote) - if err != nil { - return nil, err - } - - return &ICECandidatePair{Local: &local, Remote: &remote}, nil -} - -// NewICETransport creates a new NewICETransport. -func NewICETransport(gatherer *ICEGatherer, loggerFactory logging.LoggerFactory) *ICETransport { - iceTransport := &ICETransport{ - gatherer: gatherer, - loggerFactory: loggerFactory, - log: loggerFactory.NewLogger("ortc"), - } - iceTransport.setState(ICETransportStateNew) - return iceTransport -} - -// Start incoming connectivity checks based on its configured role. -func (t *ICETransport) Start(gatherer *ICEGatherer, params ICEParameters, role *ICERole) error { - t.lock.Lock() - defer t.lock.Unlock() - - if t.State() != ICETransportStateNew { - return errICETransportNotInNew - } - - if gatherer != nil { - t.gatherer = gatherer - } - - if err := t.ensureGatherer(); err != nil { - return err - } - - agent := t.gatherer.getAgent() - if agent == nil { - return fmt.Errorf("%w: unable to start ICETransport", errICEAgentNotExist) - } - - if err := agent.OnConnectionStateChange(func(iceState ice.ConnectionState) { - state := newICETransportStateFromICE(iceState) - - t.setState(state) - t.onConnectionStateChange(state) - }); err != nil { - return err - } - if err := agent.OnSelectedCandidatePairChange(func(local, remote ice.Candidate) { - candidates, err := newICECandidatesFromICE([]ice.Candidate{local, remote}) - if err != nil { - t.log.Warnf("%w: %s", errICECandiatesCoversionFailed, err) - return - } - t.onSelectedCandidatePairChange(NewICECandidatePair(&candidates[0], &candidates[1])) - }); err != nil { - return err - } - - if role == nil { - controlled := ICERoleControlled - role = &controlled - } - t.role = *role - - t.ctx, t.ctxCancel = context.WithCancel(context.Background()) - - // Drop the lock here to allow ICE candidates to be - // added so that the agent can complete a connection - t.lock.Unlock() - - var iceConn *ice.Conn - var err error - switch *role { - case ICERoleControlling: - iceConn, err = agent.Dial(t.ctx, - params.UsernameFragment, - params.Password) - - case ICERoleControlled: - iceConn, err = agent.Accept(t.ctx, - params.UsernameFragment, - params.Password) - - default: - err = errICERoleUnknown - } - - // Reacquire the lock to set the connection/mux - t.lock.Lock() - if err != nil { - return err - } - - t.conn = iceConn - - config := mux.Config{ - Conn: t.conn, - BufferSize: int(t.gatherer.api.settingEngine.getReceiveMTU()), - LoggerFactory: t.loggerFactory, - } - t.mux = mux.NewMux(config) - - return nil -} - -// restart is not exposed currently because ORTC has users create a whole new ICETransport -// so for now lets keep it private so we don't cause ORTC users to depend on non-standard APIs -func (t *ICETransport) restart() error { - t.lock.Lock() - defer t.lock.Unlock() - - agent := t.gatherer.getAgent() - if agent == nil { - return fmt.Errorf("%w: unable to restart ICETransport", errICEAgentNotExist) - } - - if err := agent.Restart(t.gatherer.api.settingEngine.candidates.UsernameFragment, t.gatherer.api.settingEngine.candidates.Password); err != nil { - return err - } - return t.gatherer.Gather() -} - -// Stop irreversibly stops the ICETransport. -func (t *ICETransport) Stop() error { - t.lock.Lock() - defer t.lock.Unlock() - - t.setState(ICETransportStateClosed) - - if t.ctxCancel != nil { - t.ctxCancel() - } - - if t.mux != nil { - return t.mux.Close() - } else if t.gatherer != nil { - return t.gatherer.Close() - } - return nil -} - -// OnSelectedCandidatePairChange sets a handler that is invoked when a new -// ICE candidate pair is selected -func (t *ICETransport) OnSelectedCandidatePairChange(f func(*ICECandidatePair)) { - t.onSelectedCandidatePairChangeHandler.Store(f) -} - -func (t *ICETransport) onSelectedCandidatePairChange(pair *ICECandidatePair) { - if handler, ok := t.onSelectedCandidatePairChangeHandler.Load().(func(*ICECandidatePair)); ok { - handler(pair) - } -} - -// OnConnectionStateChange sets a handler that is fired when the ICE -// connection state changes. -func (t *ICETransport) OnConnectionStateChange(f func(ICETransportState)) { - t.onConnectionStateChangeHandler.Store(f) -} - -func (t *ICETransport) onConnectionStateChange(state ICETransportState) { - if handler, ok := t.onConnectionStateChangeHandler.Load().(func(ICETransportState)); ok { - handler(state) - } - if handler, ok := t.internalOnConnectionStateChangeHandler.Load().(func(ICETransportState)); ok { - handler(state) - } -} - -// Role indicates the current role of the ICE transport. -func (t *ICETransport) Role() ICERole { - t.lock.RLock() - defer t.lock.RUnlock() - - return t.role -} - -// SetRemoteCandidates sets the sequence of candidates associated with the remote ICETransport. -func (t *ICETransport) SetRemoteCandidates(remoteCandidates []ICECandidate) error { - t.lock.RLock() - defer t.lock.RUnlock() - - if err := t.ensureGatherer(); err != nil { - return err - } - - agent := t.gatherer.getAgent() - if agent == nil { - return fmt.Errorf("%w: unable to set remote candidates", errICEAgentNotExist) - } - - for _, c := range remoteCandidates { - i, err := c.toICE() - if err != nil { - return err - } - - if err = agent.AddRemoteCandidate(i); err != nil { - return err - } - } - - return nil -} - -// AddRemoteCandidate adds a candidate associated with the remote ICETransport. -func (t *ICETransport) AddRemoteCandidate(remoteCandidate *ICECandidate) error { - t.lock.RLock() - defer t.lock.RUnlock() - - var ( - c ice.Candidate - err error - ) - - if err = t.ensureGatherer(); err != nil { - return err - } - - if remoteCandidate != nil { - if c, err = remoteCandidate.toICE(); err != nil { - return err - } - } - - agent := t.gatherer.getAgent() - if agent == nil { - return fmt.Errorf("%w: unable to add remote candidates", errICEAgentNotExist) - } - - return agent.AddRemoteCandidate(c) -} - -// State returns the current ice transport state. -func (t *ICETransport) State() ICETransportState { - if v, ok := t.state.Load().(ICETransportState); ok { - return v - } - return ICETransportState(0) -} - -func (t *ICETransport) setState(i ICETransportState) { - t.state.Store(i) -} - -func (t *ICETransport) newEndpoint(f mux.MatchFunc) *mux.Endpoint { - t.lock.Lock() - defer t.lock.Unlock() - return t.mux.NewEndpoint(f) -} - -func (t *ICETransport) ensureGatherer() error { - if t.gatherer == nil { - return errICEGathererNotStarted - } else if t.gatherer.getAgent() == nil { - if err := t.gatherer.createAgent(); err != nil { - return err - } - } - - return nil -} - -func (t *ICETransport) collectStats(collector *statsReportCollector) { - t.lock.Lock() - conn := t.conn - t.lock.Unlock() - - collector.Collecting() - - stats := TransportStats{ - Timestamp: statsTimestampFrom(time.Now()), - Type: StatsTypeTransport, - ID: "iceTransport", - } - - if conn != nil { - stats.BytesSent = conn.BytesSent() - stats.BytesReceived = conn.BytesReceived() - } - - collector.Collect(stats.ID, stats) -} - -func (t *ICETransport) haveRemoteCredentialsChange(newUfrag, newPwd string) bool { - t.lock.Lock() - defer t.lock.Unlock() - - agent := t.gatherer.getAgent() - if agent == nil { - return false - } - - uFrag, uPwd, err := agent.GetRemoteUserCredentials() - if err != nil { - return false - } - - return uFrag != newUfrag || uPwd != newPwd -} - -func (t *ICETransport) setRemoteCredentials(newUfrag, newPwd string) error { - t.lock.Lock() - defer t.lock.Unlock() - - agent := t.gatherer.getAgent() - if agent == nil { - return fmt.Errorf("%w: unable to SetRemoteCredentials", errICEAgentNotExist) - } - - return agent.SetRemoteCredentials(newUfrag, newPwd) -} diff --git a/vendor/github.com/pion/webrtc/v3/icetransport_js.go b/vendor/github.com/pion/webrtc/v3/icetransport_js.go deleted file mode 100644 index 3ca577b1..00000000 --- a/vendor/github.com/pion/webrtc/v3/icetransport_js.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import "syscall/js" - -// ICETransport allows an application access to information about the ICE -// transport over which packets are sent and received. -type ICETransport struct { - // Pointer to the underlying JavaScript ICETransport object. - underlying js.Value -} - -// GetSelectedCandidatePair returns the selected candidate pair on which packets are sent -// if there is no selected pair nil is returned -func (t *ICETransport) GetSelectedCandidatePair() (*ICECandidatePair, error) { - val := t.underlying.Call("getSelectedCandidatePair") - if val.IsNull() || val.IsUndefined() { - return nil, nil - } - - return NewICECandidatePair( - valueToICECandidate(val.Get("local")), - valueToICECandidate(val.Get("remote")), - ), nil -} diff --git a/vendor/github.com/pion/webrtc/v3/icetransportpolicy.go b/vendor/github.com/pion/webrtc/v3/icetransportpolicy.go deleted file mode 100644 index a2629fda..00000000 --- a/vendor/github.com/pion/webrtc/v3/icetransportpolicy.go +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "encoding/json" -) - -// ICETransportPolicy defines the ICE candidate policy surface the -// permitted candidates. Only these candidates are used for connectivity checks. -type ICETransportPolicy int - -// ICEGatherPolicy is the ORTC equivalent of ICETransportPolicy -type ICEGatherPolicy = ICETransportPolicy - -const ( - // ICETransportPolicyAll indicates any type of candidate is used. - ICETransportPolicyAll ICETransportPolicy = iota - - // ICETransportPolicyRelay indicates only media relay candidates such - // as candidates passing through a TURN server are used. - ICETransportPolicyRelay -) - -// This is done this way because of a linter. -const ( - iceTransportPolicyRelayStr = "relay" - iceTransportPolicyAllStr = "all" -) - -// NewICETransportPolicy takes a string and converts it to ICETransportPolicy -func NewICETransportPolicy(raw string) ICETransportPolicy { - switch raw { - case iceTransportPolicyRelayStr: - return ICETransportPolicyRelay - case iceTransportPolicyAllStr: - return ICETransportPolicyAll - default: - return ICETransportPolicy(Unknown) - } -} - -func (t ICETransportPolicy) String() string { - switch t { - case ICETransportPolicyRelay: - return iceTransportPolicyRelayStr - case ICETransportPolicyAll: - return iceTransportPolicyAllStr - default: - return ErrUnknownType.Error() - } -} - -// UnmarshalJSON parses the JSON-encoded data and stores the result -func (t *ICETransportPolicy) UnmarshalJSON(b []byte) error { - var val string - if err := json.Unmarshal(b, &val); err != nil { - return err - } - *t = NewICETransportPolicy(val) - return nil -} - -// MarshalJSON returns the JSON encoding -func (t ICETransportPolicy) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} diff --git a/vendor/github.com/pion/webrtc/v3/icetransportstate.go b/vendor/github.com/pion/webrtc/v3/icetransportstate.go deleted file mode 100644 index 4edbf0f4..00000000 --- a/vendor/github.com/pion/webrtc/v3/icetransportstate.go +++ /dev/null @@ -1,110 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import "github.com/pion/ice/v2" - -// ICETransportState represents the current state of the ICE transport. -type ICETransportState int - -const ( - // ICETransportStateNew indicates the ICETransport is waiting - // for remote candidates to be supplied. - ICETransportStateNew = iota + 1 - - // ICETransportStateChecking indicates the ICETransport has - // received at least one remote candidate, and a local and remote - // ICECandidateComplete dictionary was not added as the last candidate. - ICETransportStateChecking - - // ICETransportStateConnected indicates the ICETransport has - // received a response to an outgoing connectivity check, or has - // received incoming DTLS/media after a successful response to an - // incoming connectivity check, but is still checking other candidate - // pairs to see if there is a better connection. - ICETransportStateConnected - - // ICETransportStateCompleted indicates the ICETransport tested - // all appropriate candidate pairs and at least one functioning - // candidate pair has been found. - ICETransportStateCompleted - - // ICETransportStateFailed indicates the ICETransport the last - // candidate was added and all appropriate candidate pairs have either - // failed connectivity checks or have lost consent. - ICETransportStateFailed - - // ICETransportStateDisconnected indicates the ICETransport has received - // at least one local and remote candidate, but the final candidate was - // received yet and all appropriate candidate pairs thus far have been - // tested and failed. - ICETransportStateDisconnected - - // ICETransportStateClosed indicates the ICETransport has shut down - // and is no longer responding to STUN requests. - ICETransportStateClosed -) - -func (c ICETransportState) String() string { - switch c { - case ICETransportStateNew: - return "new" - case ICETransportStateChecking: - return "checking" - case ICETransportStateConnected: - return "connected" - case ICETransportStateCompleted: - return "completed" - case ICETransportStateFailed: - return "failed" - case ICETransportStateDisconnected: - return "disconnected" - case ICETransportStateClosed: - return "closed" - default: - return unknownStr - } -} - -func newICETransportStateFromICE(i ice.ConnectionState) ICETransportState { - switch i { - case ice.ConnectionStateNew: - return ICETransportStateNew - case ice.ConnectionStateChecking: - return ICETransportStateChecking - case ice.ConnectionStateConnected: - return ICETransportStateConnected - case ice.ConnectionStateCompleted: - return ICETransportStateCompleted - case ice.ConnectionStateFailed: - return ICETransportStateFailed - case ice.ConnectionStateDisconnected: - return ICETransportStateDisconnected - case ice.ConnectionStateClosed: - return ICETransportStateClosed - default: - return ICETransportState(Unknown) - } -} - -func (c ICETransportState) toICE() ice.ConnectionState { - switch c { - case ICETransportStateNew: - return ice.ConnectionStateNew - case ICETransportStateChecking: - return ice.ConnectionStateChecking - case ICETransportStateConnected: - return ice.ConnectionStateConnected - case ICETransportStateCompleted: - return ice.ConnectionStateCompleted - case ICETransportStateFailed: - return ice.ConnectionStateFailed - case ICETransportStateDisconnected: - return ice.ConnectionStateDisconnected - case ICETransportStateClosed: - return ice.ConnectionStateClosed - default: - return ice.ConnectionState(Unknown) - } -} diff --git a/vendor/github.com/pion/webrtc/v3/interceptor.go b/vendor/github.com/pion/webrtc/v3/interceptor.go deleted file mode 100644 index 85232f35..00000000 --- a/vendor/github.com/pion/webrtc/v3/interceptor.go +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "sync/atomic" - - "github.com/pion/interceptor" - "github.com/pion/interceptor/pkg/nack" - "github.com/pion/interceptor/pkg/report" - "github.com/pion/interceptor/pkg/twcc" - "github.com/pion/rtp" - "github.com/pion/sdp/v3" -) - -// RegisterDefaultInterceptors will register some useful interceptors. -// If you want to customize which interceptors are loaded, you should copy the -// code from this method and remove unwanted interceptors. -func RegisterDefaultInterceptors(mediaEngine *MediaEngine, interceptorRegistry *interceptor.Registry) error { - if err := ConfigureNack(mediaEngine, interceptorRegistry); err != nil { - return err - } - - if err := ConfigureRTCPReports(interceptorRegistry); err != nil { - return err - } - - return ConfigureTWCCSender(mediaEngine, interceptorRegistry) -} - -// ConfigureRTCPReports will setup everything necessary for generating Sender and Receiver Reports -func ConfigureRTCPReports(interceptorRegistry *interceptor.Registry) error { - reciver, err := report.NewReceiverInterceptor() - if err != nil { - return err - } - - sender, err := report.NewSenderInterceptor() - if err != nil { - return err - } - - interceptorRegistry.Add(reciver) - interceptorRegistry.Add(sender) - return nil -} - -// ConfigureNack will setup everything necessary for handling generating/responding to nack messages. -func ConfigureNack(mediaEngine *MediaEngine, interceptorRegistry *interceptor.Registry) error { - generator, err := nack.NewGeneratorInterceptor() - if err != nil { - return err - } - - responder, err := nack.NewResponderInterceptor() - if err != nil { - return err - } - - mediaEngine.RegisterFeedback(RTCPFeedback{Type: "nack"}, RTPCodecTypeVideo) - mediaEngine.RegisterFeedback(RTCPFeedback{Type: "nack", Parameter: "pli"}, RTPCodecTypeVideo) - interceptorRegistry.Add(responder) - interceptorRegistry.Add(generator) - return nil -} - -// ConfigureTWCCHeaderExtensionSender will setup everything necessary for adding -// a TWCC header extension to outgoing RTP packets. This will allow the remote peer to generate TWCC reports. -func ConfigureTWCCHeaderExtensionSender(mediaEngine *MediaEngine, interceptorRegistry *interceptor.Registry) error { - if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeVideo); err != nil { - return err - } - - if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeAudio); err != nil { - return err - } - - i, err := twcc.NewHeaderExtensionInterceptor() - if err != nil { - return err - } - - interceptorRegistry.Add(i) - return nil -} - -// ConfigureTWCCSender will setup everything necessary for generating TWCC reports. -func ConfigureTWCCSender(mediaEngine *MediaEngine, interceptorRegistry *interceptor.Registry) error { - mediaEngine.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBTransportCC}, RTPCodecTypeVideo) - if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeVideo); err != nil { - return err - } - - mediaEngine.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBTransportCC}, RTPCodecTypeAudio) - if err := mediaEngine.RegisterHeaderExtension(RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeAudio); err != nil { - return err - } - - generator, err := twcc.NewSenderInterceptor() - if err != nil { - return err - } - - interceptorRegistry.Add(generator) - return nil -} - -type interceptorToTrackLocalWriter struct{ interceptor atomic.Value } // interceptor.RTPWriter } - -func (i *interceptorToTrackLocalWriter) WriteRTP(header *rtp.Header, payload []byte) (int, error) { - if writer, ok := i.interceptor.Load().(interceptor.RTPWriter); ok && writer != nil { - return writer.Write(header, payload, interceptor.Attributes{}) - } - - return 0, nil -} - -func (i *interceptorToTrackLocalWriter) Write(b []byte) (int, error) { - packet := &rtp.Packet{} - if err := packet.Unmarshal(b); err != nil { - return 0, err - } - - return i.WriteRTP(&packet.Header, packet.Payload) -} - -func createStreamInfo(id string, ssrc SSRC, payloadType PayloadType, codec RTPCodecCapability, webrtcHeaderExtensions []RTPHeaderExtensionParameter) *interceptor.StreamInfo { - headerExtensions := make([]interceptor.RTPHeaderExtension, 0, len(webrtcHeaderExtensions)) - for _, h := range webrtcHeaderExtensions { - headerExtensions = append(headerExtensions, interceptor.RTPHeaderExtension{ID: h.ID, URI: h.URI}) - } - - feedbacks := make([]interceptor.RTCPFeedback, 0, len(codec.RTCPFeedback)) - for _, f := range codec.RTCPFeedback { - feedbacks = append(feedbacks, interceptor.RTCPFeedback{Type: f.Type, Parameter: f.Parameter}) - } - - return &interceptor.StreamInfo{ - ID: id, - Attributes: interceptor.Attributes{}, - SSRC: uint32(ssrc), - PayloadType: uint8(payloadType), - RTPHeaderExtensions: headerExtensions, - MimeType: codec.MimeType, - ClockRate: codec.ClockRate, - Channels: codec.Channels, - SDPFmtpLine: codec.SDPFmtpLine, - RTCPFeedback: feedbacks, - } -} diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go b/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go deleted file mode 100644 index 5461c019..00000000 --- a/vendor/github.com/pion/webrtc/v3/internal/fmtp/fmtp.go +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package fmtp implements per codec parsing of fmtp lines -package fmtp - -import ( - "strings" -) - -// FMTP interface for implementing custom -// FMTP parsers based on MimeType -type FMTP interface { - // MimeType returns the MimeType associated with - // the fmtp - MimeType() string - // Match compares two fmtp descriptions for - // compatibility based on the MimeType - Match(f FMTP) bool - // Parameter returns a value for the associated key - // if contained in the parsed fmtp string - Parameter(key string) (string, bool) -} - -// Parse parses an fmtp string based on the MimeType -func Parse(mimetype, line string) FMTP { - var f FMTP - - parameters := make(map[string]string) - - for _, p := range strings.Split(line, ";") { - pp := strings.SplitN(strings.TrimSpace(p), "=", 2) - key := strings.ToLower(pp[0]) - var value string - if len(pp) > 1 { - value = pp[1] - } - parameters[key] = value - } - - switch { - case strings.EqualFold(mimetype, "video/h264"): - f = &h264FMTP{ - parameters: parameters, - } - default: - f = &genericFMTP{ - mimeType: mimetype, - parameters: parameters, - } - } - - return f -} - -type genericFMTP struct { - mimeType string - parameters map[string]string -} - -func (g *genericFMTP) MimeType() string { - return g.mimeType -} - -// Match returns true if g and b are compatible fmtp descriptions -// The generic implementation is used for MimeTypes that are not defined -func (g *genericFMTP) Match(b FMTP) bool { - c, ok := b.(*genericFMTP) - if !ok { - return false - } - - if !strings.EqualFold(g.mimeType, c.MimeType()) { - return false - } - - for k, v := range g.parameters { - if vb, ok := c.parameters[k]; ok && !strings.EqualFold(vb, v) { - return false - } - } - - for k, v := range c.parameters { - if va, ok := g.parameters[k]; ok && !strings.EqualFold(va, v) { - return false - } - } - - return true -} - -func (g *genericFMTP) Parameter(key string) (string, bool) { - v, ok := g.parameters[key] - return v, ok -} diff --git a/vendor/github.com/pion/webrtc/v3/internal/fmtp/h264.go b/vendor/github.com/pion/webrtc/v3/internal/fmtp/h264.go deleted file mode 100644 index b89b97aa..00000000 --- a/vendor/github.com/pion/webrtc/v3/internal/fmtp/h264.go +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package fmtp - -import ( - "encoding/hex" -) - -func profileLevelIDMatches(a, b string) bool { - aa, err := hex.DecodeString(a) - if err != nil || len(aa) < 2 { - return false - } - bb, err := hex.DecodeString(b) - if err != nil || len(bb) < 2 { - return false - } - return aa[0] == bb[0] && aa[1] == bb[1] -} - -type h264FMTP struct { - parameters map[string]string -} - -func (h *h264FMTP) MimeType() string { - return "video/h264" -} - -// Match returns true if h and b are compatible fmtp descriptions -// Based on RFC6184 Section 8.2.2: -// -// The parameters identifying a media format configuration for H.264 -// are profile-level-id and packetization-mode. These media format -// configuration parameters (except for the level part of profile- -// level-id) MUST be used symmetrically; that is, the answerer MUST -// either maintain all configuration parameters or remove the media -// format (payload type) completely if one or more of the parameter -// values are not supported. -// Informative note: The requirement for symmetric use does not -// apply for the level part of profile-level-id and does not apply -// for the other stream properties and capability parameters. -func (h *h264FMTP) Match(b FMTP) bool { - c, ok := b.(*h264FMTP) - if !ok { - return false - } - - // test packetization-mode - hpmode, hok := h.parameters["packetization-mode"] - if !hok { - return false - } - cpmode, cok := c.parameters["packetization-mode"] - if !cok { - return false - } - - if hpmode != cpmode { - return false - } - - // test profile-level-id - hplid, hok := h.parameters["profile-level-id"] - if !hok { - return false - } - - cplid, cok := c.parameters["profile-level-id"] - if !cok { - return false - } - - if !profileLevelIDMatches(hplid, cplid) { - return false - } - - return true -} - -func (h *h264FMTP) Parameter(key string) (string, bool) { - v, ok := h.parameters[key] - return v, ok -} diff --git a/vendor/github.com/pion/webrtc/v3/internal/mux/endpoint.go b/vendor/github.com/pion/webrtc/v3/internal/mux/endpoint.go deleted file mode 100644 index 3f53d16c..00000000 --- a/vendor/github.com/pion/webrtc/v3/internal/mux/endpoint.go +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package mux - -import ( - "errors" - "io" - "net" - "time" - - "github.com/pion/ice/v2" - "github.com/pion/transport/v2/packetio" -) - -// Endpoint implements net.Conn. It is used to read muxed packets. -type Endpoint struct { - mux *Mux - buffer *packetio.Buffer -} - -// Close unregisters the endpoint from the Mux -func (e *Endpoint) Close() (err error) { - err = e.close() - if err != nil { - return err - } - - e.mux.RemoveEndpoint(e) - return nil -} - -func (e *Endpoint) close() error { - return e.buffer.Close() -} - -// Read reads a packet of len(p) bytes from the underlying conn -// that are matched by the associated MuxFunc -func (e *Endpoint) Read(p []byte) (int, error) { - return e.buffer.Read(p) -} - -// Write writes len(p) bytes to the underlying conn -func (e *Endpoint) Write(p []byte) (int, error) { - n, err := e.mux.nextConn.Write(p) - if errors.Is(err, ice.ErrNoCandidatePairs) { - return 0, nil - } else if errors.Is(err, ice.ErrClosed) { - return 0, io.ErrClosedPipe - } - - return n, err -} - -// LocalAddr is a stub -func (e *Endpoint) LocalAddr() net.Addr { - return e.mux.nextConn.LocalAddr() -} - -// RemoteAddr is a stub -func (e *Endpoint) RemoteAddr() net.Addr { - return e.mux.nextConn.RemoteAddr() -} - -// SetDeadline is a stub -func (e *Endpoint) SetDeadline(time.Time) error { - return nil -} - -// SetReadDeadline is a stub -func (e *Endpoint) SetReadDeadline(time.Time) error { - return nil -} - -// SetWriteDeadline is a stub -func (e *Endpoint) SetWriteDeadline(time.Time) error { - return nil -} diff --git a/vendor/github.com/pion/webrtc/v3/internal/mux/mux.go b/vendor/github.com/pion/webrtc/v3/internal/mux/mux.go deleted file mode 100644 index 1e167b89..00000000 --- a/vendor/github.com/pion/webrtc/v3/internal/mux/mux.go +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package mux multiplexes packets on a single socket (RFC7983) -package mux - -import ( - "errors" - "io" - "net" - "sync" - - "github.com/pion/ice/v2" - "github.com/pion/logging" - "github.com/pion/transport/v2/packetio" -) - -// The maximum amount of data that can be buffered before returning errors. -const maxBufferSize = 1000 * 1000 // 1MB - -// Config collects the arguments to mux.Mux construction into -// a single structure -type Config struct { - Conn net.Conn - BufferSize int - LoggerFactory logging.LoggerFactory -} - -// Mux allows multiplexing -type Mux struct { - lock sync.RWMutex - nextConn net.Conn - endpoints map[*Endpoint]MatchFunc - bufferSize int - closedCh chan struct{} - - log logging.LeveledLogger -} - -// NewMux creates a new Mux -func NewMux(config Config) *Mux { - m := &Mux{ - nextConn: config.Conn, - endpoints: make(map[*Endpoint]MatchFunc), - bufferSize: config.BufferSize, - closedCh: make(chan struct{}), - log: config.LoggerFactory.NewLogger("mux"), - } - - go m.readLoop() - - return m -} - -// NewEndpoint creates a new Endpoint -func (m *Mux) NewEndpoint(f MatchFunc) *Endpoint { - e := &Endpoint{ - mux: m, - buffer: packetio.NewBuffer(), - } - - // Set a maximum size of the buffer in bytes. - e.buffer.SetLimitSize(maxBufferSize) - - m.lock.Lock() - m.endpoints[e] = f - m.lock.Unlock() - - return e -} - -// RemoveEndpoint removes an endpoint from the Mux -func (m *Mux) RemoveEndpoint(e *Endpoint) { - m.lock.Lock() - defer m.lock.Unlock() - delete(m.endpoints, e) -} - -// Close closes the Mux and all associated Endpoints. -func (m *Mux) Close() error { - m.lock.Lock() - for e := range m.endpoints { - if err := e.close(); err != nil { - m.lock.Unlock() - return err - } - - delete(m.endpoints, e) - } - m.lock.Unlock() - - err := m.nextConn.Close() - if err != nil { - return err - } - - // Wait for readLoop to end - <-m.closedCh - - return nil -} - -func (m *Mux) readLoop() { - defer func() { - close(m.closedCh) - }() - - buf := make([]byte, m.bufferSize) - for { - n, err := m.nextConn.Read(buf) - switch { - case errors.Is(err, io.EOF), errors.Is(err, ice.ErrClosed): - return - case errors.Is(err, io.ErrShortBuffer), errors.Is(err, packetio.ErrTimeout): - m.log.Errorf("mux: failed to read from packetio.Buffer %s", err.Error()) - continue - case err != nil: - m.log.Errorf("mux: ending readLoop packetio.Buffer error %s", err.Error()) - return - } - - if err = m.dispatch(buf[:n]); err != nil { - m.log.Errorf("mux: ending readLoop dispatch error %s", err.Error()) - return - } - } -} - -func (m *Mux) dispatch(buf []byte) error { - var endpoint *Endpoint - - m.lock.Lock() - for e, f := range m.endpoints { - if f(buf) { - endpoint = e - break - } - } - m.lock.Unlock() - - if endpoint == nil { - if len(buf) > 0 { - m.log.Warnf("Warning: mux: no endpoint for packet starting with %d", buf[0]) - } else { - m.log.Warnf("Warning: mux: no endpoint for zero length packet") - } - return nil - } - - _, err := endpoint.buffer.Write(buf) - - // Expected when bytes are received faster than the endpoint can process them (#2152, #2180) - if errors.Is(err, packetio.ErrFull) { - m.log.Infof("mux: endpoint buffer is full, dropping packet") - return nil - } - - return err -} diff --git a/vendor/github.com/pion/webrtc/v3/internal/mux/muxfunc.go b/vendor/github.com/pion/webrtc/v3/internal/mux/muxfunc.go deleted file mode 100644 index 69c3d14c..00000000 --- a/vendor/github.com/pion/webrtc/v3/internal/mux/muxfunc.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package mux - -// MatchFunc allows custom logic for mapping packets to an Endpoint -type MatchFunc func([]byte) bool - -// MatchAll always returns true -func MatchAll([]byte) bool { - return true -} - -// MatchRange returns true if the first byte of buf is in [lower..upper] -func MatchRange(lower, upper byte, buf []byte) bool { - if len(buf) < 1 { - return false - } - b := buf[0] - return b >= lower && b <= upper -} - -// MatchFuncs as described in RFC7983 -// https://tools.ietf.org/html/rfc7983 -// +----------------+ -// | [0..3] -+--> forward to STUN -// | | -// | [16..19] -+--> forward to ZRTP -// | | -// packet --> | [20..63] -+--> forward to DTLS -// | | -// | [64..79] -+--> forward to TURN Channel -// | | -// | [128..191] -+--> forward to RTP/RTCP -// +----------------+ - -// MatchDTLS is a MatchFunc that accepts packets with the first byte in [20..63] -// as defied in RFC7983 -func MatchDTLS(b []byte) bool { - return MatchRange(20, 63, b) -} - -// MatchSRTPOrSRTCP is a MatchFunc that accepts packets with the first byte in [128..191] -// as defied in RFC7983 -func MatchSRTPOrSRTCP(b []byte) bool { - return MatchRange(128, 191, b) -} - -func isRTCP(buf []byte) bool { - // Not long enough to determine RTP/RTCP - if len(buf) < 4 { - return false - } - return buf[1] >= 192 && buf[1] <= 223 -} - -// MatchSRTP is a MatchFunc that only matches SRTP and not SRTCP -func MatchSRTP(buf []byte) bool { - return MatchSRTPOrSRTCP(buf) && !isRTCP(buf) -} - -// MatchSRTCP is a MatchFunc that only matches SRTCP and not SRTP -func MatchSRTCP(buf []byte) bool { - return MatchSRTPOrSRTCP(buf) && isRTCP(buf) -} diff --git a/vendor/github.com/pion/webrtc/v3/internal/util/util.go b/vendor/github.com/pion/webrtc/v3/internal/util/util.go deleted file mode 100644 index 3f43c123..00000000 --- a/vendor/github.com/pion/webrtc/v3/internal/util/util.go +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package util provides auxiliary functions internally used in webrtc package -package util - -import ( - "errors" - "strings" - - "github.com/pion/randutil" -) - -const ( - runesAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -) - -// Use global random generator to properly seed by crypto grade random. -var globalMathRandomGenerator = randutil.NewMathRandomGenerator() // nolint:gochecknoglobals - -// MathRandAlpha generates a mathmatical random alphabet sequence of the requested length. -func MathRandAlpha(n int) string { - return globalMathRandomGenerator.GenerateString(n, runesAlpha) -} - -// RandUint32 generates a mathmatical random uint32. -func RandUint32() uint32 { - return globalMathRandomGenerator.Uint32() -} - -// FlattenErrs flattens multiple errors into one -func FlattenErrs(errs []error) error { - errs2 := []error{} - for _, e := range errs { - if e != nil { - errs2 = append(errs2, e) - } - } - if len(errs2) == 0 { - return nil - } - return multiError(errs2) -} - -type multiError []error //nolint:errname - -func (me multiError) Error() string { - var errstrings []string - - for _, err := range me { - if err != nil { - errstrings = append(errstrings, err.Error()) - } - } - - if len(errstrings) == 0 { - return "multiError must contain multiple error but is empty" - } - - return strings.Join(errstrings, "\n") -} - -func (me multiError) Is(err error) bool { - for _, e := range me { - if errors.Is(e, err) { - return true - } - if me2, ok := e.(multiError); ok { //nolint:errorlint - if me2.Is(err) { - return true - } - } - } - return false -} diff --git a/vendor/github.com/pion/webrtc/v3/js_utils.go b/vendor/github.com/pion/webrtc/v3/js_utils.go deleted file mode 100644 index 7e7b5e19..00000000 --- a/vendor/github.com/pion/webrtc/v3/js_utils.go +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import ( - "fmt" - "syscall/js" -) - -// awaitPromise accepts a js.Value representing a Promise. If the promise -// resolves, it returns (result, nil). If the promise rejects, it returns -// (js.Undefined, error). awaitPromise has a synchronous-like API but does not -// block the JavaScript event loop. -func awaitPromise(promise js.Value) (js.Value, error) { - resultsChan := make(chan js.Value) - errChan := make(chan js.Error) - - thenFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go func() { - resultsChan <- args[0] - }() - return js.Undefined() - }) - defer thenFunc.Release() - - catchFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go func() { - errChan <- js.Error{args[0]} - }() - return js.Undefined() - }) - defer catchFunc.Release() - - promise.Call("then", thenFunc).Call("catch", catchFunc) - - select { - case result := <-resultsChan: - return result, nil - case err := <-errChan: - return js.Undefined(), err - } -} - -func valueToUint16Pointer(val js.Value) *uint16 { - if val.IsNull() || val.IsUndefined() { - return nil - } - convertedVal := uint16(val.Int()) - return &convertedVal -} - -func valueToStringPointer(val js.Value) *string { - if val.IsNull() || val.IsUndefined() { - return nil - } - stringVal := val.String() - return &stringVal -} - -func stringToValueOrUndefined(val string) js.Value { - if val == "" { - return js.Undefined() - } - return js.ValueOf(val) -} - -func uint8ToValueOrUndefined(val uint8) js.Value { - if val == 0 { - return js.Undefined() - } - return js.ValueOf(val) -} - -func interfaceToValueOrUndefined(val interface{}) js.Value { - if val == nil { - return js.Undefined() - } - return js.ValueOf(val) -} - -func valueToStringOrZero(val js.Value) string { - if val.IsUndefined() || val.IsNull() { - return "" - } - return val.String() -} - -func valueToUint8OrZero(val js.Value) uint8 { - if val.IsUndefined() || val.IsNull() { - return 0 - } - return uint8(val.Int()) -} - -func valueToUint16OrZero(val js.Value) uint16 { - if val.IsNull() || val.IsUndefined() { - return 0 - } - return uint16(val.Int()) -} - -func valueToUint32OrZero(val js.Value) uint32 { - if val.IsNull() || val.IsUndefined() { - return 0 - } - return uint32(val.Int()) -} - -func valueToStrings(val js.Value) []string { - result := make([]string, val.Length()) - for i := 0; i < val.Length(); i++ { - result[i] = val.Index(i).String() - } - return result -} - -func stringPointerToValue(val *string) js.Value { - if val == nil { - return js.Undefined() - } - return js.ValueOf(*val) -} - -func uint16PointerToValue(val *uint16) js.Value { - if val == nil { - return js.Undefined() - } - return js.ValueOf(*val) -} - -func boolPointerToValue(val *bool) js.Value { - if val == nil { - return js.Undefined() - } - return js.ValueOf(*val) -} - -func stringsToValue(strings []string) js.Value { - val := make([]interface{}, len(strings)) - for i, s := range strings { - val[i] = s - } - return js.ValueOf(val) -} - -func stringEnumToValueOrUndefined(s string) js.Value { - if s == "unknown" { - return js.Undefined() - } - return js.ValueOf(s) -} - -// Converts the return value of recover() to an error. -func recoveryToError(e interface{}) error { - switch e := e.(type) { - case error: - return e - default: - return fmt.Errorf("recovered with non-error value: (%T) %s", e, e) - } -} - -func uint8ArrayValueToBytes(val js.Value) []byte { - result := make([]byte, val.Length()) - js.CopyBytesToGo(result, val) - - return result -} diff --git a/vendor/github.com/pion/webrtc/v3/mediaengine.go b/vendor/github.com/pion/webrtc/v3/mediaengine.go deleted file mode 100644 index c824d1ed..00000000 --- a/vendor/github.com/pion/webrtc/v3/mediaengine.go +++ /dev/null @@ -1,653 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "fmt" - "strconv" - "strings" - "sync" - "time" - - "github.com/pion/rtp" - "github.com/pion/rtp/codecs" - "github.com/pion/sdp/v3" - "github.com/pion/webrtc/v3/internal/fmtp" -) - -const ( - // MimeTypeH264 H264 MIME type. - // Note: Matching should be case insensitive. - MimeTypeH264 = "video/H264" - // MimeTypeH265 H265 MIME type - // Note: Matching should be case insensitive. - MimeTypeH265 = "video/H265" - // MimeTypeOpus Opus MIME type - // Note: Matching should be case insensitive. - MimeTypeOpus = "audio/opus" - // MimeTypeVP8 VP8 MIME type - // Note: Matching should be case insensitive. - MimeTypeVP8 = "video/VP8" - // MimeTypeVP9 VP9 MIME type - // Note: Matching should be case insensitive. - MimeTypeVP9 = "video/VP9" - // MimeTypeAV1 AV1 MIME type - // Note: Matching should be case insensitive. - MimeTypeAV1 = "video/AV1" - // MimeTypeG722 G722 MIME type - // Note: Matching should be case insensitive. - MimeTypeG722 = "audio/G722" - // MimeTypePCMU PCMU MIME type - // Note: Matching should be case insensitive. - MimeTypePCMU = "audio/PCMU" - // MimeTypePCMA PCMA MIME type - // Note: Matching should be case insensitive. - MimeTypePCMA = "audio/PCMA" -) - -type mediaEngineHeaderExtension struct { - uri string - isAudio, isVideo bool - - // If set only Transceivers of this direction are allowed - allowedDirections []RTPTransceiverDirection -} - -// A MediaEngine defines the codecs supported by a PeerConnection, and the -// configuration of those codecs. -type MediaEngine struct { - // If we have attempted to negotiate a codec type yet. - negotiatedVideo, negotiatedAudio bool - - videoCodecs, audioCodecs []RTPCodecParameters - negotiatedVideoCodecs, negotiatedAudioCodecs []RTPCodecParameters - - headerExtensions []mediaEngineHeaderExtension - negotiatedHeaderExtensions map[int]mediaEngineHeaderExtension - - mu sync.RWMutex -} - -// RegisterDefaultCodecs registers the default codecs supported by Pion WebRTC. -// RegisterDefaultCodecs is not safe for concurrent use. -func (m *MediaEngine) RegisterDefaultCodecs() error { - // Default Pion Audio Codecs - for _, codec := range []RTPCodecParameters{ - { - RTPCodecCapability: RTPCodecCapability{MimeTypeOpus, 48000, 2, "minptime=10;useinbandfec=1", nil}, - PayloadType: 111, - }, - { - RTPCodecCapability: RTPCodecCapability{MimeTypeG722, 8000, 0, "", nil}, - PayloadType: 9, - }, - { - RTPCodecCapability: RTPCodecCapability{MimeTypePCMU, 8000, 0, "", nil}, - PayloadType: 0, - }, - { - RTPCodecCapability: RTPCodecCapability{MimeTypePCMA, 8000, 0, "", nil}, - PayloadType: 8, - }, - } { - if err := m.RegisterCodec(codec, RTPCodecTypeAudio); err != nil { - return err - } - } - - videoRTCPFeedback := []RTCPFeedback{{"goog-remb", ""}, {"ccm", "fir"}, {"nack", ""}, {"nack", "pli"}} - for _, codec := range []RTPCodecParameters{ - { - RTPCodecCapability: RTPCodecCapability{MimeTypeVP8, 90000, 0, "", videoRTCPFeedback}, - PayloadType: 96, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=96", nil}, - PayloadType: 97, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeVP9, 90000, 0, "profile-id=0", videoRTCPFeedback}, - PayloadType: 98, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=98", nil}, - PayloadType: 99, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeVP9, 90000, 0, "profile-id=1", videoRTCPFeedback}, - PayloadType: 100, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=100", nil}, - PayloadType: 101, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", videoRTCPFeedback}, - PayloadType: 102, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=102", nil}, - PayloadType: 121, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f", videoRTCPFeedback}, - PayloadType: 127, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=127", nil}, - PayloadType: 120, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f", videoRTCPFeedback}, - PayloadType: 125, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=125", nil}, - PayloadType: 107, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f", videoRTCPFeedback}, - PayloadType: 108, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=108", nil}, - PayloadType: 109, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f", videoRTCPFeedback}, - PayloadType: 127, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=127", nil}, - PayloadType: 120, - }, - - { - RTPCodecCapability: RTPCodecCapability{MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032", videoRTCPFeedback}, - PayloadType: 123, - }, - { - RTPCodecCapability: RTPCodecCapability{"video/rtx", 90000, 0, "apt=123", nil}, - PayloadType: 118, - }, - - { - RTPCodecCapability: RTPCodecCapability{"video/ulpfec", 90000, 0, "", nil}, - PayloadType: 116, - }, - } { - if err := m.RegisterCodec(codec, RTPCodecTypeVideo); err != nil { - return err - } - } - - return nil -} - -// addCodec will append codec if it not exists -func (m *MediaEngine) addCodec(codecs []RTPCodecParameters, codec RTPCodecParameters) []RTPCodecParameters { - for _, c := range codecs { - if c.MimeType == codec.MimeType && c.PayloadType == codec.PayloadType { - return codecs - } - } - return append(codecs, codec) -} - -// RegisterCodec adds codec to the MediaEngine -// These are the list of codecs supported by this PeerConnection. -// RegisterCodec is not safe for concurrent use. -func (m *MediaEngine) RegisterCodec(codec RTPCodecParameters, typ RTPCodecType) error { - m.mu.Lock() - defer m.mu.Unlock() - - codec.statsID = fmt.Sprintf("RTPCodec-%d", time.Now().UnixNano()) - switch typ { - case RTPCodecTypeAudio: - m.audioCodecs = m.addCodec(m.audioCodecs, codec) - case RTPCodecTypeVideo: - m.videoCodecs = m.addCodec(m.videoCodecs, codec) - default: - return ErrUnknownType - } - return nil -} - -// RegisterHeaderExtension adds a header extension to the MediaEngine -// To determine the negotiated value use `GetHeaderExtensionID` after signaling is complete -func (m *MediaEngine) RegisterHeaderExtension(extension RTPHeaderExtensionCapability, typ RTPCodecType, allowedDirections ...RTPTransceiverDirection) error { - m.mu.Lock() - defer m.mu.Unlock() - - if m.negotiatedHeaderExtensions == nil { - m.negotiatedHeaderExtensions = map[int]mediaEngineHeaderExtension{} - } - - if len(allowedDirections) == 0 { - allowedDirections = []RTPTransceiverDirection{RTPTransceiverDirectionRecvonly, RTPTransceiverDirectionSendonly} - } - - for _, direction := range allowedDirections { - if direction != RTPTransceiverDirectionRecvonly && direction != RTPTransceiverDirectionSendonly { - return ErrRegisterHeaderExtensionInvalidDirection - } - } - - extensionIndex := -1 - for i := range m.headerExtensions { - if extension.URI == m.headerExtensions[i].uri { - extensionIndex = i - } - } - - if extensionIndex == -1 { - m.headerExtensions = append(m.headerExtensions, mediaEngineHeaderExtension{}) - extensionIndex = len(m.headerExtensions) - 1 - } - - if typ == RTPCodecTypeAudio { - m.headerExtensions[extensionIndex].isAudio = true - } else if typ == RTPCodecTypeVideo { - m.headerExtensions[extensionIndex].isVideo = true - } - - m.headerExtensions[extensionIndex].uri = extension.URI - m.headerExtensions[extensionIndex].allowedDirections = allowedDirections - - return nil -} - -// RegisterFeedback adds feedback mechanism to already registered codecs. -func (m *MediaEngine) RegisterFeedback(feedback RTCPFeedback, typ RTPCodecType) { - m.mu.Lock() - defer m.mu.Unlock() - - switch typ { - case RTPCodecTypeVideo: - for i, v := range m.videoCodecs { - v.RTCPFeedback = append(v.RTCPFeedback, feedback) - m.videoCodecs[i] = v - } - case RTPCodecTypeAudio: - for i, v := range m.audioCodecs { - v.RTCPFeedback = append(v.RTCPFeedback, feedback) - m.audioCodecs[i] = v - } - } -} - -// getHeaderExtensionID returns the negotiated ID for a header extension. -// If the Header Extension isn't enabled ok will be false -func (m *MediaEngine) getHeaderExtensionID(extension RTPHeaderExtensionCapability) (val int, audioNegotiated, videoNegotiated bool) { - m.mu.RLock() - defer m.mu.RUnlock() - - if m.negotiatedHeaderExtensions == nil { - return 0, false, false - } - - for id, h := range m.negotiatedHeaderExtensions { - if extension.URI == h.uri { - return id, h.isAudio, h.isVideo - } - } - - return -} - -// copy copies any user modifiable state of the MediaEngine -// all internal state is reset -func (m *MediaEngine) copy() *MediaEngine { - m.mu.Lock() - defer m.mu.Unlock() - cloned := &MediaEngine{ - videoCodecs: append([]RTPCodecParameters{}, m.videoCodecs...), - audioCodecs: append([]RTPCodecParameters{}, m.audioCodecs...), - headerExtensions: append([]mediaEngineHeaderExtension{}, m.headerExtensions...), - } - if len(m.headerExtensions) > 0 { - cloned.negotiatedHeaderExtensions = map[int]mediaEngineHeaderExtension{} - } - return cloned -} - -func findCodecByPayload(codecs []RTPCodecParameters, payloadType PayloadType) *RTPCodecParameters { - for _, codec := range codecs { - if codec.PayloadType == payloadType { - return &codec - } - } - return nil -} - -func (m *MediaEngine) getCodecByPayload(payloadType PayloadType) (RTPCodecParameters, RTPCodecType, error) { - m.mu.RLock() - defer m.mu.RUnlock() - - // if we've negotiated audio or video, check the negotiated types before our - // built-in payload types, to ensure we pick the codec the other side wants. - if m.negotiatedVideo { - if codec := findCodecByPayload(m.negotiatedVideoCodecs, payloadType); codec != nil { - return *codec, RTPCodecTypeVideo, nil - } - } - if m.negotiatedAudio { - if codec := findCodecByPayload(m.negotiatedAudioCodecs, payloadType); codec != nil { - return *codec, RTPCodecTypeAudio, nil - } - } - if !m.negotiatedVideo { - if codec := findCodecByPayload(m.videoCodecs, payloadType); codec != nil { - return *codec, RTPCodecTypeVideo, nil - } - } - if !m.negotiatedAudio { - if codec := findCodecByPayload(m.audioCodecs, payloadType); codec != nil { - return *codec, RTPCodecTypeAudio, nil - } - } - - return RTPCodecParameters{}, 0, ErrCodecNotFound -} - -func (m *MediaEngine) collectStats(collector *statsReportCollector) { - m.mu.RLock() - defer m.mu.RUnlock() - - statsLoop := func(codecs []RTPCodecParameters) { - for _, codec := range codecs { - collector.Collecting() - stats := CodecStats{ - Timestamp: statsTimestampFrom(time.Now()), - Type: StatsTypeCodec, - ID: codec.statsID, - PayloadType: codec.PayloadType, - MimeType: codec.MimeType, - ClockRate: codec.ClockRate, - Channels: uint8(codec.Channels), - SDPFmtpLine: codec.SDPFmtpLine, - } - - collector.Collect(stats.ID, stats) - } - } - - statsLoop(m.videoCodecs) - statsLoop(m.audioCodecs) -} - -// Look up a codec and enable if it exists -func (m *MediaEngine) matchRemoteCodec(remoteCodec RTPCodecParameters, typ RTPCodecType, exactMatches, partialMatches []RTPCodecParameters) (codecMatchType, error) { - codecs := m.videoCodecs - if typ == RTPCodecTypeAudio { - codecs = m.audioCodecs - } - - remoteFmtp := fmtp.Parse(remoteCodec.RTPCodecCapability.MimeType, remoteCodec.RTPCodecCapability.SDPFmtpLine) - if apt, hasApt := remoteFmtp.Parameter("apt"); hasApt { - payloadType, err := strconv.ParseUint(apt, 10, 8) - if err != nil { - return codecMatchNone, err - } - - aptMatch := codecMatchNone - for _, codec := range exactMatches { - if codec.PayloadType == PayloadType(payloadType) { - aptMatch = codecMatchExact - break - } - } - - if aptMatch == codecMatchNone { - for _, codec := range partialMatches { - if codec.PayloadType == PayloadType(payloadType) { - aptMatch = codecMatchPartial - break - } - } - } - - if aptMatch == codecMatchNone { - return codecMatchNone, nil // not an error, we just ignore this codec we don't support - } - - // if apt's media codec is partial match, then apt codec must be partial match too - _, matchType := codecParametersFuzzySearch(remoteCodec, codecs) - if matchType == codecMatchExact && aptMatch == codecMatchPartial { - matchType = codecMatchPartial - } - return matchType, nil - } - - _, matchType := codecParametersFuzzySearch(remoteCodec, codecs) - return matchType, nil -} - -// Look up a header extension and enable if it exists -func (m *MediaEngine) updateHeaderExtension(id int, extension string, typ RTPCodecType) error { - if m.negotiatedHeaderExtensions == nil { - return nil - } - - for _, localExtension := range m.headerExtensions { - if localExtension.uri == extension { - h := mediaEngineHeaderExtension{uri: extension, allowedDirections: localExtension.allowedDirections} - if existingValue, ok := m.negotiatedHeaderExtensions[id]; ok { - h = existingValue - } - - switch { - case localExtension.isAudio && typ == RTPCodecTypeAudio: - h.isAudio = true - case localExtension.isVideo && typ == RTPCodecTypeVideo: - h.isVideo = true - } - - m.negotiatedHeaderExtensions[id] = h - } - } - return nil -} - -func (m *MediaEngine) pushCodecs(codecs []RTPCodecParameters, typ RTPCodecType) { - for _, codec := range codecs { - if typ == RTPCodecTypeAudio { - m.negotiatedAudioCodecs = m.addCodec(m.negotiatedAudioCodecs, codec) - } else if typ == RTPCodecTypeVideo { - m.negotiatedVideoCodecs = m.addCodec(m.negotiatedVideoCodecs, codec) - } - } -} - -// Update the MediaEngine from a remote description -func (m *MediaEngine) updateFromRemoteDescription(desc sdp.SessionDescription) error { - m.mu.Lock() - defer m.mu.Unlock() - - for _, media := range desc.MediaDescriptions { - var typ RTPCodecType - switch { - case !m.negotiatedAudio && strings.EqualFold(media.MediaName.Media, "audio"): - m.negotiatedAudio = true - typ = RTPCodecTypeAudio - case !m.negotiatedVideo && strings.EqualFold(media.MediaName.Media, "video"): - m.negotiatedVideo = true - typ = RTPCodecTypeVideo - default: - continue - } - - codecs, err := codecsFromMediaDescription(media) - if err != nil { - return err - } - - exactMatches := make([]RTPCodecParameters, 0, len(codecs)) - partialMatches := make([]RTPCodecParameters, 0, len(codecs)) - - for _, codec := range codecs { - matchType, mErr := m.matchRemoteCodec(codec, typ, exactMatches, partialMatches) - if mErr != nil { - return mErr - } - - if matchType == codecMatchExact { - exactMatches = append(exactMatches, codec) - } else if matchType == codecMatchPartial { - partialMatches = append(partialMatches, codec) - } - } - - // use exact matches when they exist, otherwise fall back to partial - switch { - case len(exactMatches) > 0: - m.pushCodecs(exactMatches, typ) - case len(partialMatches) > 0: - m.pushCodecs(partialMatches, typ) - default: - // no match, not negotiated - continue - } - - extensions, err := rtpExtensionsFromMediaDescription(media) - if err != nil { - return err - } - - for extension, id := range extensions { - if err = m.updateHeaderExtension(id, extension, typ); err != nil { - return err - } - } - } - return nil -} - -func (m *MediaEngine) getCodecsByKind(typ RTPCodecType) []RTPCodecParameters { - m.mu.RLock() - defer m.mu.RUnlock() - - if typ == RTPCodecTypeVideo { - if m.negotiatedVideo { - return m.negotiatedVideoCodecs - } - - return m.videoCodecs - } else if typ == RTPCodecTypeAudio { - if m.negotiatedAudio { - return m.negotiatedAudioCodecs - } - - return m.audioCodecs - } - - return nil -} - -func (m *MediaEngine) getRTPParametersByKind(typ RTPCodecType, directions []RTPTransceiverDirection) RTPParameters { //nolint:gocognit - headerExtensions := make([]RTPHeaderExtensionParameter, 0) - - // perform before locking to prevent recursive RLocks - foundCodecs := m.getCodecsByKind(typ) - - m.mu.RLock() - defer m.mu.RUnlock() - if m.negotiatedVideo && typ == RTPCodecTypeVideo || - m.negotiatedAudio && typ == RTPCodecTypeAudio { - for id, e := range m.negotiatedHeaderExtensions { - if haveRTPTransceiverDirectionIntersection(e.allowedDirections, directions) && (e.isAudio && typ == RTPCodecTypeAudio || e.isVideo && typ == RTPCodecTypeVideo) { - headerExtensions = append(headerExtensions, RTPHeaderExtensionParameter{ID: id, URI: e.uri}) - } - } - } else { - mediaHeaderExtensions := make(map[int]mediaEngineHeaderExtension) - for _, e := range m.headerExtensions { - usingNegotiatedID := false - for id := range m.negotiatedHeaderExtensions { - if m.negotiatedHeaderExtensions[id].uri == e.uri { - usingNegotiatedID = true - mediaHeaderExtensions[id] = e - break - } - } - if !usingNegotiatedID { - for id := 1; id < 15; id++ { - idAvailable := true - if _, ok := mediaHeaderExtensions[id]; ok { - idAvailable = false - } - if _, taken := m.negotiatedHeaderExtensions[id]; idAvailable && !taken { - mediaHeaderExtensions[id] = e - break - } - } - } - } - - for id, e := range mediaHeaderExtensions { - if haveRTPTransceiverDirectionIntersection(e.allowedDirections, directions) && (e.isAudio && typ == RTPCodecTypeAudio || e.isVideo && typ == RTPCodecTypeVideo) { - headerExtensions = append(headerExtensions, RTPHeaderExtensionParameter{ID: id, URI: e.uri}) - } - } - } - - return RTPParameters{ - HeaderExtensions: headerExtensions, - Codecs: foundCodecs, - } -} - -func (m *MediaEngine) getRTPParametersByPayloadType(payloadType PayloadType) (RTPParameters, error) { - codec, typ, err := m.getCodecByPayload(payloadType) - if err != nil { - return RTPParameters{}, err - } - - m.mu.RLock() - defer m.mu.RUnlock() - headerExtensions := make([]RTPHeaderExtensionParameter, 0) - for id, e := range m.negotiatedHeaderExtensions { - if e.isAudio && typ == RTPCodecTypeAudio || e.isVideo && typ == RTPCodecTypeVideo { - headerExtensions = append(headerExtensions, RTPHeaderExtensionParameter{ID: id, URI: e.uri}) - } - } - - return RTPParameters{ - HeaderExtensions: headerExtensions, - Codecs: []RTPCodecParameters{codec}, - }, nil -} - -func payloaderForCodec(codec RTPCodecCapability) (rtp.Payloader, error) { - switch strings.ToLower(codec.MimeType) { - case strings.ToLower(MimeTypeH264): - return &codecs.H264Payloader{}, nil - case strings.ToLower(MimeTypeOpus): - return &codecs.OpusPayloader{}, nil - case strings.ToLower(MimeTypeVP8): - return &codecs.VP8Payloader{ - EnablePictureID: true, - }, nil - case strings.ToLower(MimeTypeVP9): - return &codecs.VP9Payloader{}, nil - case strings.ToLower(MimeTypeAV1): - return &codecs.AV1Payloader{}, nil - case strings.ToLower(MimeTypeG722): - return &codecs.G722Payloader{}, nil - case strings.ToLower(MimeTypePCMU), strings.ToLower(MimeTypePCMA): - return &codecs.G711Payloader{}, nil - default: - return nil, ErrNoPayloaderForCodec - } -} diff --git a/vendor/github.com/pion/webrtc/v3/networktype.go b/vendor/github.com/pion/webrtc/v3/networktype.go deleted file mode 100644 index 601e73ff..00000000 --- a/vendor/github.com/pion/webrtc/v3/networktype.go +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "fmt" - - "github.com/pion/ice/v2" -) - -func supportedNetworkTypes() []NetworkType { - return []NetworkType{ - NetworkTypeUDP4, - NetworkTypeUDP6, - // NetworkTypeTCP4, // Not supported yet - // NetworkTypeTCP6, // Not supported yet - } -} - -// NetworkType represents the type of network -type NetworkType int - -const ( - // NetworkTypeUDP4 indicates UDP over IPv4. - NetworkTypeUDP4 NetworkType = iota + 1 - - // NetworkTypeUDP6 indicates UDP over IPv6. - NetworkTypeUDP6 - - // NetworkTypeTCP4 indicates TCP over IPv4. - NetworkTypeTCP4 - - // NetworkTypeTCP6 indicates TCP over IPv6. - NetworkTypeTCP6 -) - -// This is done this way because of a linter. -const ( - networkTypeUDP4Str = "udp4" - networkTypeUDP6Str = "udp6" - networkTypeTCP4Str = "tcp4" - networkTypeTCP6Str = "tcp6" -) - -func (t NetworkType) String() string { - switch t { - case NetworkTypeUDP4: - return networkTypeUDP4Str - case NetworkTypeUDP6: - return networkTypeUDP6Str - case NetworkTypeTCP4: - return networkTypeTCP4Str - case NetworkTypeTCP6: - return networkTypeTCP6Str - default: - return ErrUnknownType.Error() - } -} - -// Protocol returns udp or tcp -func (t NetworkType) Protocol() string { - switch t { - case NetworkTypeUDP4: - return "udp" - case NetworkTypeUDP6: - return "udp" - case NetworkTypeTCP4: - return "tcp" - case NetworkTypeTCP6: - return "tcp" - default: - return ErrUnknownType.Error() - } -} - -// NewNetworkType allows create network type from string -// It will be useful for getting custom network types from external config. -func NewNetworkType(raw string) (NetworkType, error) { - switch raw { - case networkTypeUDP4Str: - return NetworkTypeUDP4, nil - case networkTypeUDP6Str: - return NetworkTypeUDP6, nil - case networkTypeTCP4Str: - return NetworkTypeTCP4, nil - case networkTypeTCP6Str: - return NetworkTypeTCP6, nil - default: - return NetworkType(Unknown), fmt.Errorf("%w: %s", errNetworkTypeUnknown, raw) - } -} - -func getNetworkType(iceNetworkType ice.NetworkType) (NetworkType, error) { - switch iceNetworkType { - case ice.NetworkTypeUDP4: - return NetworkTypeUDP4, nil - case ice.NetworkTypeUDP6: - return NetworkTypeUDP6, nil - case ice.NetworkTypeTCP4: - return NetworkTypeTCP4, nil - case ice.NetworkTypeTCP6: - return NetworkTypeTCP6, nil - default: - return NetworkType(Unknown), fmt.Errorf("%w: %s", errNetworkTypeUnknown, iceNetworkType.String()) - } -} diff --git a/vendor/github.com/pion/webrtc/v3/oauthcredential.go b/vendor/github.com/pion/webrtc/v3/oauthcredential.go deleted file mode 100644 index 16210f9d..00000000 --- a/vendor/github.com/pion/webrtc/v3/oauthcredential.go +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// OAuthCredential represents OAuth credential information which is used by -// the STUN/TURN client to connect to an ICE server as defined in -// https://tools.ietf.org/html/rfc7635. Note that the kid parameter is not -// located in OAuthCredential, but in ICEServer's username member. -type OAuthCredential struct { - // MACKey is a base64-url encoded format. It is used in STUN message - // integrity hash calculation. - MACKey string - - // AccessToken is a base64-encoded format. This is an encrypted - // self-contained token that is opaque to the application. - AccessToken string -} diff --git a/vendor/github.com/pion/webrtc/v3/offeransweroptions.go b/vendor/github.com/pion/webrtc/v3/offeransweroptions.go deleted file mode 100644 index 52868897..00000000 --- a/vendor/github.com/pion/webrtc/v3/offeransweroptions.go +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// OfferAnswerOptions is a base structure which describes the options that -// can be used to control the offer/answer creation process. -type OfferAnswerOptions struct { - // VoiceActivityDetection allows the application to provide information - // about whether it wishes voice detection feature to be enabled or disabled. - VoiceActivityDetection bool -} - -// AnswerOptions structure describes the options used to control the answer -// creation process. -type AnswerOptions struct { - OfferAnswerOptions -} - -// OfferOptions structure describes the options used to control the offer -// creation process -type OfferOptions struct { - OfferAnswerOptions - - // ICERestart forces the underlying ice gathering process to be restarted. - // When this value is true, the generated description will have ICE - // credentials that are different from the current credentials - ICERestart bool -} diff --git a/vendor/github.com/pion/webrtc/v3/operations.go b/vendor/github.com/pion/webrtc/v3/operations.go deleted file mode 100644 index d9dca4a8..00000000 --- a/vendor/github.com/pion/webrtc/v3/operations.go +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "container/list" - "sync" -) - -// Operation is a function -type operation func() - -// Operations is a task executor. -type operations struct { - mu sync.Mutex - busy bool - ops *list.List -} - -func newOperations() *operations { - return &operations{ - ops: list.New(), - } -} - -// Enqueue adds a new action to be executed. If there are no actions scheduled, -// the execution will start immediately in a new goroutine. -func (o *operations) Enqueue(op operation) { - if op == nil { - return - } - - o.mu.Lock() - running := o.busy - o.ops.PushBack(op) - o.busy = true - o.mu.Unlock() - - if !running { - go o.start() - } -} - -// IsEmpty checks if there are tasks in the queue -func (o *operations) IsEmpty() bool { - o.mu.Lock() - defer o.mu.Unlock() - return o.ops.Len() == 0 -} - -// Done blocks until all currently enqueued operations are finished executing. -// For more complex synchronization, use Enqueue directly. -func (o *operations) Done() { - var wg sync.WaitGroup - wg.Add(1) - o.Enqueue(func() { - wg.Done() - }) - wg.Wait() -} - -func (o *operations) pop() func() { - o.mu.Lock() - defer o.mu.Unlock() - if o.ops.Len() == 0 { - return nil - } - - e := o.ops.Front() - o.ops.Remove(e) - if op, ok := e.Value.(operation); ok { - return op - } - return nil -} - -func (o *operations) start() { - defer func() { - o.mu.Lock() - defer o.mu.Unlock() - if o.ops.Len() == 0 { - o.busy = false - return - } - // either a new operation was enqueued while we - // were busy, or an operation panicked - go o.start() - }() - - fn := o.pop() - for fn != nil { - fn() - fn = o.pop() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/package.json b/vendor/github.com/pion/webrtc/v3/package.json deleted file mode 100644 index 429f3efb..00000000 --- a/vendor/github.com/pion/webrtc/v3/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "webrtc", - "repository": "git@github.com:pion/webrtc.git", - "private": true, - "devDependencies": { - "wrtc": "0.4.7" - }, - "dependencies": { - "request": "2.88.2" - } -} diff --git a/vendor/github.com/pion/webrtc/v3/peerconnection.go b/vendor/github.com/pion/webrtc/v3/peerconnection.go deleted file mode 100644 index b3c0ef42..00000000 --- a/vendor/github.com/pion/webrtc/v3/peerconnection.go +++ /dev/null @@ -1,2496 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "errors" - "fmt" - "io" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" - - "github.com/pion/ice/v2" - "github.com/pion/interceptor" - "github.com/pion/logging" - "github.com/pion/rtcp" - "github.com/pion/sdp/v3" - "github.com/pion/srtp/v2" - "github.com/pion/webrtc/v3/internal/util" - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -// PeerConnection represents a WebRTC connection that establishes a -// peer-to-peer communications with another PeerConnection instance in a -// browser, or to another endpoint implementing the required protocols. -type PeerConnection struct { - statsID string - mu sync.RWMutex - - sdpOrigin sdp.Origin - - // ops is an operations queue which will ensure the enqueued actions are - // executed in order. It is used for asynchronously, but serially processing - // remote and local descriptions - ops *operations - - configuration Configuration - - currentLocalDescription *SessionDescription - pendingLocalDescription *SessionDescription - currentRemoteDescription *SessionDescription - pendingRemoteDescription *SessionDescription - signalingState SignalingState - iceConnectionState atomic.Value // ICEConnectionState - connectionState atomic.Value // PeerConnectionState - - idpLoginURL *string - - isClosed *atomicBool - isNegotiationNeeded *atomicBool - negotiationNeededState negotiationNeededState - - lastOffer string - lastAnswer string - - // a value containing the last known greater mid value - // we internally generate mids as numbers. Needed since JSEP - // requires that when reusing a media section a new unique mid - // should be defined (see JSEP 3.4.1). - greaterMid int - - rtpTransceivers []*RTPTransceiver - - onSignalingStateChangeHandler func(SignalingState) - onICEConnectionStateChangeHandler atomic.Value // func(ICEConnectionState) - onConnectionStateChangeHandler atomic.Value // func(PeerConnectionState) - onTrackHandler func(*TrackRemote, *RTPReceiver) - onDataChannelHandler func(*DataChannel) - onNegotiationNeededHandler atomic.Value // func() - - iceGatherer *ICEGatherer - iceTransport *ICETransport - dtlsTransport *DTLSTransport - sctpTransport *SCTPTransport - - // A reference to the associated API state used by this connection - api *API - log logging.LeveledLogger - - interceptorRTCPWriter interceptor.RTCPWriter -} - -// NewPeerConnection creates a PeerConnection with the default codecs and -// interceptors. See RegisterDefaultCodecs and RegisterDefaultInterceptors. -// -// If you wish to customize the set of available codecs or the set of -// active interceptors, create a MediaEngine and call api.NewPeerConnection -// instead of this function. -func NewPeerConnection(configuration Configuration) (*PeerConnection, error) { - m := &MediaEngine{} - if err := m.RegisterDefaultCodecs(); err != nil { - return nil, err - } - - i := &interceptor.Registry{} - if err := RegisterDefaultInterceptors(m, i); err != nil { - return nil, err - } - - api := NewAPI(WithMediaEngine(m), WithInterceptorRegistry(i)) - return api.NewPeerConnection(configuration) -} - -// NewPeerConnection creates a new PeerConnection with the provided configuration against the received API object -func (api *API) NewPeerConnection(configuration Configuration) (*PeerConnection, error) { - // https://w3c.github.io/webrtc-pc/#constructor (Step #2) - // Some variables defined explicitly despite their implicit zero values to - // allow better readability to understand what is happening. - pc := &PeerConnection{ - statsID: fmt.Sprintf("PeerConnection-%d", time.Now().UnixNano()), - configuration: Configuration{ - ICEServers: []ICEServer{}, - ICETransportPolicy: ICETransportPolicyAll, - BundlePolicy: BundlePolicyBalanced, - RTCPMuxPolicy: RTCPMuxPolicyRequire, - Certificates: []Certificate{}, - ICECandidatePoolSize: 0, - }, - ops: newOperations(), - isClosed: &atomicBool{}, - isNegotiationNeeded: &atomicBool{}, - negotiationNeededState: negotiationNeededStateEmpty, - lastOffer: "", - lastAnswer: "", - greaterMid: -1, - signalingState: SignalingStateStable, - - api: api, - log: api.settingEngine.LoggerFactory.NewLogger("pc"), - } - pc.iceConnectionState.Store(ICEConnectionStateNew) - pc.connectionState.Store(PeerConnectionStateNew) - - i, err := api.interceptorRegistry.Build("") - if err != nil { - return nil, err - } - - pc.api = &API{ - settingEngine: api.settingEngine, - interceptor: i, - } - - if api.settingEngine.disableMediaEngineCopy { - pc.api.mediaEngine = api.mediaEngine - } else { - pc.api.mediaEngine = api.mediaEngine.copy() - } - - if err = pc.initConfiguration(configuration); err != nil { - return nil, err - } - - pc.iceGatherer, err = pc.createICEGatherer() - if err != nil { - return nil, err - } - - // Create the ice transport - iceTransport := pc.createICETransport() - pc.iceTransport = iceTransport - - // Create the DTLS transport - dtlsTransport, err := pc.api.NewDTLSTransport(pc.iceTransport, pc.configuration.Certificates) - if err != nil { - return nil, err - } - pc.dtlsTransport = dtlsTransport - - // Create the SCTP transport - pc.sctpTransport = pc.api.NewSCTPTransport(pc.dtlsTransport) - - // Wire up the on datachannel handler - pc.sctpTransport.OnDataChannel(func(d *DataChannel) { - pc.mu.RLock() - handler := pc.onDataChannelHandler - pc.mu.RUnlock() - if handler != nil { - handler(d) - } - }) - - pc.interceptorRTCPWriter = pc.api.interceptor.BindRTCPWriter(interceptor.RTCPWriterFunc(pc.writeRTCP)) - - return pc, nil -} - -// initConfiguration defines validation of the specified Configuration and -// its assignment to the internal configuration variable. This function differs -// from its SetConfiguration counterpart because most of the checks do not -// include verification statements related to the existing state. Thus the -// function describes only minor verification of some the struct variables. -func (pc *PeerConnection) initConfiguration(configuration Configuration) error { - if configuration.PeerIdentity != "" { - pc.configuration.PeerIdentity = configuration.PeerIdentity - } - - // https://www.w3.org/TR/webrtc/#constructor (step #3) - if len(configuration.Certificates) > 0 { - now := time.Now() - for _, x509Cert := range configuration.Certificates { - if !x509Cert.Expires().IsZero() && now.After(x509Cert.Expires()) { - return &rtcerr.InvalidAccessError{Err: ErrCertificateExpired} - } - pc.configuration.Certificates = append(pc.configuration.Certificates, x509Cert) - } - } else { - sk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return &rtcerr.UnknownError{Err: err} - } - certificate, err := GenerateCertificate(sk) - if err != nil { - return err - } - pc.configuration.Certificates = []Certificate{*certificate} - } - - if configuration.BundlePolicy != BundlePolicy(Unknown) { - pc.configuration.BundlePolicy = configuration.BundlePolicy - } - - if configuration.RTCPMuxPolicy != RTCPMuxPolicy(Unknown) { - pc.configuration.RTCPMuxPolicy = configuration.RTCPMuxPolicy - } - - if configuration.ICECandidatePoolSize != 0 { - pc.configuration.ICECandidatePoolSize = configuration.ICECandidatePoolSize - } - - if configuration.ICETransportPolicy != ICETransportPolicy(Unknown) { - pc.configuration.ICETransportPolicy = configuration.ICETransportPolicy - } - - if configuration.SDPSemantics != SDPSemantics(Unknown) { - pc.configuration.SDPSemantics = configuration.SDPSemantics - } - - sanitizedICEServers := configuration.getICEServers() - if len(sanitizedICEServers) > 0 { - for _, server := range sanitizedICEServers { - if err := server.validate(); err != nil { - return err - } - } - pc.configuration.ICEServers = sanitizedICEServers - } - - return nil -} - -// OnSignalingStateChange sets an event handler which is invoked when the -// peer connection's signaling state changes -func (pc *PeerConnection) OnSignalingStateChange(f func(SignalingState)) { - pc.mu.Lock() - defer pc.mu.Unlock() - pc.onSignalingStateChangeHandler = f -} - -func (pc *PeerConnection) onSignalingStateChange(newState SignalingState) { - pc.mu.RLock() - handler := pc.onSignalingStateChangeHandler - pc.mu.RUnlock() - - pc.log.Infof("signaling state changed to %s", newState) - if handler != nil { - go handler(newState) - } -} - -// OnDataChannel sets an event handler which is invoked when a data -// channel message arrives from a remote peer. -func (pc *PeerConnection) OnDataChannel(f func(*DataChannel)) { - pc.mu.Lock() - defer pc.mu.Unlock() - pc.onDataChannelHandler = f -} - -// OnNegotiationNeeded sets an event handler which is invoked when -// a change has occurred which requires session negotiation -func (pc *PeerConnection) OnNegotiationNeeded(f func()) { - pc.onNegotiationNeededHandler.Store(f) -} - -// onNegotiationNeeded enqueues negotiationNeededOp if necessary -// caller of this method should hold `pc.mu` lock -func (pc *PeerConnection) onNegotiationNeeded() { - // https://w3c.github.io/webrtc-pc/#updating-the-negotiation-needed-flag - // non-canon step 1 - if pc.negotiationNeededState == negotiationNeededStateRun { - pc.negotiationNeededState = negotiationNeededStateQueue - return - } else if pc.negotiationNeededState == negotiationNeededStateQueue { - return - } - pc.negotiationNeededState = negotiationNeededStateRun - pc.ops.Enqueue(pc.negotiationNeededOp) -} - -func (pc *PeerConnection) negotiationNeededOp() { - // Don't run NegotiatedNeeded checks if OnNegotiationNeeded is not set - if handler, ok := pc.onNegotiationNeededHandler.Load().(func()); !ok || handler == nil { - return - } - - // https://www.w3.org/TR/webrtc/#updating-the-negotiation-needed-flag - // Step 2.1 - if pc.isClosed.get() { - return - } - // non-canon step 2.2 - if !pc.ops.IsEmpty() { - pc.ops.Enqueue(pc.negotiationNeededOp) - return - } - - // non-canon, run again if there was a request - defer func() { - pc.mu.Lock() - defer pc.mu.Unlock() - if pc.negotiationNeededState == negotiationNeededStateQueue { - defer pc.onNegotiationNeeded() - } - pc.negotiationNeededState = negotiationNeededStateEmpty - }() - - // Step 2.3 - if pc.SignalingState() != SignalingStateStable { - return - } - - // Step 2.4 - if !pc.checkNegotiationNeeded() { - pc.isNegotiationNeeded.set(false) - return - } - - // Step 2.5 - if pc.isNegotiationNeeded.get() { - return - } - - // Step 2.6 - pc.isNegotiationNeeded.set(true) - - // Step 2.7 - if handler, ok := pc.onNegotiationNeededHandler.Load().(func()); ok && handler != nil { - handler() - } -} - -func (pc *PeerConnection) checkNegotiationNeeded() bool { //nolint:gocognit - // To check if negotiation is needed for connection, perform the following checks: - // Skip 1, 2 steps - // Step 3 - pc.mu.Lock() - defer pc.mu.Unlock() - - localDesc := pc.currentLocalDescription - remoteDesc := pc.currentRemoteDescription - - if localDesc == nil { - return true - } - - pc.sctpTransport.lock.Lock() - lenDataChannel := len(pc.sctpTransport.dataChannels) - pc.sctpTransport.lock.Unlock() - - if lenDataChannel != 0 && haveDataChannel(localDesc) == nil { - return true - } - - for _, t := range pc.rtpTransceivers { - // https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag - // Step 5.1 - // if t.stopping && !t.stopped { - // return true - // } - m := getByMid(t.Mid(), localDesc) - // Step 5.2 - if !t.stopped && m == nil { - return true - } - if !t.stopped && m != nil { - // Step 5.3.1 - if t.Direction() == RTPTransceiverDirectionSendrecv || t.Direction() == RTPTransceiverDirectionSendonly { - descMsid, okMsid := m.Attribute(sdp.AttrKeyMsid) - sender := t.Sender() - if sender == nil { - return true - } - track := sender.Track() - if !okMsid || descMsid != track.StreamID()+" "+track.ID() { - return true - } - } - switch localDesc.Type { - case SDPTypeOffer: - // Step 5.3.2 - rm := getByMid(t.Mid(), remoteDesc) - if rm == nil { - return true - } - - if getPeerDirection(m) != t.Direction() && getPeerDirection(rm) != t.Direction().Revers() { - return true - } - case SDPTypeAnswer: - // Step 5.3.3 - if _, ok := m.Attribute(t.Direction().String()); !ok { - return true - } - default: - } - } - // Step 5.4 - if t.stopped && t.Mid() != "" { - if getByMid(t.Mid(), localDesc) != nil || getByMid(t.Mid(), remoteDesc) != nil { - return true - } - } - } - // Step 6 - return false -} - -// OnICECandidate sets an event handler which is invoked when a new ICE -// candidate is found. -// ICE candidate gathering only begins when SetLocalDescription or -// SetRemoteDescription is called. -// Take note that the handler will be called with a nil pointer when -// gathering is finished. -func (pc *PeerConnection) OnICECandidate(f func(*ICECandidate)) { - pc.iceGatherer.OnLocalCandidate(f) -} - -// OnICEGatheringStateChange sets an event handler which is invoked when the -// ICE candidate gathering state has changed. -func (pc *PeerConnection) OnICEGatheringStateChange(f func(ICEGathererState)) { - pc.iceGatherer.OnStateChange(f) -} - -// OnTrack sets an event handler which is called when remote track -// arrives from a remote peer. -func (pc *PeerConnection) OnTrack(f func(*TrackRemote, *RTPReceiver)) { - pc.mu.Lock() - defer pc.mu.Unlock() - pc.onTrackHandler = f -} - -func (pc *PeerConnection) onTrack(t *TrackRemote, r *RTPReceiver) { - pc.mu.RLock() - handler := pc.onTrackHandler - pc.mu.RUnlock() - - pc.log.Debugf("got new track: %+v", t) - if t != nil { - if handler != nil { - go handler(t, r) - } else { - pc.log.Warnf("OnTrack unset, unable to handle incoming media streams") - } - } -} - -// OnICEConnectionStateChange sets an event handler which is called -// when an ICE connection state is changed. -func (pc *PeerConnection) OnICEConnectionStateChange(f func(ICEConnectionState)) { - pc.onICEConnectionStateChangeHandler.Store(f) -} - -func (pc *PeerConnection) onICEConnectionStateChange(cs ICEConnectionState) { - pc.iceConnectionState.Store(cs) - pc.log.Infof("ICE connection state changed: %s", cs) - if handler, ok := pc.onICEConnectionStateChangeHandler.Load().(func(ICEConnectionState)); ok && handler != nil { - handler(cs) - } -} - -// OnConnectionStateChange sets an event handler which is called -// when the PeerConnectionState has changed -func (pc *PeerConnection) OnConnectionStateChange(f func(PeerConnectionState)) { - pc.onConnectionStateChangeHandler.Store(f) -} - -func (pc *PeerConnection) onConnectionStateChange(cs PeerConnectionState) { - pc.connectionState.Store(cs) - pc.log.Infof("peer connection state changed: %s", cs) - if handler, ok := pc.onConnectionStateChangeHandler.Load().(func(PeerConnectionState)); ok && handler != nil { - go handler(cs) - } -} - -// SetConfiguration updates the configuration of this PeerConnection object. -func (pc *PeerConnection) SetConfiguration(configuration Configuration) error { //nolint:gocognit - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-setconfiguration (step #2) - if pc.isClosed.get() { - return &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #3) - if configuration.PeerIdentity != "" { - if configuration.PeerIdentity != pc.configuration.PeerIdentity { - return &rtcerr.InvalidModificationError{Err: ErrModifyingPeerIdentity} - } - pc.configuration.PeerIdentity = configuration.PeerIdentity - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #4) - if len(configuration.Certificates) > 0 { - if len(configuration.Certificates) != len(pc.configuration.Certificates) { - return &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates} - } - - for i, certificate := range configuration.Certificates { - if !pc.configuration.Certificates[i].Equals(certificate) { - return &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates} - } - } - pc.configuration.Certificates = configuration.Certificates - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #5) - if configuration.BundlePolicy != BundlePolicy(Unknown) { - if configuration.BundlePolicy != pc.configuration.BundlePolicy { - return &rtcerr.InvalidModificationError{Err: ErrModifyingBundlePolicy} - } - pc.configuration.BundlePolicy = configuration.BundlePolicy - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #6) - if configuration.RTCPMuxPolicy != RTCPMuxPolicy(Unknown) { - if configuration.RTCPMuxPolicy != pc.configuration.RTCPMuxPolicy { - return &rtcerr.InvalidModificationError{Err: ErrModifyingRTCPMuxPolicy} - } - pc.configuration.RTCPMuxPolicy = configuration.RTCPMuxPolicy - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #7) - if configuration.ICECandidatePoolSize != 0 { - if pc.configuration.ICECandidatePoolSize != configuration.ICECandidatePoolSize && - pc.LocalDescription() != nil { - return &rtcerr.InvalidModificationError{Err: ErrModifyingICECandidatePoolSize} - } - pc.configuration.ICECandidatePoolSize = configuration.ICECandidatePoolSize - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #8) - if configuration.ICETransportPolicy != ICETransportPolicy(Unknown) { - pc.configuration.ICETransportPolicy = configuration.ICETransportPolicy - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11) - if len(configuration.ICEServers) > 0 { - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3) - for _, server := range configuration.ICEServers { - if err := server.validate(); err != nil { - return err - } - } - pc.configuration.ICEServers = configuration.ICEServers - } - return nil -} - -// GetConfiguration returns a Configuration object representing the current -// configuration of this PeerConnection object. The returned object is a -// copy and direct mutation on it will not take affect until SetConfiguration -// has been called with Configuration passed as its only argument. -// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-getconfiguration -func (pc *PeerConnection) GetConfiguration() Configuration { - return pc.configuration -} - -func (pc *PeerConnection) getStatsID() string { - pc.mu.RLock() - defer pc.mu.RUnlock() - return pc.statsID -} - -// hasLocalDescriptionChanged returns whether local media (rtpTransceivers) has changed -// caller of this method should hold `pc.mu` lock -func (pc *PeerConnection) hasLocalDescriptionChanged(desc *SessionDescription) bool { - for _, t := range pc.rtpTransceivers { - m := getByMid(t.Mid(), desc) - if m == nil { - return true - } - - if getPeerDirection(m) != t.Direction() { - return true - } - } - return false -} - -// CreateOffer starts the PeerConnection and generates the localDescription -// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer -func (pc *PeerConnection) CreateOffer(options *OfferOptions) (SessionDescription, error) { //nolint:gocognit - useIdentity := pc.idpLoginURL != nil - switch { - case useIdentity: - return SessionDescription{}, errIdentityProviderNotImplemented - case pc.isClosed.get(): - return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - if options != nil && options.ICERestart { - if err := pc.iceTransport.restart(); err != nil { - return SessionDescription{}, err - } - } - - var ( - d *sdp.SessionDescription - offer SessionDescription - err error - ) - - // This may be necessary to recompute if, for example, createOffer was called when only an - // audio RTCRtpTransceiver was added to connection, but while performing the in-parallel - // steps to create an offer, a video RTCRtpTransceiver was added, requiring additional - // inspection of video system resources. - count := 0 - pc.mu.Lock() - defer pc.mu.Unlock() - for { - // We cache current transceivers to ensure they aren't - // mutated during offer generation. We later check if they have - // been mutated and recompute the offer if necessary. - currentTransceivers := pc.rtpTransceivers - - // in-parallel steps to create an offer - // https://w3c.github.io/webrtc-pc/#dfn-in-parallel-steps-to-create-an-offer - isPlanB := pc.configuration.SDPSemantics == SDPSemanticsPlanB - if pc.currentRemoteDescription != nil && isPlanB { - isPlanB = descriptionPossiblyPlanB(pc.currentRemoteDescription) - } - - // include unmatched local transceivers - if !isPlanB { - // update the greater mid if the remote description provides a greater one - if pc.currentRemoteDescription != nil { - var numericMid int - for _, media := range pc.currentRemoteDescription.parsed.MediaDescriptions { - mid := getMidValue(media) - if mid == "" { - continue - } - numericMid, err = strconv.Atoi(mid) - if err != nil { - continue - } - if numericMid > pc.greaterMid { - pc.greaterMid = numericMid - } - } - } - for _, t := range currentTransceivers { - if mid := t.Mid(); mid != "" { - numericMid, errMid := strconv.Atoi(mid) - if errMid == nil { - if numericMid > pc.greaterMid { - pc.greaterMid = numericMid - } - } - continue - } - pc.greaterMid++ - err = t.SetMid(strconv.Itoa(pc.greaterMid)) - if err != nil { - return SessionDescription{}, err - } - } - } - - if pc.currentRemoteDescription == nil { - d, err = pc.generateUnmatchedSDP(currentTransceivers, useIdentity) - } else { - d, err = pc.generateMatchedSDP(currentTransceivers, useIdentity, true /*includeUnmatched */, connectionRoleFromDtlsRole(defaultDtlsRoleOffer)) - } - - if err != nil { - return SessionDescription{}, err - } - - updateSDPOrigin(&pc.sdpOrigin, d) - sdpBytes, err := d.Marshal() - if err != nil { - return SessionDescription{}, err - } - - offer = SessionDescription{ - Type: SDPTypeOffer, - SDP: string(sdpBytes), - parsed: d, - } - - // Verify local media hasn't changed during offer - // generation. Recompute if necessary - if isPlanB || !pc.hasLocalDescriptionChanged(&offer) { - break - } - count++ - if count >= 128 { - return SessionDescription{}, errExcessiveRetries - } - } - - pc.lastOffer = offer.SDP - return offer, nil -} - -func (pc *PeerConnection) createICEGatherer() (*ICEGatherer, error) { - g, err := pc.api.NewICEGatherer(ICEGatherOptions{ - ICEServers: pc.configuration.getICEServers(), - ICEGatherPolicy: pc.configuration.ICETransportPolicy, - }) - if err != nil { - return nil, err - } - - return g, nil -} - -// Update the PeerConnectionState given the state of relevant transports -// https://www.w3.org/TR/webrtc/#rtcpeerconnectionstate-enum -func (pc *PeerConnection) updateConnectionState(iceConnectionState ICEConnectionState, dtlsTransportState DTLSTransportState) { - connectionState := PeerConnectionStateNew - switch { - // The RTCPeerConnection object's [[IsClosed]] slot is true. - case pc.isClosed.get(): - connectionState = PeerConnectionStateClosed - - // Any of the RTCIceTransports or RTCDtlsTransports are in a "failed" state. - case iceConnectionState == ICEConnectionStateFailed || dtlsTransportState == DTLSTransportStateFailed: - connectionState = PeerConnectionStateFailed - - // Any of the RTCIceTransports or RTCDtlsTransports are in the "disconnected" - // state and none of them are in the "failed" or "connecting" or "checking" state. */ - case iceConnectionState == ICEConnectionStateDisconnected: - connectionState = PeerConnectionStateDisconnected - - // None of the previous states apply and all RTCIceTransports are in the "new" or "closed" state, - // and all RTCDtlsTransports are in the "new" or "closed" state, or there are no transports. - case (iceConnectionState == ICEConnectionStateNew || iceConnectionState == ICEConnectionStateClosed) && - (dtlsTransportState == DTLSTransportStateNew || dtlsTransportState == DTLSTransportStateClosed): - connectionState = PeerConnectionStateNew - - // None of the previous states apply and any RTCIceTransport is in the "new" or "checking" state or - // any RTCDtlsTransport is in the "new" or "connecting" state. - case (iceConnectionState == ICEConnectionStateNew || iceConnectionState == ICEConnectionStateChecking) || - (dtlsTransportState == DTLSTransportStateNew || dtlsTransportState == DTLSTransportStateConnecting): - connectionState = PeerConnectionStateConnecting - - // All RTCIceTransports and RTCDtlsTransports are in the "connected", "completed" or "closed" - // state and all RTCDtlsTransports are in the "connected" or "closed" state. - case (iceConnectionState == ICEConnectionStateConnected || iceConnectionState == ICEConnectionStateCompleted || iceConnectionState == ICEConnectionStateClosed) && - (dtlsTransportState == DTLSTransportStateConnected || dtlsTransportState == DTLSTransportStateClosed): - connectionState = PeerConnectionStateConnected - } - - if pc.connectionState.Load() == connectionState { - return - } - - pc.onConnectionStateChange(connectionState) -} - -func (pc *PeerConnection) createICETransport() *ICETransport { - t := pc.api.NewICETransport(pc.iceGatherer) - t.internalOnConnectionStateChangeHandler.Store(func(state ICETransportState) { - var cs ICEConnectionState - switch state { - case ICETransportStateNew: - cs = ICEConnectionStateNew - case ICETransportStateChecking: - cs = ICEConnectionStateChecking - case ICETransportStateConnected: - cs = ICEConnectionStateConnected - case ICETransportStateCompleted: - cs = ICEConnectionStateCompleted - case ICETransportStateFailed: - cs = ICEConnectionStateFailed - case ICETransportStateDisconnected: - cs = ICEConnectionStateDisconnected - case ICETransportStateClosed: - cs = ICEConnectionStateClosed - default: - pc.log.Warnf("OnConnectionStateChange: unhandled ICE state: %s", state) - return - } - pc.onICEConnectionStateChange(cs) - pc.updateConnectionState(cs, pc.dtlsTransport.State()) - }) - - return t -} - -// CreateAnswer starts the PeerConnection and generates the localDescription -func (pc *PeerConnection) CreateAnswer(*AnswerOptions) (SessionDescription, error) { - useIdentity := pc.idpLoginURL != nil - remoteDesc := pc.RemoteDescription() - switch { - case remoteDesc == nil: - return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrNoRemoteDescription} - case useIdentity: - return SessionDescription{}, errIdentityProviderNotImplemented - case pc.isClosed.get(): - return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - case pc.signalingState.Get() != SignalingStateHaveRemoteOffer && pc.signalingState.Get() != SignalingStateHaveLocalPranswer: - return SessionDescription{}, &rtcerr.InvalidStateError{Err: ErrIncorrectSignalingState} - } - - connectionRole := connectionRoleFromDtlsRole(pc.api.settingEngine.answeringDTLSRole) - if connectionRole == sdp.ConnectionRole(0) { - connectionRole = connectionRoleFromDtlsRole(defaultDtlsRoleAnswer) - - // If one of the agents is lite and the other one is not, the lite agent must be the controlling agent. - // If both or neither agents are lite the offering agent is controlling. - // RFC 8445 S6.1.1 - if isIceLiteSet(remoteDesc.parsed) && !pc.api.settingEngine.candidates.ICELite { - connectionRole = connectionRoleFromDtlsRole(DTLSRoleServer) - } - } - pc.mu.Lock() - defer pc.mu.Unlock() - - d, err := pc.generateMatchedSDP(pc.rtpTransceivers, useIdentity, false /*includeUnmatched */, connectionRole) - if err != nil { - return SessionDescription{}, err - } - - updateSDPOrigin(&pc.sdpOrigin, d) - sdpBytes, err := d.Marshal() - if err != nil { - return SessionDescription{}, err - } - - desc := SessionDescription{ - Type: SDPTypeAnswer, - SDP: string(sdpBytes), - parsed: d, - } - pc.lastAnswer = desc.SDP - return desc, nil -} - -// 4.4.1.6 Set the SessionDescription -func (pc *PeerConnection) setDescription(sd *SessionDescription, op stateChangeOp) error { //nolint:gocognit - switch { - case pc.isClosed.get(): - return &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - case NewSDPType(sd.Type.String()) == SDPType(Unknown): - return &rtcerr.TypeError{Err: fmt.Errorf("%w: '%d' is not a valid enum value of type SDPType", errPeerConnSDPTypeInvalidValue, sd.Type)} - } - - nextState, err := func() (SignalingState, error) { - pc.mu.Lock() - defer pc.mu.Unlock() - - cur := pc.SignalingState() - setLocal := stateChangeOpSetLocal - setRemote := stateChangeOpSetRemote - newSDPDoesNotMatchOffer := &rtcerr.InvalidModificationError{Err: errSDPDoesNotMatchOffer} - newSDPDoesNotMatchAnswer := &rtcerr.InvalidModificationError{Err: errSDPDoesNotMatchAnswer} - - var nextState SignalingState - var err error - switch op { - case setLocal: - switch sd.Type { - // stable->SetLocal(offer)->have-local-offer - case SDPTypeOffer: - if sd.SDP != pc.lastOffer { - return nextState, newSDPDoesNotMatchOffer - } - nextState, err = checkNextSignalingState(cur, SignalingStateHaveLocalOffer, setLocal, sd.Type) - if err == nil { - pc.pendingLocalDescription = sd - } - // have-remote-offer->SetLocal(answer)->stable - // have-local-pranswer->SetLocal(answer)->stable - case SDPTypeAnswer: - if sd.SDP != pc.lastAnswer { - return nextState, newSDPDoesNotMatchAnswer - } - nextState, err = checkNextSignalingState(cur, SignalingStateStable, setLocal, sd.Type) - if err == nil { - pc.currentLocalDescription = sd - pc.currentRemoteDescription = pc.pendingRemoteDescription - pc.pendingRemoteDescription = nil - pc.pendingLocalDescription = nil - } - case SDPTypeRollback: - nextState, err = checkNextSignalingState(cur, SignalingStateStable, setLocal, sd.Type) - if err == nil { - pc.pendingLocalDescription = nil - } - // have-remote-offer->SetLocal(pranswer)->have-local-pranswer - case SDPTypePranswer: - if sd.SDP != pc.lastAnswer { - return nextState, newSDPDoesNotMatchAnswer - } - nextState, err = checkNextSignalingState(cur, SignalingStateHaveLocalPranswer, setLocal, sd.Type) - if err == nil { - pc.pendingLocalDescription = sd - } - default: - return nextState, &rtcerr.OperationError{Err: fmt.Errorf("%w: %s(%s)", errPeerConnStateChangeInvalid, op, sd.Type)} - } - case setRemote: - switch sd.Type { - // stable->SetRemote(offer)->have-remote-offer - case SDPTypeOffer: - nextState, err = checkNextSignalingState(cur, SignalingStateHaveRemoteOffer, setRemote, sd.Type) - if err == nil { - pc.pendingRemoteDescription = sd - } - // have-local-offer->SetRemote(answer)->stable - // have-remote-pranswer->SetRemote(answer)->stable - case SDPTypeAnswer: - nextState, err = checkNextSignalingState(cur, SignalingStateStable, setRemote, sd.Type) - if err == nil { - pc.currentRemoteDescription = sd - pc.currentLocalDescription = pc.pendingLocalDescription - pc.pendingRemoteDescription = nil - pc.pendingLocalDescription = nil - } - case SDPTypeRollback: - nextState, err = checkNextSignalingState(cur, SignalingStateStable, setRemote, sd.Type) - if err == nil { - pc.pendingRemoteDescription = nil - } - // have-local-offer->SetRemote(pranswer)->have-remote-pranswer - case SDPTypePranswer: - nextState, err = checkNextSignalingState(cur, SignalingStateHaveRemotePranswer, setRemote, sd.Type) - if err == nil { - pc.pendingRemoteDescription = sd - } - default: - return nextState, &rtcerr.OperationError{Err: fmt.Errorf("%w: %s(%s)", errPeerConnStateChangeInvalid, op, sd.Type)} - } - default: - return nextState, &rtcerr.OperationError{Err: fmt.Errorf("%w: %q", errPeerConnStateChangeUnhandled, op)} - } - - return nextState, err - }() - - if err == nil { - pc.signalingState.Set(nextState) - if pc.signalingState.Get() == SignalingStateStable { - pc.isNegotiationNeeded.set(false) - pc.mu.Lock() - pc.onNegotiationNeeded() - pc.mu.Unlock() - } - pc.onSignalingStateChange(nextState) - } - return err -} - -// SetLocalDescription sets the SessionDescription of the local peer -func (pc *PeerConnection) SetLocalDescription(desc SessionDescription) error { - if pc.isClosed.get() { - return &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - haveLocalDescription := pc.currentLocalDescription != nil - - // JSEP 5.4 - if desc.SDP == "" { - switch desc.Type { - case SDPTypeAnswer, SDPTypePranswer: - desc.SDP = pc.lastAnswer - case SDPTypeOffer: - desc.SDP = pc.lastOffer - default: - return &rtcerr.InvalidModificationError{ - Err: fmt.Errorf("%w: %s", errPeerConnSDPTypeInvalidValueSetLocalDescription, desc.Type), - } - } - } - - desc.parsed = &sdp.SessionDescription{} - if err := desc.parsed.Unmarshal([]byte(desc.SDP)); err != nil { - return err - } - if err := pc.setDescription(&desc, stateChangeOpSetLocal); err != nil { - return err - } - - currentTransceivers := append([]*RTPTransceiver{}, pc.GetTransceivers()...) - - weAnswer := desc.Type == SDPTypeAnswer - remoteDesc := pc.RemoteDescription() - if weAnswer && remoteDesc != nil { - _ = setRTPTransceiverCurrentDirection(&desc, currentTransceivers, false) - if err := pc.startRTPSenders(currentTransceivers); err != nil { - return err - } - pc.configureRTPReceivers(haveLocalDescription, remoteDesc, currentTransceivers) - pc.ops.Enqueue(func() { - pc.startRTP(haveLocalDescription, remoteDesc, currentTransceivers) - }) - } - - if pc.iceGatherer.State() == ICEGathererStateNew { - return pc.iceGatherer.Gather() - } - return nil -} - -// LocalDescription returns PendingLocalDescription if it is not null and -// otherwise it returns CurrentLocalDescription. This property is used to -// determine if SetLocalDescription has already been called. -// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-localdescription -func (pc *PeerConnection) LocalDescription() *SessionDescription { - if pendingLocalDescription := pc.PendingLocalDescription(); pendingLocalDescription != nil { - return pendingLocalDescription - } - return pc.CurrentLocalDescription() -} - -// SetRemoteDescription sets the SessionDescription of the remote peer -func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error { //nolint:gocognit,gocyclo - if pc.isClosed.get() { - return &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - isRenegotation := pc.currentRemoteDescription != nil - - if _, err := desc.Unmarshal(); err != nil { - return err - } - if err := pc.setDescription(&desc, stateChangeOpSetRemote); err != nil { - return err - } - - if err := pc.api.mediaEngine.updateFromRemoteDescription(*desc.parsed); err != nil { - return err - } - - var t *RTPTransceiver - localTransceivers := append([]*RTPTransceiver{}, pc.GetTransceivers()...) - detectedPlanB := descriptionIsPlanB(pc.RemoteDescription(), pc.log) - if pc.configuration.SDPSemantics != SDPSemanticsUnifiedPlan { - detectedPlanB = descriptionPossiblyPlanB(pc.RemoteDescription()) - } - - weOffer := desc.Type == SDPTypeAnswer - - if !weOffer && !detectedPlanB { - for _, media := range pc.RemoteDescription().parsed.MediaDescriptions { - midValue := getMidValue(media) - if midValue == "" { - return errPeerConnRemoteDescriptionWithoutMidValue - } - - if media.MediaName.Media == mediaSectionApplication { - continue - } - - kind := NewRTPCodecType(media.MediaName.Media) - direction := getPeerDirection(media) - if kind == 0 || direction == RTPTransceiverDirection(Unknown) { - continue - } - - t, localTransceivers = findByMid(midValue, localTransceivers) - if t == nil { - t, localTransceivers = satisfyTypeAndDirection(kind, direction, localTransceivers) - } else if direction == RTPTransceiverDirectionInactive { - if err := t.Stop(); err != nil { - return err - } - } - - switch { - case t == nil: - receiver, err := pc.api.NewRTPReceiver(kind, pc.dtlsTransport) - if err != nil { - return err - } - - localDirection := RTPTransceiverDirectionRecvonly - if direction == RTPTransceiverDirectionRecvonly { - localDirection = RTPTransceiverDirectionSendonly - } else if direction == RTPTransceiverDirectionInactive { - localDirection = RTPTransceiverDirectionInactive - } - - t = newRTPTransceiver(receiver, nil, localDirection, kind, pc.api) - pc.mu.Lock() - pc.addRTPTransceiver(t) - pc.mu.Unlock() - - // if transceiver is create by remote sdp, set prefer codec same as remote peer - if codecs, err := codecsFromMediaDescription(media); err == nil { - filteredCodecs := []RTPCodecParameters{} - for _, codec := range codecs { - if c, matchType := codecParametersFuzzySearch(codec, pc.api.mediaEngine.getCodecsByKind(kind)); matchType == codecMatchExact { - // if codec match exact, use payloadtype register to mediaengine - codec.PayloadType = c.PayloadType - filteredCodecs = append(filteredCodecs, codec) - } - } - _ = t.SetCodecPreferences(filteredCodecs) - } - - case direction == RTPTransceiverDirectionRecvonly: - if t.Direction() == RTPTransceiverDirectionSendrecv { - t.setDirection(RTPTransceiverDirectionSendonly) - } - case direction == RTPTransceiverDirectionSendrecv: - if t.Direction() == RTPTransceiverDirectionSendonly { - t.setDirection(RTPTransceiverDirectionSendrecv) - } - } - - if t.Mid() == "" { - if err := t.SetMid(midValue); err != nil { - return err - } - } - } - } - - remoteUfrag, remotePwd, candidates, err := extractICEDetails(desc.parsed, pc.log) - if err != nil { - return err - } - - if isRenegotation && pc.iceTransport.haveRemoteCredentialsChange(remoteUfrag, remotePwd) { - // An ICE Restart only happens implicitly for a SetRemoteDescription of type offer - if !weOffer { - if err = pc.iceTransport.restart(); err != nil { - return err - } - } - - if err = pc.iceTransport.setRemoteCredentials(remoteUfrag, remotePwd); err != nil { - return err - } - } - - for i := range candidates { - if err = pc.iceTransport.AddRemoteCandidate(&candidates[i]); err != nil { - return err - } - } - - currentTransceivers := append([]*RTPTransceiver{}, pc.GetTransceivers()...) - - if isRenegotation { - if weOffer { - _ = setRTPTransceiverCurrentDirection(&desc, currentTransceivers, true) - if err = pc.startRTPSenders(currentTransceivers); err != nil { - return err - } - pc.configureRTPReceivers(true, &desc, currentTransceivers) - pc.ops.Enqueue(func() { - pc.startRTP(true, &desc, currentTransceivers) - }) - } - return nil - } - - remoteIsLite := isIceLiteSet(desc.parsed) - - fingerprint, fingerprintHash, err := extractFingerprint(desc.parsed) - if err != nil { - return err - } - - iceRole := ICERoleControlled - // If one of the agents is lite and the other one is not, the lite agent must be the controlling agent. - // If both or neither agents are lite the offering agent is controlling. - // RFC 8445 S6.1.1 - if (weOffer && remoteIsLite == pc.api.settingEngine.candidates.ICELite) || (remoteIsLite && !pc.api.settingEngine.candidates.ICELite) { - iceRole = ICERoleControlling - } - - // Start the networking in a new routine since it will block until - // the connection is actually established. - if weOffer { - _ = setRTPTransceiverCurrentDirection(&desc, currentTransceivers, true) - if err := pc.startRTPSenders(currentTransceivers); err != nil { - return err - } - - pc.configureRTPReceivers(false, &desc, currentTransceivers) - } - - pc.ops.Enqueue(func() { - pc.startTransports(iceRole, dtlsRoleFromRemoteSDP(desc.parsed), remoteUfrag, remotePwd, fingerprint, fingerprintHash) - if weOffer { - pc.startRTP(false, &desc, currentTransceivers) - } - }) - return nil -} - -func (pc *PeerConnection) configureReceiver(incoming trackDetails, receiver *RTPReceiver) { - receiver.configureReceive(trackDetailsToRTPReceiveParameters(&incoming)) - - // set track id and label early so they can be set as new track information - // is received from the SDP. - for i := range receiver.tracks { - receiver.tracks[i].track.mu.Lock() - receiver.tracks[i].track.id = incoming.id - receiver.tracks[i].track.streamID = incoming.streamID - receiver.tracks[i].track.mu.Unlock() - } -} - -func (pc *PeerConnection) startReceiver(incoming trackDetails, receiver *RTPReceiver) { - if err := receiver.startReceive(trackDetailsToRTPReceiveParameters(&incoming)); err != nil { - pc.log.Warnf("RTPReceiver Receive failed %s", err) - return - } - - for _, t := range receiver.Tracks() { - if t.SSRC() == 0 || t.RID() != "" { - return - } - - go func(track *TrackRemote) { - b := make([]byte, pc.api.settingEngine.getReceiveMTU()) - n, _, err := track.peek(b) - if err != nil { - pc.log.Warnf("Could not determine PayloadType for SSRC %d (%s)", track.SSRC(), err) - return - } - - if err = track.checkAndUpdateTrack(b[:n]); err != nil { - pc.log.Warnf("Failed to set codec settings for track SSRC %d (%s)", track.SSRC(), err) - return - } - - pc.onTrack(track, receiver) - }(t) - } -} - -func setRTPTransceiverCurrentDirection(answer *SessionDescription, currentTransceivers []*RTPTransceiver, weOffer bool) error { - currentTransceivers = append([]*RTPTransceiver{}, currentTransceivers...) - for _, media := range answer.parsed.MediaDescriptions { - midValue := getMidValue(media) - if midValue == "" { - return errPeerConnRemoteDescriptionWithoutMidValue - } - - if media.MediaName.Media == mediaSectionApplication { - continue - } - - var t *RTPTransceiver - t, currentTransceivers = findByMid(midValue, currentTransceivers) - - if t == nil { - return fmt.Errorf("%w: %q", errPeerConnTranscieverMidNil, midValue) - } - - direction := getPeerDirection(media) - if direction == RTPTransceiverDirection(Unknown) { - continue - } - - // reverse direction if it was a remote answer - if weOffer { - switch direction { - case RTPTransceiverDirectionSendonly: - direction = RTPTransceiverDirectionRecvonly - case RTPTransceiverDirectionRecvonly: - direction = RTPTransceiverDirectionSendonly - default: - } - } - - // If a transceiver is created by applying a remote description that has recvonly transceiver, - // it will have no sender. In this case, the transceiver's current direction is set to inactive so - // that the transceiver can be reused by next AddTrack. - if direction == RTPTransceiverDirectionSendonly && t.Sender() == nil { - direction = RTPTransceiverDirectionInactive - } - - t.setCurrentDirection(direction) - } - return nil -} - -func runIfNewReceiver( - incomingTrack trackDetails, - transceivers []*RTPTransceiver, - f func(incomingTrack trackDetails, receiver *RTPReceiver), -) bool { - for _, t := range transceivers { - if t.Mid() != incomingTrack.mid { - continue - } - - receiver := t.Receiver() - if (incomingTrack.kind != t.Kind()) || - (t.Direction() != RTPTransceiverDirectionRecvonly && t.Direction() != RTPTransceiverDirectionSendrecv) || - receiver == nil || - (receiver.haveReceived()) { - continue - } - - f(incomingTrack, receiver) - return true - } - - return false -} - -// configurepRTPReceivers opens knows inbound SRTP streams from the RemoteDescription -func (pc *PeerConnection) configureRTPReceivers(isRenegotiation bool, remoteDesc *SessionDescription, currentTransceivers []*RTPTransceiver) { //nolint:gocognit - incomingTracks := trackDetailsFromSDP(pc.log, remoteDesc.parsed) - - if isRenegotiation { - for _, t := range currentTransceivers { - receiver := t.Receiver() - if receiver == nil { - continue - } - - tracks := t.Receiver().Tracks() - if len(tracks) == 0 { - continue - } - - mid := t.Mid() - receiverNeedsStopped := false - func() { - for _, t := range tracks { - t.mu.Lock() - defer t.mu.Unlock() - - if t.rid != "" { - if details := trackDetailsForRID(incomingTracks, mid, t.rid); details != nil { - t.id = details.id - t.streamID = details.streamID - continue - } - } else if t.ssrc != 0 { - if details := trackDetailsForSSRC(incomingTracks, t.ssrc); details != nil { - t.id = details.id - t.streamID = details.streamID - continue - } - } - - receiverNeedsStopped = true - } - }() - - if !receiverNeedsStopped { - continue - } - - if err := receiver.Stop(); err != nil { - pc.log.Warnf("Failed to stop RtpReceiver: %s", err) - continue - } - - receiver, err := pc.api.NewRTPReceiver(receiver.kind, pc.dtlsTransport) - if err != nil { - pc.log.Warnf("Failed to create new RtpReceiver: %s", err) - continue - } - t.setReceiver(receiver) - } - } - - localTransceivers := append([]*RTPTransceiver{}, currentTransceivers...) - - // Ensure we haven't already started a transceiver for this ssrc - filteredTracks := append([]trackDetails{}, incomingTracks...) - for _, incomingTrack := range incomingTracks { - // If we already have a TrackRemote for a given SSRC don't handle it again - for _, t := range localTransceivers { - if receiver := t.Receiver(); receiver != nil { - for _, track := range receiver.Tracks() { - for _, ssrc := range incomingTrack.ssrcs { - if ssrc == track.SSRC() { - filteredTracks = filterTrackWithSSRC(filteredTracks, track.SSRC()) - } - } - } - } - } - } - - for _, incomingTrack := range filteredTracks { - _ = runIfNewReceiver(incomingTrack, localTransceivers, pc.configureReceiver) - } -} - -// startRTPReceivers opens knows inbound SRTP streams from the RemoteDescription -func (pc *PeerConnection) startRTPReceivers(remoteDesc *SessionDescription, currentTransceivers []*RTPTransceiver) { - incomingTracks := trackDetailsFromSDP(pc.log, remoteDesc.parsed) - if len(incomingTracks) == 0 { - return - } - - localTransceivers := append([]*RTPTransceiver{}, currentTransceivers...) - - unhandledTracks := incomingTracks[:0] - for _, incomingTrack := range incomingTracks { - trackHandled := runIfNewReceiver(incomingTrack, localTransceivers, pc.startReceiver) - if !trackHandled { - unhandledTracks = append(unhandledTracks, incomingTrack) - } - } - - remoteIsPlanB := false - switch pc.configuration.SDPSemantics { - case SDPSemanticsPlanB: - remoteIsPlanB = true - case SDPSemanticsUnifiedPlanWithFallback: - remoteIsPlanB = descriptionPossiblyPlanB(pc.RemoteDescription()) - default: - // none - } - - if remoteIsPlanB { - for _, incomingTrack := range unhandledTracks { - t, err := pc.AddTransceiverFromKind(incomingTrack.kind, RTPTransceiverInit{ - Direction: RTPTransceiverDirectionSendrecv, - }) - if err != nil { - pc.log.Warnf("Could not add transceiver for remote SSRC %d: %s", incomingTrack.ssrcs[0], err) - continue - } - pc.configureReceiver(incomingTrack, t.Receiver()) - pc.startReceiver(incomingTrack, t.Receiver()) - } - } -} - -// startRTPSenders starts all outbound RTP streams -func (pc *PeerConnection) startRTPSenders(currentTransceivers []*RTPTransceiver) error { - for _, transceiver := range currentTransceivers { - if sender := transceiver.Sender(); sender != nil && sender.isNegotiated() && !sender.hasSent() { - err := sender.Send(sender.GetParameters()) - if err != nil { - return err - } - } - } - - return nil -} - -// Start SCTP subsystem -func (pc *PeerConnection) startSCTP() { - // Start sctp - if err := pc.sctpTransport.Start(SCTPCapabilities{ - MaxMessageSize: 0, - }); err != nil { - pc.log.Warnf("Failed to start SCTP: %s", err) - if err = pc.sctpTransport.Stop(); err != nil { - pc.log.Warnf("Failed to stop SCTPTransport: %s", err) - } - - return - } -} - -func (pc *PeerConnection) handleUndeclaredSSRC(ssrc SSRC, remoteDescription *SessionDescription) (handled bool, err error) { - if len(remoteDescription.parsed.MediaDescriptions) != 1 { - return false, nil - } - - onlyMediaSection := remoteDescription.parsed.MediaDescriptions[0] - streamID := "" - id := "" - hasRidAttribute := false - hasSSRCAttribute := false - - for _, a := range onlyMediaSection.Attributes { - switch a.Key { - case sdp.AttrKeyMsid: - if split := strings.Split(a.Value, " "); len(split) == 2 { - streamID = split[0] - id = split[1] - } - case sdp.AttrKeySSRC: - hasSSRCAttribute = true - case sdpAttributeRid: - hasRidAttribute = true - } - } - - if hasRidAttribute { - return false, nil - } else if hasSSRCAttribute { - return false, errPeerConnSingleMediaSectionHasExplicitSSRC - } - - incoming := trackDetails{ - ssrcs: []SSRC{ssrc}, - kind: RTPCodecTypeVideo, - streamID: streamID, - id: id, - } - if onlyMediaSection.MediaName.Media == RTPCodecTypeAudio.String() { - incoming.kind = RTPCodecTypeAudio - } - - t, err := pc.AddTransceiverFromKind(incoming.kind, RTPTransceiverInit{ - Direction: RTPTransceiverDirectionSendrecv, - }) - if err != nil { - // nolint - return false, fmt.Errorf("%w: %d: %s", errPeerConnRemoteSSRCAddTransceiver, ssrc, err) - } - - pc.configureReceiver(incoming, t.Receiver()) - pc.startReceiver(incoming, t.Receiver()) - return true, nil -} - -func (pc *PeerConnection) handleIncomingSSRC(rtpStream io.Reader, ssrc SSRC) error { //nolint:gocognit - remoteDescription := pc.RemoteDescription() - if remoteDescription == nil { - return errPeerConnRemoteDescriptionNil - } - - // If a SSRC already exists in the RemoteDescription don't perform heuristics upon it - for _, track := range trackDetailsFromSDP(pc.log, remoteDescription.parsed) { - if track.repairSsrc != nil && ssrc == *track.repairSsrc { - return nil - } - for _, trackSsrc := range track.ssrcs { - if ssrc == trackSsrc { - return nil - } - } - } - - // If the remote SDP was only one media section the ssrc doesn't have to be explicitly declared - if handled, err := pc.handleUndeclaredSSRC(ssrc, remoteDescription); handled || err != nil { - return err - } - - midExtensionID, audioSupported, videoSupported := pc.api.mediaEngine.getHeaderExtensionID(RTPHeaderExtensionCapability{sdp.SDESMidURI}) - if !audioSupported && !videoSupported { - return errPeerConnSimulcastMidRTPExtensionRequired - } - - streamIDExtensionID, audioSupported, videoSupported := pc.api.mediaEngine.getHeaderExtensionID(RTPHeaderExtensionCapability{sdp.SDESRTPStreamIDURI}) - if !audioSupported && !videoSupported { - return errPeerConnSimulcastStreamIDRTPExtensionRequired - } - - repairStreamIDExtensionID, _, _ := pc.api.mediaEngine.getHeaderExtensionID(RTPHeaderExtensionCapability{sdesRepairRTPStreamIDURI}) - - b := make([]byte, pc.api.settingEngine.getReceiveMTU()) - - i, err := rtpStream.Read(b) - if err != nil { - return err - } - - var mid, rid, rsid string - payloadType, err := handleUnknownRTPPacket(b[:i], uint8(midExtensionID), uint8(streamIDExtensionID), uint8(repairStreamIDExtensionID), &mid, &rid, &rsid) - if err != nil { - return err - } - - params, err := pc.api.mediaEngine.getRTPParametersByPayloadType(payloadType) - if err != nil { - return err - } - - streamInfo := createStreamInfo("", ssrc, params.Codecs[0].PayloadType, params.Codecs[0].RTPCodecCapability, params.HeaderExtensions) - readStream, interceptor, rtcpReadStream, rtcpInterceptor, err := pc.dtlsTransport.streamsForSSRC(ssrc, *streamInfo) - if err != nil { - return err - } - - for readCount := 0; readCount <= simulcastProbeCount; readCount++ { - if mid == "" || (rid == "" && rsid == "") { - i, _, err := interceptor.Read(b, nil) - if err != nil { - return err - } - - if _, err = handleUnknownRTPPacket(b[:i], uint8(midExtensionID), uint8(streamIDExtensionID), uint8(repairStreamIDExtensionID), &mid, &rid, &rsid); err != nil { - return err - } - - continue - } - - for _, t := range pc.GetTransceivers() { - receiver := t.Receiver() - if t.Mid() != mid || receiver == nil { - continue - } - - if rsid != "" { - receiver.mu.Lock() - defer receiver.mu.Unlock() - return receiver.receiveForRtx(SSRC(0), rsid, streamInfo, readStream, interceptor, rtcpReadStream, rtcpInterceptor) - } - - track, err := receiver.receiveForRid(rid, params, streamInfo, readStream, interceptor, rtcpReadStream, rtcpInterceptor) - if err != nil { - return err - } - pc.onTrack(track, receiver) - return nil - } - } - - pc.api.interceptor.UnbindRemoteStream(streamInfo) - return errPeerConnSimulcastIncomingSSRCFailed -} - -// undeclaredMediaProcessor handles RTP/RTCP packets that don't match any a:ssrc lines -func (pc *PeerConnection) undeclaredMediaProcessor() { - go pc.undeclaredRTPMediaProcessor() - go pc.undeclaredRTCPMediaProcessor() -} - -func (pc *PeerConnection) undeclaredRTPMediaProcessor() { - var simulcastRoutineCount uint64 - for { - srtpSession, err := pc.dtlsTransport.getSRTPSession() - if err != nil { - pc.log.Warnf("undeclaredMediaProcessor failed to open SrtpSession: %v", err) - return - } - - stream, ssrc, err := srtpSession.AcceptStream() - if err != nil { - pc.log.Warnf("Failed to accept RTP %v", err) - return - } - - if pc.isClosed.get() { - if err = stream.Close(); err != nil { - pc.log.Warnf("Failed to close RTP stream %v", err) - } - continue - } - - if atomic.AddUint64(&simulcastRoutineCount, 1) >= simulcastMaxProbeRoutines { - atomic.AddUint64(&simulcastRoutineCount, ^uint64(0)) - pc.log.Warn(ErrSimulcastProbeOverflow.Error()) - pc.dtlsTransport.storeSimulcastStream(stream) - continue - } - - go func(rtpStream io.Reader, ssrc SSRC) { - if err := pc.handleIncomingSSRC(rtpStream, ssrc); err != nil { - pc.log.Errorf(incomingUnhandledRTPSsrc, ssrc, err) - pc.dtlsTransport.storeSimulcastStream(stream) - } - atomic.AddUint64(&simulcastRoutineCount, ^uint64(0)) - }(stream, SSRC(ssrc)) - } -} - -func (pc *PeerConnection) undeclaredRTCPMediaProcessor() { - var unhandledStreams []*srtp.ReadStreamSRTCP - defer func() { - for _, s := range unhandledStreams { - _ = s.Close() - } - }() - for { - srtcpSession, err := pc.dtlsTransport.getSRTCPSession() - if err != nil { - pc.log.Warnf("undeclaredMediaProcessor failed to open SrtcpSession: %v", err) - return - } - - stream, ssrc, err := srtcpSession.AcceptStream() - if err != nil { - pc.log.Warnf("Failed to accept RTCP %v", err) - return - } - pc.log.Warnf("Incoming unhandled RTCP ssrc(%d), OnTrack will not be fired", ssrc) - unhandledStreams = append(unhandledStreams, stream) - } -} - -// RemoteDescription returns pendingRemoteDescription if it is not null and -// otherwise it returns currentRemoteDescription. This property is used to -// determine if setRemoteDescription has already been called. -// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-remotedescription -func (pc *PeerConnection) RemoteDescription() *SessionDescription { - pc.mu.RLock() - defer pc.mu.RUnlock() - - if pc.pendingRemoteDescription != nil { - return pc.pendingRemoteDescription - } - return pc.currentRemoteDescription -} - -// AddICECandidate accepts an ICE candidate string and adds it -// to the existing set of candidates. -func (pc *PeerConnection) AddICECandidate(candidate ICECandidateInit) error { - if pc.RemoteDescription() == nil { - return &rtcerr.InvalidStateError{Err: ErrNoRemoteDescription} - } - - candidateValue := strings.TrimPrefix(candidate.Candidate, "candidate:") - - var iceCandidate *ICECandidate - if candidateValue != "" { - candidate, err := ice.UnmarshalCandidate(candidateValue) - if err != nil { - if errors.Is(err, ice.ErrUnknownCandidateTyp) || errors.Is(err, ice.ErrDetermineNetworkType) { - pc.log.Warnf("Discarding remote candidate: %s", err) - return nil - } - return err - } - - c, err := newICECandidateFromICE(candidate) - if err != nil { - return err - } - iceCandidate = &c - } - - return pc.iceTransport.AddRemoteCandidate(iceCandidate) -} - -// ICEConnectionState returns the ICE connection state of the -// PeerConnection instance. -func (pc *PeerConnection) ICEConnectionState() ICEConnectionState { - if state, ok := pc.iceConnectionState.Load().(ICEConnectionState); ok { - return state - } - return ICEConnectionState(0) -} - -// GetSenders returns the RTPSender that are currently attached to this PeerConnection -func (pc *PeerConnection) GetSenders() (result []*RTPSender) { - pc.mu.Lock() - defer pc.mu.Unlock() - - for _, transceiver := range pc.rtpTransceivers { - if sender := transceiver.Sender(); sender != nil { - result = append(result, sender) - } - } - return result -} - -// GetReceivers returns the RTPReceivers that are currently attached to this PeerConnection -func (pc *PeerConnection) GetReceivers() (receivers []*RTPReceiver) { - pc.mu.Lock() - defer pc.mu.Unlock() - - for _, transceiver := range pc.rtpTransceivers { - if receiver := transceiver.Receiver(); receiver != nil { - receivers = append(receivers, receiver) - } - } - return -} - -// GetTransceivers returns the RtpTransceiver that are currently attached to this PeerConnection -func (pc *PeerConnection) GetTransceivers() []*RTPTransceiver { - pc.mu.Lock() - defer pc.mu.Unlock() - - return pc.rtpTransceivers -} - -// AddTrack adds a Track to the PeerConnection -func (pc *PeerConnection) AddTrack(track TrackLocal) (*RTPSender, error) { - if pc.isClosed.get() { - return nil, &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - pc.mu.Lock() - defer pc.mu.Unlock() - for _, t := range pc.rtpTransceivers { - currentDirection := t.getCurrentDirection() - // According to https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-addtrack, if the - // transceiver can be reused only if it's currentDirection never be sendrecv or sendonly. - // But that will cause sdp inflate. So we only check currentDirection's current value, - // that's worked for all browsers. - if !t.stopped && t.kind == track.Kind() && t.Sender() == nil && - !(currentDirection == RTPTransceiverDirectionSendrecv || currentDirection == RTPTransceiverDirectionSendonly) { - sender, err := pc.api.NewRTPSender(track, pc.dtlsTransport) - if err == nil { - err = t.SetSender(sender, track) - if err != nil { - _ = sender.Stop() - t.setSender(nil) - } - } - if err != nil { - return nil, err - } - pc.onNegotiationNeeded() - return sender, nil - } - } - - transceiver, err := pc.newTransceiverFromTrack(RTPTransceiverDirectionSendrecv, track) - if err != nil { - return nil, err - } - pc.addRTPTransceiver(transceiver) - return transceiver.Sender(), nil -} - -// RemoveTrack removes a Track from the PeerConnection -func (pc *PeerConnection) RemoveTrack(sender *RTPSender) (err error) { - if pc.isClosed.get() { - return &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - var transceiver *RTPTransceiver - pc.mu.Lock() - defer pc.mu.Unlock() - for _, t := range pc.rtpTransceivers { - if t.Sender() == sender { - transceiver = t - break - } - } - if transceiver == nil { - return &rtcerr.InvalidAccessError{Err: ErrSenderNotCreatedByConnection} - } else if err = sender.Stop(); err == nil { - err = transceiver.setSendingTrack(nil) - if err == nil { - pc.onNegotiationNeeded() - } - } - return -} - -func (pc *PeerConnection) newTransceiverFromTrack(direction RTPTransceiverDirection, track TrackLocal) (t *RTPTransceiver, err error) { - var ( - r *RTPReceiver - s *RTPSender - ) - switch direction { - case RTPTransceiverDirectionSendrecv: - r, err = pc.api.NewRTPReceiver(track.Kind(), pc.dtlsTransport) - if err != nil { - return - } - s, err = pc.api.NewRTPSender(track, pc.dtlsTransport) - case RTPTransceiverDirectionSendonly: - s, err = pc.api.NewRTPSender(track, pc.dtlsTransport) - default: - err = errPeerConnAddTransceiverFromTrackSupport - } - if err != nil { - return - } - return newRTPTransceiver(r, s, direction, track.Kind(), pc.api), nil -} - -// AddTransceiverFromKind Create a new RtpTransceiver and adds it to the set of transceivers. -func (pc *PeerConnection) AddTransceiverFromKind(kind RTPCodecType, init ...RTPTransceiverInit) (t *RTPTransceiver, err error) { - if pc.isClosed.get() { - return nil, &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - direction := RTPTransceiverDirectionSendrecv - if len(init) > 1 { - return nil, errPeerConnAddTransceiverFromKindOnlyAcceptsOne - } else if len(init) == 1 { - direction = init[0].Direction - } - switch direction { - case RTPTransceiverDirectionSendonly, RTPTransceiverDirectionSendrecv: - codecs := pc.api.mediaEngine.getCodecsByKind(kind) - if len(codecs) == 0 { - return nil, ErrNoCodecsAvailable - } - track, err := NewTrackLocalStaticSample(codecs[0].RTPCodecCapability, util.MathRandAlpha(16), util.MathRandAlpha(16)) - if err != nil { - return nil, err - } - t, err = pc.newTransceiverFromTrack(direction, track) - if err != nil { - return nil, err - } - case RTPTransceiverDirectionRecvonly: - receiver, err := pc.api.NewRTPReceiver(kind, pc.dtlsTransport) - if err != nil { - return nil, err - } - t = newRTPTransceiver(receiver, nil, RTPTransceiverDirectionRecvonly, kind, pc.api) - default: - return nil, errPeerConnAddTransceiverFromKindSupport - } - pc.mu.Lock() - pc.addRTPTransceiver(t) - pc.mu.Unlock() - return t, nil -} - -// AddTransceiverFromTrack Create a new RtpTransceiver(SendRecv or SendOnly) and add it to the set of transceivers. -func (pc *PeerConnection) AddTransceiverFromTrack(track TrackLocal, init ...RTPTransceiverInit) (t *RTPTransceiver, err error) { - if pc.isClosed.get() { - return nil, &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - direction := RTPTransceiverDirectionSendrecv - if len(init) > 1 { - return nil, errPeerConnAddTransceiverFromTrackOnlyAcceptsOne - } else if len(init) == 1 { - direction = init[0].Direction - } - - t, err = pc.newTransceiverFromTrack(direction, track) - if err == nil { - pc.mu.Lock() - pc.addRTPTransceiver(t) - pc.mu.Unlock() - } - return -} - -// CreateDataChannel creates a new DataChannel object with the given label -// and optional DataChannelInit used to configure properties of the -// underlying channel such as data reliability. -func (pc *PeerConnection) CreateDataChannel(label string, options *DataChannelInit) (*DataChannel, error) { - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #2) - if pc.isClosed.get() { - return nil, &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - params := &DataChannelParameters{ - Label: label, - Ordered: true, - } - - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #19) - if options != nil { - params.ID = options.ID - } - - if options != nil { - // Ordered indicates if data is allowed to be delivered out of order. The - // default value of true, guarantees that data will be delivered in order. - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #9) - if options.Ordered != nil { - params.Ordered = *options.Ordered - } - - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #7) - if options.MaxPacketLifeTime != nil { - params.MaxPacketLifeTime = options.MaxPacketLifeTime - } - - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #8) - if options.MaxRetransmits != nil { - params.MaxRetransmits = options.MaxRetransmits - } - - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #10) - if options.Protocol != nil { - params.Protocol = *options.Protocol - } - - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #11) - if len(params.Protocol) > 65535 { - return nil, &rtcerr.TypeError{Err: ErrProtocolTooLarge} - } - - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #12) - if options.Negotiated != nil { - params.Negotiated = *options.Negotiated - } - } - - d, err := pc.api.newDataChannel(params, nil, pc.log) - if err != nil { - return nil, err - } - - // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #16) - if d.maxPacketLifeTime != nil && d.maxRetransmits != nil { - return nil, &rtcerr.TypeError{Err: ErrRetransmitsOrPacketLifeTime} - } - - pc.sctpTransport.lock.Lock() - pc.sctpTransport.dataChannels = append(pc.sctpTransport.dataChannels, d) - pc.sctpTransport.dataChannelsRequested++ - pc.sctpTransport.lock.Unlock() - - // If SCTP already connected open all the channels - if pc.sctpTransport.State() == SCTPTransportStateConnected { - if err = d.open(pc.sctpTransport); err != nil { - return nil, err - } - } - - pc.mu.Lock() - pc.onNegotiationNeeded() - pc.mu.Unlock() - - return d, nil -} - -// SetIdentityProvider is used to configure an identity provider to generate identity assertions -func (pc *PeerConnection) SetIdentityProvider(string) error { - return errPeerConnSetIdentityProviderNotImplemented -} - -// WriteRTCP sends a user provided RTCP packet to the connected peer. If no peer is connected the -// packet is discarded. It also runs any configured interceptors. -func (pc *PeerConnection) WriteRTCP(pkts []rtcp.Packet) error { - _, err := pc.interceptorRTCPWriter.Write(pkts, make(interceptor.Attributes)) - return err -} - -func (pc *PeerConnection) writeRTCP(pkts []rtcp.Packet, _ interceptor.Attributes) (int, error) { - return pc.dtlsTransport.WriteRTCP(pkts) -} - -// Close ends the PeerConnection -func (pc *PeerConnection) Close() error { - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #1) - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #2) - if pc.isClosed.swap(true) { - return nil - } - - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #3) - pc.signalingState.Set(SignalingStateClosed) - - // Try closing everything and collect the errors - // Shutdown strategy: - // 1. All Conn close by closing their underlying Conn. - // 2. A Mux stops this chain. It won't close the underlying - // Conn if one of the endpoints is closed down. To - // continue the chain the Mux has to be closed. - closeErrs := make([]error, 4) - - closeErrs = append(closeErrs, pc.api.interceptor.Close()) - - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #4) - pc.mu.Lock() - for _, t := range pc.rtpTransceivers { - if !t.stopped { - closeErrs = append(closeErrs, t.Stop()) - } - } - pc.mu.Unlock() - - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #5) - pc.sctpTransport.lock.Lock() - for _, d := range pc.sctpTransport.dataChannels { - d.setReadyState(DataChannelStateClosed) - } - pc.sctpTransport.lock.Unlock() - - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #6) - if pc.sctpTransport != nil { - closeErrs = append(closeErrs, pc.sctpTransport.Stop()) - } - - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #7) - closeErrs = append(closeErrs, pc.dtlsTransport.Stop()) - - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #8, #9, #10) - if pc.iceTransport != nil { - closeErrs = append(closeErrs, pc.iceTransport.Stop()) - } - - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #11) - pc.updateConnectionState(pc.ICEConnectionState(), pc.dtlsTransport.State()) - - return util.FlattenErrs(closeErrs) -} - -// addRTPTransceiver appends t into rtpTransceivers -// and fires onNegotiationNeeded; -// caller of this method should hold `pc.mu` lock -func (pc *PeerConnection) addRTPTransceiver(t *RTPTransceiver) { - pc.rtpTransceivers = append(pc.rtpTransceivers, t) - pc.onNegotiationNeeded() -} - -// CurrentLocalDescription represents the local description that was -// successfully negotiated the last time the PeerConnection transitioned -// into the stable state plus any local candidates that have been generated -// by the ICEAgent since the offer or answer was created. -func (pc *PeerConnection) CurrentLocalDescription() *SessionDescription { - pc.mu.Lock() - localDescription := pc.currentLocalDescription - iceGather := pc.iceGatherer - iceGatheringState := pc.ICEGatheringState() - pc.mu.Unlock() - return populateLocalCandidates(localDescription, iceGather, iceGatheringState) -} - -// PendingLocalDescription represents a local description that is in the -// process of being negotiated plus any local candidates that have been -// generated by the ICEAgent since the offer or answer was created. If the -// PeerConnection is in the stable state, the value is null. -func (pc *PeerConnection) PendingLocalDescription() *SessionDescription { - pc.mu.Lock() - localDescription := pc.pendingLocalDescription - iceGather := pc.iceGatherer - iceGatheringState := pc.ICEGatheringState() - pc.mu.Unlock() - return populateLocalCandidates(localDescription, iceGather, iceGatheringState) -} - -// CurrentRemoteDescription represents the last remote description that was -// successfully negotiated the last time the PeerConnection transitioned -// into the stable state plus any remote candidates that have been supplied -// via AddICECandidate() since the offer or answer was created. -func (pc *PeerConnection) CurrentRemoteDescription() *SessionDescription { - pc.mu.RLock() - defer pc.mu.RUnlock() - - return pc.currentRemoteDescription -} - -// PendingRemoteDescription represents a remote description that is in the -// process of being negotiated, complete with any remote candidates that -// have been supplied via AddICECandidate() since the offer or answer was -// created. If the PeerConnection is in the stable state, the value is -// null. -func (pc *PeerConnection) PendingRemoteDescription() *SessionDescription { - pc.mu.RLock() - defer pc.mu.RUnlock() - - return pc.pendingRemoteDescription -} - -// SignalingState attribute returns the signaling state of the -// PeerConnection instance. -func (pc *PeerConnection) SignalingState() SignalingState { - return pc.signalingState.Get() -} - -// ICEGatheringState attribute returns the ICE gathering state of the -// PeerConnection instance. -func (pc *PeerConnection) ICEGatheringState() ICEGatheringState { - if pc.iceGatherer == nil { - return ICEGatheringStateNew - } - - switch pc.iceGatherer.State() { - case ICEGathererStateNew: - return ICEGatheringStateNew - case ICEGathererStateGathering: - return ICEGatheringStateGathering - default: - return ICEGatheringStateComplete - } -} - -// ConnectionState attribute returns the connection state of the -// PeerConnection instance. -func (pc *PeerConnection) ConnectionState() PeerConnectionState { - if state, ok := pc.connectionState.Load().(PeerConnectionState); ok { - return state - } - return PeerConnectionState(0) -} - -// GetStats return data providing statistics about the overall connection -func (pc *PeerConnection) GetStats() StatsReport { - var ( - dataChannelsAccepted uint32 - dataChannelsClosed uint32 - dataChannelsOpened uint32 - dataChannelsRequested uint32 - ) - statsCollector := newStatsReportCollector() - statsCollector.Collecting() - - pc.mu.Lock() - if pc.iceGatherer != nil { - pc.iceGatherer.collectStats(statsCollector) - } - if pc.iceTransport != nil { - pc.iceTransport.collectStats(statsCollector) - } - - pc.sctpTransport.lock.Lock() - dataChannels := append([]*DataChannel{}, pc.sctpTransport.dataChannels...) - dataChannelsAccepted = pc.sctpTransport.dataChannelsAccepted - dataChannelsOpened = pc.sctpTransport.dataChannelsOpened - dataChannelsRequested = pc.sctpTransport.dataChannelsRequested - pc.sctpTransport.lock.Unlock() - - for _, d := range dataChannels { - state := d.ReadyState() - if state != DataChannelStateConnecting && state != DataChannelStateOpen { - dataChannelsClosed++ - } - - d.collectStats(statsCollector) - } - pc.sctpTransport.collectStats(statsCollector) - - stats := PeerConnectionStats{ - Timestamp: statsTimestampNow(), - Type: StatsTypePeerConnection, - ID: pc.statsID, - DataChannelsAccepted: dataChannelsAccepted, - DataChannelsClosed: dataChannelsClosed, - DataChannelsOpened: dataChannelsOpened, - DataChannelsRequested: dataChannelsRequested, - } - - statsCollector.Collect(stats.ID, stats) - - certificates := pc.configuration.Certificates - for _, certificate := range certificates { - if err := certificate.collectStats(statsCollector); err != nil { - continue - } - } - pc.mu.Unlock() - - pc.api.mediaEngine.collectStats(statsCollector) - - return statsCollector.Ready() -} - -// Start all transports. PeerConnection now has enough state -func (pc *PeerConnection) startTransports(iceRole ICERole, dtlsRole DTLSRole, remoteUfrag, remotePwd, fingerprint, fingerprintHash string) { - // Start the ice transport - err := pc.iceTransport.Start( - pc.iceGatherer, - ICEParameters{ - UsernameFragment: remoteUfrag, - Password: remotePwd, - ICELite: false, - }, - &iceRole, - ) - if err != nil { - pc.log.Warnf("Failed to start manager: %s", err) - return - } - - // Start the dtls transport - err = pc.dtlsTransport.Start(DTLSParameters{ - Role: dtlsRole, - Fingerprints: []DTLSFingerprint{{Algorithm: fingerprintHash, Value: fingerprint}}, - }) - pc.updateConnectionState(pc.ICEConnectionState(), pc.dtlsTransport.State()) - if err != nil { - pc.log.Warnf("Failed to start manager: %s", err) - return - } -} - -// nolint: gocognit -func (pc *PeerConnection) startRTP(isRenegotiation bool, remoteDesc *SessionDescription, currentTransceivers []*RTPTransceiver) { - if !isRenegotiation { - pc.undeclaredMediaProcessor() - } - - pc.startRTPReceivers(remoteDesc, currentTransceivers) - if haveApplicationMediaSection(remoteDesc.parsed) { - pc.startSCTP() - } -} - -// generateUnmatchedSDP generates an SDP that doesn't take remote state into account -// This is used for the initial call for CreateOffer -func (pc *PeerConnection) generateUnmatchedSDP(transceivers []*RTPTransceiver, useIdentity bool) (*sdp.SessionDescription, error) { - d, err := sdp.NewJSEPSessionDescription(useIdentity) - if err != nil { - return nil, err - } - - iceParams, err := pc.iceGatherer.GetLocalParameters() - if err != nil { - return nil, err - } - - candidates, err := pc.iceGatherer.GetLocalCandidates() - if err != nil { - return nil, err - } - - isPlanB := pc.configuration.SDPSemantics == SDPSemanticsPlanB - mediaSections := []mediaSection{} - - // Needed for pc.sctpTransport.dataChannelsRequested - pc.sctpTransport.lock.Lock() - defer pc.sctpTransport.lock.Unlock() - - if isPlanB { - video := make([]*RTPTransceiver, 0) - audio := make([]*RTPTransceiver, 0) - - for _, t := range transceivers { - if t.kind == RTPCodecTypeVideo { - video = append(video, t) - } else if t.kind == RTPCodecTypeAudio { - audio = append(audio, t) - } - if sender := t.Sender(); sender != nil { - sender.setNegotiated() - } - } - - if len(video) > 0 { - mediaSections = append(mediaSections, mediaSection{id: "video", transceivers: video}) - } - if len(audio) > 0 { - mediaSections = append(mediaSections, mediaSection{id: "audio", transceivers: audio}) - } - - if pc.sctpTransport.dataChannelsRequested != 0 { - mediaSections = append(mediaSections, mediaSection{id: "data", data: true}) - } - } else { - for _, t := range transceivers { - if sender := t.Sender(); sender != nil { - sender.setNegotiated() - } - mediaSections = append(mediaSections, mediaSection{id: t.Mid(), transceivers: []*RTPTransceiver{t}}) - } - - if pc.sctpTransport.dataChannelsRequested != 0 { - mediaSections = append(mediaSections, mediaSection{id: strconv.Itoa(len(mediaSections)), data: true}) - } - } - - dtlsFingerprints, err := pc.configuration.Certificates[0].GetFingerprints() - if err != nil { - return nil, err - } - - return populateSDP(d, isPlanB, dtlsFingerprints, pc.api.settingEngine.sdpMediaLevelFingerprints, pc.api.settingEngine.candidates.ICELite, true, pc.api.mediaEngine, connectionRoleFromDtlsRole(defaultDtlsRoleOffer), candidates, iceParams, mediaSections, pc.ICEGatheringState()) -} - -// generateMatchedSDP generates a SDP and takes the remote state into account -// this is used everytime we have a RemoteDescription -// nolint: gocyclo -func (pc *PeerConnection) generateMatchedSDP(transceivers []*RTPTransceiver, useIdentity bool, includeUnmatched bool, connectionRole sdp.ConnectionRole) (*sdp.SessionDescription, error) { //nolint:gocognit - d, err := sdp.NewJSEPSessionDescription(useIdentity) - if err != nil { - return nil, err - } - - iceParams, err := pc.iceGatherer.GetLocalParameters() - if err != nil { - return nil, err - } - - candidates, err := pc.iceGatherer.GetLocalCandidates() - if err != nil { - return nil, err - } - - var t *RTPTransceiver - remoteDescription := pc.currentRemoteDescription - if pc.pendingRemoteDescription != nil { - remoteDescription = pc.pendingRemoteDescription - } - isExtmapAllowMixed := isExtMapAllowMixedSet(remoteDescription.parsed) - localTransceivers := append([]*RTPTransceiver{}, transceivers...) - - detectedPlanB := descriptionIsPlanB(remoteDescription, pc.log) - if pc.configuration.SDPSemantics != SDPSemanticsUnifiedPlan { - detectedPlanB = descriptionPossiblyPlanB(remoteDescription) - } - - mediaSections := []mediaSection{} - alreadyHaveApplicationMediaSection := false - for _, media := range remoteDescription.parsed.MediaDescriptions { - midValue := getMidValue(media) - if midValue == "" { - return nil, errPeerConnRemoteDescriptionWithoutMidValue - } - - if media.MediaName.Media == mediaSectionApplication { - mediaSections = append(mediaSections, mediaSection{id: midValue, data: true}) - alreadyHaveApplicationMediaSection = true - continue - } - - kind := NewRTPCodecType(media.MediaName.Media) - direction := getPeerDirection(media) - if kind == 0 || direction == RTPTransceiverDirection(Unknown) { - continue - } - - sdpSemantics := pc.configuration.SDPSemantics - - switch { - case sdpSemantics == SDPSemanticsPlanB || sdpSemantics == SDPSemanticsUnifiedPlanWithFallback && detectedPlanB: - if !detectedPlanB { - return nil, &rtcerr.TypeError{Err: fmt.Errorf("%w: Expected PlanB, but RemoteDescription is UnifiedPlan", ErrIncorrectSDPSemantics)} - } - // If we're responding to a plan-b offer, then we should try to fill up this - // media entry with all matching local transceivers - mediaTransceivers := []*RTPTransceiver{} - for { - // keep going until we can't get any more - t, localTransceivers = satisfyTypeAndDirection(kind, direction, localTransceivers) - if t == nil { - if len(mediaTransceivers) == 0 { - t = &RTPTransceiver{kind: kind, api: pc.api, codecs: pc.api.mediaEngine.getCodecsByKind(kind)} - t.setDirection(RTPTransceiverDirectionInactive) - mediaTransceivers = append(mediaTransceivers, t) - } - break - } - if sender := t.Sender(); sender != nil { - sender.setNegotiated() - } - mediaTransceivers = append(mediaTransceivers, t) - } - mediaSections = append(mediaSections, mediaSection{id: midValue, transceivers: mediaTransceivers}) - case sdpSemantics == SDPSemanticsUnifiedPlan || sdpSemantics == SDPSemanticsUnifiedPlanWithFallback: - if detectedPlanB { - return nil, &rtcerr.TypeError{Err: fmt.Errorf("%w: Expected UnifiedPlan, but RemoteDescription is PlanB", ErrIncorrectSDPSemantics)} - } - t, localTransceivers = findByMid(midValue, localTransceivers) - if t == nil { - return nil, fmt.Errorf("%w: %q", errPeerConnTranscieverMidNil, midValue) - } - if sender := t.Sender(); sender != nil { - sender.setNegotiated() - } - mediaTransceivers := []*RTPTransceiver{t} - mediaSections = append(mediaSections, mediaSection{id: midValue, transceivers: mediaTransceivers, ridMap: getRids(media)}) - } - } - - // If we are offering also include unmatched local transceivers - if includeUnmatched { - if !detectedPlanB { - for _, t := range localTransceivers { - if sender := t.Sender(); sender != nil { - sender.setNegotiated() - } - mediaSections = append(mediaSections, mediaSection{id: t.Mid(), transceivers: []*RTPTransceiver{t}}) - } - } - - if pc.sctpTransport.dataChannelsRequested != 0 && !alreadyHaveApplicationMediaSection { - if detectedPlanB { - mediaSections = append(mediaSections, mediaSection{id: "data", data: true}) - } else { - mediaSections = append(mediaSections, mediaSection{id: strconv.Itoa(len(mediaSections)), data: true}) - } - } - } - - if pc.configuration.SDPSemantics == SDPSemanticsUnifiedPlanWithFallback && detectedPlanB { - pc.log.Info("Plan-B Offer detected; responding with Plan-B Answer") - } - - dtlsFingerprints, err := pc.configuration.Certificates[0].GetFingerprints() - if err != nil { - return nil, err - } - - return populateSDP(d, detectedPlanB, dtlsFingerprints, pc.api.settingEngine.sdpMediaLevelFingerprints, pc.api.settingEngine.candidates.ICELite, isExtmapAllowMixed, pc.api.mediaEngine, connectionRole, candidates, iceParams, mediaSections, pc.ICEGatheringState()) -} - -func (pc *PeerConnection) setGatherCompleteHandler(handler func()) { - pc.iceGatherer.onGatheringCompleteHandler.Store(handler) -} - -// SCTP returns the SCTPTransport for this PeerConnection -// -// The SCTP transport over which SCTP data is sent and received. If SCTP has not been negotiated, the value is nil. -// https://www.w3.org/TR/webrtc/#attributes-15 -func (pc *PeerConnection) SCTP() *SCTPTransport { - return pc.sctpTransport -} diff --git a/vendor/github.com/pion/webrtc/v3/peerconnection_js.go b/vendor/github.com/pion/webrtc/v3/peerconnection_js.go deleted file mode 100644 index 8322e1be..00000000 --- a/vendor/github.com/pion/webrtc/v3/peerconnection_js.go +++ /dev/null @@ -1,774 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -// Package webrtc implements the WebRTC 1.0 as defined in W3C WebRTC specification document. -package webrtc - -import ( - "syscall/js" - - "github.com/pion/ice/v2" - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -// PeerConnection represents a WebRTC connection that establishes a -// peer-to-peer communications with another PeerConnection instance in a -// browser, or to another endpoint implementing the required protocols. -type PeerConnection struct { - // Pointer to the underlying JavaScript RTCPeerConnection object. - underlying js.Value - - // Keep track of handlers/callbacks so we can call Release as required by the - // syscall/js API. Initially nil. - onSignalingStateChangeHandler *js.Func - onDataChannelHandler *js.Func - onNegotiationNeededHandler *js.Func - onConnectionStateChangeHandler *js.Func - onICEConnectionStateChangeHandler *js.Func - onICECandidateHandler *js.Func - onICEGatheringStateChangeHandler *js.Func - - // Used by GatheringCompletePromise - onGatherCompleteHandler func() - - // A reference to the associated API state used by this connection - api *API -} - -// NewPeerConnection creates a peerconnection. -func NewPeerConnection(configuration Configuration) (*PeerConnection, error) { - api := NewAPI() - return api.NewPeerConnection(configuration) -} - -// NewPeerConnection creates a new PeerConnection with the provided configuration against the received API object -func (api *API) NewPeerConnection(configuration Configuration) (_ *PeerConnection, err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - configMap := configurationToValue(configuration) - underlying := js.Global().Get("window").Get("RTCPeerConnection").New(configMap) - return &PeerConnection{ - underlying: underlying, - api: api, - }, nil -} - -// JSValue returns the underlying PeerConnection -func (pc *PeerConnection) JSValue() js.Value { - return pc.underlying -} - -// OnSignalingStateChange sets an event handler which is invoked when the -// peer connection's signaling state changes -func (pc *PeerConnection) OnSignalingStateChange(f func(SignalingState)) { - if pc.onSignalingStateChangeHandler != nil { - oldHandler := pc.onSignalingStateChangeHandler - defer oldHandler.Release() - } - onSignalingStateChangeHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - state := newSignalingState(args[0].String()) - go f(state) - return js.Undefined() - }) - pc.onSignalingStateChangeHandler = &onSignalingStateChangeHandler - pc.underlying.Set("onsignalingstatechange", onSignalingStateChangeHandler) -} - -// OnDataChannel sets an event handler which is invoked when a data -// channel message arrives from a remote peer. -func (pc *PeerConnection) OnDataChannel(f func(*DataChannel)) { - if pc.onDataChannelHandler != nil { - oldHandler := pc.onDataChannelHandler - defer oldHandler.Release() - } - onDataChannelHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - // pion/webrtc/projects/15 - // This reference to the underlying DataChannel doesn't know - // about any other references to the same DataChannel. This might result in - // memory leaks where we don't clean up handler functions. Could possibly fix - // by keeping a mutex-protected list of all DataChannel references as a - // property of this PeerConnection, but at the cost of additional overhead. - dataChannel := &DataChannel{ - underlying: args[0].Get("channel"), - api: pc.api, - } - go f(dataChannel) - return js.Undefined() - }) - pc.onDataChannelHandler = &onDataChannelHandler - pc.underlying.Set("ondatachannel", onDataChannelHandler) -} - -// OnNegotiationNeeded sets an event handler which is invoked when -// a change has occurred which requires session negotiation -func (pc *PeerConnection) OnNegotiationNeeded(f func()) { - if pc.onNegotiationNeededHandler != nil { - oldHandler := pc.onNegotiationNeededHandler - defer oldHandler.Release() - } - onNegotiationNeededHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go f() - return js.Undefined() - }) - pc.onNegotiationNeededHandler = &onNegotiationNeededHandler - pc.underlying.Set("onnegotiationneeded", onNegotiationNeededHandler) -} - -// OnICEConnectionStateChange sets an event handler which is called -// when an ICE connection state is changed. -func (pc *PeerConnection) OnICEConnectionStateChange(f func(ICEConnectionState)) { - if pc.onICEConnectionStateChangeHandler != nil { - oldHandler := pc.onICEConnectionStateChangeHandler - defer oldHandler.Release() - } - onICEConnectionStateChangeHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - connectionState := NewICEConnectionState(pc.underlying.Get("iceConnectionState").String()) - go f(connectionState) - return js.Undefined() - }) - pc.onICEConnectionStateChangeHandler = &onICEConnectionStateChangeHandler - pc.underlying.Set("oniceconnectionstatechange", onICEConnectionStateChangeHandler) -} - -// OnConnectionStateChange sets an event handler which is called -// when an PeerConnectionState is changed. -func (pc *PeerConnection) OnConnectionStateChange(f func(PeerConnectionState)) { - if pc.onConnectionStateChangeHandler != nil { - oldHandler := pc.onConnectionStateChangeHandler - defer oldHandler.Release() - } - onConnectionStateChangeHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - connectionState := newPeerConnectionState(pc.underlying.Get("connectionState").String()) - go f(connectionState) - return js.Undefined() - }) - pc.onConnectionStateChangeHandler = &onConnectionStateChangeHandler - pc.underlying.Set("onconnectionstatechange", onConnectionStateChangeHandler) -} - -func (pc *PeerConnection) checkConfiguration(configuration Configuration) error { - // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-setconfiguration (step #2) - if pc.ConnectionState() == PeerConnectionStateClosed { - return &rtcerr.InvalidStateError{Err: ErrConnectionClosed} - } - - existingConfig := pc.GetConfiguration() - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #3) - if configuration.PeerIdentity != "" { - if configuration.PeerIdentity != existingConfig.PeerIdentity { - return &rtcerr.InvalidModificationError{Err: ErrModifyingPeerIdentity} - } - } - - // https://github.com/pion/webrtc/issues/513 - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #4) - // if len(configuration.Certificates) > 0 { - // if len(configuration.Certificates) != len(existingConfiguration.Certificates) { - // return &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates} - // } - - // for i, certificate := range configuration.Certificates { - // if !pc.configuration.Certificates[i].Equals(certificate) { - // return &rtcerr.InvalidModificationError{Err: ErrModifyingCertificates} - // } - // } - // pc.configuration.Certificates = configuration.Certificates - // } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #5) - if configuration.BundlePolicy != BundlePolicy(Unknown) { - if configuration.BundlePolicy != existingConfig.BundlePolicy { - return &rtcerr.InvalidModificationError{Err: ErrModifyingBundlePolicy} - } - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #6) - if configuration.RTCPMuxPolicy != RTCPMuxPolicy(Unknown) { - if configuration.RTCPMuxPolicy != existingConfig.RTCPMuxPolicy { - return &rtcerr.InvalidModificationError{Err: ErrModifyingRTCPMuxPolicy} - } - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #7) - if configuration.ICECandidatePoolSize != 0 { - if configuration.ICECandidatePoolSize != existingConfig.ICECandidatePoolSize && - pc.LocalDescription() != nil { - return &rtcerr.InvalidModificationError{Err: ErrModifyingICECandidatePoolSize} - } - } - - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11) - if len(configuration.ICEServers) > 0 { - // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3) - for _, server := range configuration.ICEServers { - if _, err := server.validate(); err != nil { - return err - } - } - } - return nil -} - -// SetConfiguration updates the configuration of this PeerConnection object. -func (pc *PeerConnection) SetConfiguration(configuration Configuration) (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - if err := pc.checkConfiguration(configuration); err != nil { - return err - } - configMap := configurationToValue(configuration) - pc.underlying.Call("setConfiguration", configMap) - return nil -} - -// GetConfiguration returns a Configuration object representing the current -// configuration of this PeerConnection object. The returned object is a -// copy and direct mutation on it will not take affect until SetConfiguration -// has been called with Configuration passed as its only argument. -// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-getconfiguration -func (pc *PeerConnection) GetConfiguration() Configuration { - return valueToConfiguration(pc.underlying.Call("getConfiguration")) -} - -// CreateOffer starts the PeerConnection and generates the localDescription -func (pc *PeerConnection) CreateOffer(options *OfferOptions) (_ SessionDescription, err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - promise := pc.underlying.Call("createOffer", offerOptionsToValue(options)) - desc, err := awaitPromise(promise) - if err != nil { - return SessionDescription{}, err - } - return *valueToSessionDescription(desc), nil -} - -// CreateAnswer starts the PeerConnection and generates the localDescription -func (pc *PeerConnection) CreateAnswer(options *AnswerOptions) (_ SessionDescription, err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - promise := pc.underlying.Call("createAnswer", answerOptionsToValue(options)) - desc, err := awaitPromise(promise) - if err != nil { - return SessionDescription{}, err - } - return *valueToSessionDescription(desc), nil -} - -// SetLocalDescription sets the SessionDescription of the local peer -func (pc *PeerConnection) SetLocalDescription(desc SessionDescription) (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - promise := pc.underlying.Call("setLocalDescription", sessionDescriptionToValue(&desc)) - _, err = awaitPromise(promise) - return err -} - -// LocalDescription returns PendingLocalDescription if it is not null and -// otherwise it returns CurrentLocalDescription. This property is used to -// determine if setLocalDescription has already been called. -// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-localdescription -func (pc *PeerConnection) LocalDescription() *SessionDescription { - return valueToSessionDescription(pc.underlying.Get("localDescription")) -} - -// SetRemoteDescription sets the SessionDescription of the remote peer -func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - promise := pc.underlying.Call("setRemoteDescription", sessionDescriptionToValue(&desc)) - _, err = awaitPromise(promise) - return err -} - -// RemoteDescription returns PendingRemoteDescription if it is not null and -// otherwise it returns CurrentRemoteDescription. This property is used to -// determine if setRemoteDescription has already been called. -// https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-remotedescription -func (pc *PeerConnection) RemoteDescription() *SessionDescription { - return valueToSessionDescription(pc.underlying.Get("remoteDescription")) -} - -// AddICECandidate accepts an ICE candidate string and adds it -// to the existing set of candidates -func (pc *PeerConnection) AddICECandidate(candidate ICECandidateInit) (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - promise := pc.underlying.Call("addIceCandidate", iceCandidateInitToValue(candidate)) - _, err = awaitPromise(promise) - return err -} - -// ICEConnectionState returns the ICE connection state of the -// PeerConnection instance. -func (pc *PeerConnection) ICEConnectionState() ICEConnectionState { - return NewICEConnectionState(pc.underlying.Get("iceConnectionState").String()) -} - -// OnICECandidate sets an event handler which is invoked when a new ICE -// candidate is found. -func (pc *PeerConnection) OnICECandidate(f func(candidate *ICECandidate)) { - if pc.onICECandidateHandler != nil { - oldHandler := pc.onICECandidateHandler - defer oldHandler.Release() - } - onICECandidateHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - candidate := valueToICECandidate(args[0].Get("candidate")) - if candidate == nil && pc.onGatherCompleteHandler != nil { - go pc.onGatherCompleteHandler() - } - - go f(candidate) - return js.Undefined() - }) - pc.onICECandidateHandler = &onICECandidateHandler - pc.underlying.Set("onicecandidate", onICECandidateHandler) -} - -// OnICEGatheringStateChange sets an event handler which is invoked when the -// ICE candidate gathering state has changed. -func (pc *PeerConnection) OnICEGatheringStateChange(f func()) { - if pc.onICEGatheringStateChangeHandler != nil { - oldHandler := pc.onICEGatheringStateChangeHandler - defer oldHandler.Release() - } - onICEGatheringStateChangeHandler := js.FuncOf(func(this js.Value, args []js.Value) interface{} { - go f() - return js.Undefined() - }) - pc.onICEGatheringStateChangeHandler = &onICEGatheringStateChangeHandler - pc.underlying.Set("onicegatheringstatechange", onICEGatheringStateChangeHandler) -} - -// CreateDataChannel creates a new DataChannel object with the given label -// and optional DataChannelInit used to configure properties of the -// underlying channel such as data reliability. -func (pc *PeerConnection) CreateDataChannel(label string, options *DataChannelInit) (_ *DataChannel, err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - channel := pc.underlying.Call("createDataChannel", label, dataChannelInitToValue(options)) - return &DataChannel{ - underlying: channel, - api: pc.api, - }, nil -} - -// SetIdentityProvider is used to configure an identity provider to generate identity assertions -func (pc *PeerConnection) SetIdentityProvider(provider string) (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - pc.underlying.Call("setIdentityProvider", provider) - return nil -} - -// Close ends the PeerConnection -func (pc *PeerConnection) Close() (err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - - pc.underlying.Call("close") - - // Release any handlers as required by the syscall/js API. - if pc.onSignalingStateChangeHandler != nil { - pc.onSignalingStateChangeHandler.Release() - } - if pc.onDataChannelHandler != nil { - pc.onDataChannelHandler.Release() - } - if pc.onNegotiationNeededHandler != nil { - pc.onNegotiationNeededHandler.Release() - } - if pc.onConnectionStateChangeHandler != nil { - pc.onConnectionStateChangeHandler.Release() - } - if pc.onICEConnectionStateChangeHandler != nil { - pc.onICEConnectionStateChangeHandler.Release() - } - if pc.onICECandidateHandler != nil { - pc.onICECandidateHandler.Release() - } - if pc.onICEGatheringStateChangeHandler != nil { - pc.onICEGatheringStateChangeHandler.Release() - } - - return nil -} - -// CurrentLocalDescription represents the local description that was -// successfully negotiated the last time the PeerConnection transitioned -// into the stable state plus any local candidates that have been generated -// by the ICEAgent since the offer or answer was created. -func (pc *PeerConnection) CurrentLocalDescription() *SessionDescription { - desc := pc.underlying.Get("currentLocalDescription") - return valueToSessionDescription(desc) -} - -// PendingLocalDescription represents a local description that is in the -// process of being negotiated plus any local candidates that have been -// generated by the ICEAgent since the offer or answer was created. If the -// PeerConnection is in the stable state, the value is null. -func (pc *PeerConnection) PendingLocalDescription() *SessionDescription { - desc := pc.underlying.Get("pendingLocalDescription") - return valueToSessionDescription(desc) -} - -// CurrentRemoteDescription represents the last remote description that was -// successfully negotiated the last time the PeerConnection transitioned -// into the stable state plus any remote candidates that have been supplied -// via AddICECandidate() since the offer or answer was created. -func (pc *PeerConnection) CurrentRemoteDescription() *SessionDescription { - desc := pc.underlying.Get("currentRemoteDescription") - return valueToSessionDescription(desc) -} - -// PendingRemoteDescription represents a remote description that is in the -// process of being negotiated, complete with any remote candidates that -// have been supplied via AddICECandidate() since the offer or answer was -// created. If the PeerConnection is in the stable state, the value is -// null. -func (pc *PeerConnection) PendingRemoteDescription() *SessionDescription { - desc := pc.underlying.Get("pendingRemoteDescription") - return valueToSessionDescription(desc) -} - -// SignalingState returns the signaling state of the PeerConnection instance. -func (pc *PeerConnection) SignalingState() SignalingState { - rawState := pc.underlying.Get("signalingState").String() - return newSignalingState(rawState) -} - -// ICEGatheringState attribute the ICE gathering state of the PeerConnection -// instance. -func (pc *PeerConnection) ICEGatheringState() ICEGatheringState { - rawState := pc.underlying.Get("iceGatheringState").String() - return NewICEGatheringState(rawState) -} - -// ConnectionState attribute the connection state of the PeerConnection -// instance. -func (pc *PeerConnection) ConnectionState() PeerConnectionState { - rawState := pc.underlying.Get("connectionState").String() - return newPeerConnectionState(rawState) -} - -func (pc *PeerConnection) setGatherCompleteHandler(handler func()) { - pc.onGatherCompleteHandler = handler - - // If no onIceCandidate handler has been set provide an empty one - // otherwise our onGatherCompleteHandler will not be executed - if pc.onICECandidateHandler == nil { - pc.OnICECandidate(func(i *ICECandidate) {}) - } -} - -// AddTransceiverFromKind Create a new RtpTransceiver and adds it to the set of transceivers. -func (pc *PeerConnection) AddTransceiverFromKind(kind RTPCodecType, init ...RTPTransceiverInit) (transceiver *RTPTransceiver, err error) { - defer func() { - if e := recover(); e != nil { - err = recoveryToError(e) - } - }() - - if len(init) == 1 { - return &RTPTransceiver{ - underlying: pc.underlying.Call("addTransceiver", kind.String(), rtpTransceiverInitInitToValue(init[0])), - }, err - } - - return &RTPTransceiver{ - underlying: pc.underlying.Call("addTransceiver", kind.String()), - }, err -} - -// GetTransceivers returns the RtpTransceiver that are currently attached to this PeerConnection -func (pc *PeerConnection) GetTransceivers() (transceivers []*RTPTransceiver) { - rawTransceivers := pc.underlying.Call("getTransceivers") - transceivers = make([]*RTPTransceiver, rawTransceivers.Length()) - - for i := 0; i < rawTransceivers.Length(); i++ { - transceivers[i] = &RTPTransceiver{ - underlying: rawTransceivers.Index(i), - } - } - - return -} - -// SCTP returns the SCTPTransport for this PeerConnection -// -// The SCTP transport over which SCTP data is sent and received. If SCTP has not been negotiated, the value is nil. -// https://www.w3.org/TR/webrtc/#attributes-15 -func (pc *PeerConnection) SCTP() *SCTPTransport { - underlying := pc.underlying.Get("sctp") - if underlying.IsNull() || underlying.IsUndefined() { - return nil - } - - return &SCTPTransport{ - underlying: underlying, - } -} - -// Converts a Configuration to js.Value so it can be passed -// through to the JavaScript WebRTC API. Any zero values are converted to -// js.Undefined(), which will result in the default value being used. -func configurationToValue(configuration Configuration) js.Value { - return js.ValueOf(map[string]interface{}{ - "iceServers": iceServersToValue(configuration.ICEServers), - "iceTransportPolicy": stringEnumToValueOrUndefined(configuration.ICETransportPolicy.String()), - "bundlePolicy": stringEnumToValueOrUndefined(configuration.BundlePolicy.String()), - "rtcpMuxPolicy": stringEnumToValueOrUndefined(configuration.RTCPMuxPolicy.String()), - "peerIdentity": stringToValueOrUndefined(configuration.PeerIdentity), - "iceCandidatePoolSize": uint8ToValueOrUndefined(configuration.ICECandidatePoolSize), - - // Note: Certificates are not currently supported. - // "certificates": configuration.Certificates, - }) -} - -func iceServersToValue(iceServers []ICEServer) js.Value { - if len(iceServers) == 0 { - return js.Undefined() - } - maps := make([]interface{}, len(iceServers)) - for i, server := range iceServers { - maps[i] = iceServerToValue(server) - } - return js.ValueOf(maps) -} - -func oauthCredentialToValue(o OAuthCredential) js.Value { - out := map[string]interface{}{ - "MACKey": o.MACKey, - "AccessToken": o.AccessToken, - } - return js.ValueOf(out) -} - -func iceServerToValue(server ICEServer) js.Value { - out := map[string]interface{}{ - "urls": stringsToValue(server.URLs), // required - } - if server.Username != "" { - out["username"] = stringToValueOrUndefined(server.Username) - } - if server.Credential != nil { - switch t := server.Credential.(type) { - case string: - out["credential"] = stringToValueOrUndefined(t) - case OAuthCredential: - out["credential"] = oauthCredentialToValue(t) - } - } - out["credentialType"] = stringEnumToValueOrUndefined(server.CredentialType.String()) - return js.ValueOf(out) -} - -func valueToConfiguration(configValue js.Value) Configuration { - if configValue.IsNull() || configValue.IsUndefined() { - return Configuration{} - } - return Configuration{ - ICEServers: valueToICEServers(configValue.Get("iceServers")), - ICETransportPolicy: NewICETransportPolicy(valueToStringOrZero(configValue.Get("iceTransportPolicy"))), - BundlePolicy: newBundlePolicy(valueToStringOrZero(configValue.Get("bundlePolicy"))), - RTCPMuxPolicy: newRTCPMuxPolicy(valueToStringOrZero(configValue.Get("rtcpMuxPolicy"))), - PeerIdentity: valueToStringOrZero(configValue.Get("peerIdentity")), - ICECandidatePoolSize: valueToUint8OrZero(configValue.Get("iceCandidatePoolSize")), - - // Note: Certificates are not supported. - // Certificates []Certificate - } -} - -func valueToICEServers(iceServersValue js.Value) []ICEServer { - if iceServersValue.IsNull() || iceServersValue.IsUndefined() { - return nil - } - iceServers := make([]ICEServer, iceServersValue.Length()) - for i := 0; i < iceServersValue.Length(); i++ { - iceServers[i] = valueToICEServer(iceServersValue.Index(i)) - } - return iceServers -} - -func valueToICECredential(iceCredentialValue js.Value) interface{} { - if iceCredentialValue.IsNull() || iceCredentialValue.IsUndefined() { - return nil - } - if iceCredentialValue.Type() == js.TypeString { - return iceCredentialValue.String() - } - if iceCredentialValue.Type() == js.TypeObject { - return OAuthCredential{ - MACKey: iceCredentialValue.Get("MACKey").String(), - AccessToken: iceCredentialValue.Get("AccessToken").String(), - } - } - return nil -} - -func valueToICEServer(iceServerValue js.Value) ICEServer { - tpe, err := newICECredentialType(valueToStringOrZero(iceServerValue.Get("credentialType"))) - if err != nil { - tpe = ICECredentialTypePassword - } - s := ICEServer{ - URLs: valueToStrings(iceServerValue.Get("urls")), // required - Username: valueToStringOrZero(iceServerValue.Get("username")), - // Note: Credential and CredentialType are not currently supported. - Credential: valueToICECredential(iceServerValue.Get("credential")), - CredentialType: tpe, - } - - return s -} - -func valueToICECandidate(val js.Value) *ICECandidate { - if val.IsNull() || val.IsUndefined() { - return nil - } - if val.Get("protocol").IsUndefined() && !val.Get("candidate").IsUndefined() { - // Missing some fields, assume it's Firefox and parse SDP candidate. - c, err := ice.UnmarshalCandidate(val.Get("candidate").String()) - if err != nil { - return nil - } - - iceCandidate, err := newICECandidateFromICE(c) - if err != nil { - return nil - } - - return &iceCandidate - } - protocol, _ := NewICEProtocol(val.Get("protocol").String()) - candidateType, _ := NewICECandidateType(val.Get("type").String()) - return &ICECandidate{ - Foundation: val.Get("foundation").String(), - Priority: valueToUint32OrZero(val.Get("priority")), - Address: val.Get("address").String(), - Protocol: protocol, - Port: valueToUint16OrZero(val.Get("port")), - Typ: candidateType, - Component: stringToComponentIDOrZero(val.Get("component").String()), - RelatedAddress: val.Get("relatedAddress").String(), - RelatedPort: valueToUint16OrZero(val.Get("relatedPort")), - } -} - -func stringToComponentIDOrZero(val string) uint16 { - // See: https://developer.mozilla.org/en-US/docs/Web/API/RTCIceComponent - switch val { - case "rtp": - return 1 - case "rtcp": - return 2 - } - return 0 -} - -func sessionDescriptionToValue(desc *SessionDescription) js.Value { - if desc == nil { - return js.Undefined() - } - return js.ValueOf(map[string]interface{}{ - "type": desc.Type.String(), - "sdp": desc.SDP, - }) -} - -func valueToSessionDescription(descValue js.Value) *SessionDescription { - if descValue.IsNull() || descValue.IsUndefined() { - return nil - } - return &SessionDescription{ - Type: NewSDPType(descValue.Get("type").String()), - SDP: descValue.Get("sdp").String(), - } -} - -func offerOptionsToValue(offerOptions *OfferOptions) js.Value { - if offerOptions == nil { - return js.Undefined() - } - return js.ValueOf(map[string]interface{}{ - "iceRestart": offerOptions.ICERestart, - "voiceActivityDetection": offerOptions.VoiceActivityDetection, - }) -} - -func answerOptionsToValue(answerOptions *AnswerOptions) js.Value { - if answerOptions == nil { - return js.Undefined() - } - return js.ValueOf(map[string]interface{}{ - "voiceActivityDetection": answerOptions.VoiceActivityDetection, - }) -} - -func iceCandidateInitToValue(candidate ICECandidateInit) js.Value { - return js.ValueOf(map[string]interface{}{ - "candidate": candidate.Candidate, - "sdpMid": stringPointerToValue(candidate.SDPMid), - "sdpMLineIndex": uint16PointerToValue(candidate.SDPMLineIndex), - "usernameFragment": stringPointerToValue(candidate.UsernameFragment), - }) -} - -func dataChannelInitToValue(options *DataChannelInit) js.Value { - if options == nil { - return js.Undefined() - } - - maxPacketLifeTime := uint16PointerToValue(options.MaxPacketLifeTime) - return js.ValueOf(map[string]interface{}{ - "ordered": boolPointerToValue(options.Ordered), - "maxPacketLifeTime": maxPacketLifeTime, - // See https://bugs.chromium.org/p/chromium/issues/detail?id=696681 - // Chrome calls this "maxRetransmitTime" - "maxRetransmitTime": maxPacketLifeTime, - "maxRetransmits": uint16PointerToValue(options.MaxRetransmits), - "protocol": stringPointerToValue(options.Protocol), - "negotiated": boolPointerToValue(options.Negotiated), - "id": uint16PointerToValue(options.ID), - }) -} - -func rtpTransceiverInitInitToValue(init RTPTransceiverInit) js.Value { - return js.ValueOf(map[string]interface{}{ - "direction": init.Direction.String(), - }) -} diff --git a/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go b/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go deleted file mode 100644 index 1f145688..00000000 --- a/vendor/github.com/pion/webrtc/v3/peerconnectionstate.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// PeerConnectionState indicates the state of the PeerConnection. -type PeerConnectionState int - -const ( - // PeerConnectionStateNew indicates that any of the ICETransports or - // DTLSTransports are in the "new" state and none of the transports are - // in the "connecting", "checking", "failed" or "disconnected" state, or - // all transports are in the "closed" state, or there are no transports. - PeerConnectionStateNew PeerConnectionState = iota + 1 - - // PeerConnectionStateConnecting indicates that any of the - // ICETransports or DTLSTransports are in the "connecting" or - // "checking" state and none of them is in the "failed" state. - PeerConnectionStateConnecting - - // PeerConnectionStateConnected indicates that all ICETransports and - // DTLSTransports are in the "connected", "completed" or "closed" state - // and at least one of them is in the "connected" or "completed" state. - PeerConnectionStateConnected - - // PeerConnectionStateDisconnected indicates that any of the - // ICETransports or DTLSTransports are in the "disconnected" state - // and none of them are in the "failed" or "connecting" or "checking" state. - PeerConnectionStateDisconnected - - // PeerConnectionStateFailed indicates that any of the ICETransports - // or DTLSTransports are in a "failed" state. - PeerConnectionStateFailed - - // PeerConnectionStateClosed indicates the peer connection is closed - // and the isClosed member variable of PeerConnection is true. - PeerConnectionStateClosed -) - -// This is done this way because of a linter. -const ( - peerConnectionStateNewStr = "new" - peerConnectionStateConnectingStr = "connecting" - peerConnectionStateConnectedStr = "connected" - peerConnectionStateDisconnectedStr = "disconnected" - peerConnectionStateFailedStr = "failed" - peerConnectionStateClosedStr = "closed" -) - -func newPeerConnectionState(raw string) PeerConnectionState { - switch raw { - case peerConnectionStateNewStr: - return PeerConnectionStateNew - case peerConnectionStateConnectingStr: - return PeerConnectionStateConnecting - case peerConnectionStateConnectedStr: - return PeerConnectionStateConnected - case peerConnectionStateDisconnectedStr: - return PeerConnectionStateDisconnected - case peerConnectionStateFailedStr: - return PeerConnectionStateFailed - case peerConnectionStateClosedStr: - return PeerConnectionStateClosed - default: - return PeerConnectionState(Unknown) - } -} - -func (t PeerConnectionState) String() string { - switch t { - case PeerConnectionStateNew: - return peerConnectionStateNewStr - case PeerConnectionStateConnecting: - return peerConnectionStateConnectingStr - case PeerConnectionStateConnected: - return peerConnectionStateConnectedStr - case PeerConnectionStateDisconnected: - return peerConnectionStateDisconnectedStr - case PeerConnectionStateFailed: - return peerConnectionStateFailedStr - case PeerConnectionStateClosed: - return peerConnectionStateClosedStr - default: - return ErrUnknownType.Error() - } -} - -type negotiationNeededState int - -const ( - // NegotiationNeededStateEmpty not running and queue is empty - negotiationNeededStateEmpty = iota - // NegotiationNeededStateEmpty running and queue is empty - negotiationNeededStateRun - // NegotiationNeededStateEmpty running and queue - negotiationNeededStateQueue -) diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/h264reader/h264reader.go b/vendor/github.com/pion/webrtc/v3/pkg/media/h264reader/h264reader.go deleted file mode 100644 index c9975910..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/h264reader/h264reader.go +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package h264reader implements a H264 Annex-B Reader -package h264reader - -import ( - "bytes" - "errors" - "io" -) - -// H264Reader reads data from stream and constructs h264 nal units -type H264Reader struct { - stream io.Reader - nalBuffer []byte - countOfConsecutiveZeroBytes int - nalPrefixParsed bool - readBuffer []byte - tmpReadBuf []byte -} - -var ( - errNilReader = errors.New("stream is nil") - errDataIsNotH264Stream = errors.New("data is not a H264 bitstream") -) - -// NewReader creates new H264Reader -func NewReader(in io.Reader) (*H264Reader, error) { - if in == nil { - return nil, errNilReader - } - - reader := &H264Reader{ - stream: in, - nalBuffer: make([]byte, 0), - nalPrefixParsed: false, - readBuffer: make([]byte, 0), - tmpReadBuf: make([]byte, 4096), - } - - return reader, nil -} - -// NAL H.264 Network Abstraction Layer -type NAL struct { - PictureOrderCount uint32 - - // NAL header - ForbiddenZeroBit bool - RefIdc uint8 - UnitType NalUnitType - - Data []byte // header byte + rbsp -} - -func (reader *H264Reader) read(numToRead int) (data []byte, e error) { - for len(reader.readBuffer) < numToRead { - n, err := reader.stream.Read(reader.tmpReadBuf) - if err != nil { - return nil, err - } - if n == 0 { - break - } - reader.readBuffer = append(reader.readBuffer, reader.tmpReadBuf[0:n]...) - } - var numShouldRead int - if numToRead <= len(reader.readBuffer) { - numShouldRead = numToRead - } else { - numShouldRead = len(reader.readBuffer) - } - data = reader.readBuffer[0:numShouldRead] - reader.readBuffer = reader.readBuffer[numShouldRead:] - return data, nil -} - -func (reader *H264Reader) bitStreamStartsWithH264Prefix() (prefixLength int, e error) { - nalPrefix3Bytes := []byte{0, 0, 1} - nalPrefix4Bytes := []byte{0, 0, 0, 1} - - prefixBuffer, e := reader.read(4) - if e != nil { - return - } - - n := len(prefixBuffer) - - if n == 0 { - return 0, io.EOF - } - - if n < 3 { - return 0, errDataIsNotH264Stream - } - - nalPrefix3BytesFound := bytes.Equal(nalPrefix3Bytes, prefixBuffer[:3]) - if n == 3 { - if nalPrefix3BytesFound { - return 0, io.EOF - } - return 0, errDataIsNotH264Stream - } - - // n == 4 - if nalPrefix3BytesFound { - reader.nalBuffer = append(reader.nalBuffer, prefixBuffer[3]) - return 3, nil - } - - nalPrefix4BytesFound := bytes.Equal(nalPrefix4Bytes, prefixBuffer) - if nalPrefix4BytesFound { - return 4, nil - } - return 0, errDataIsNotH264Stream -} - -// NextNAL reads from stream and returns then next NAL, -// and an error if there is incomplete frame data. -// Returns all nil values when no more NALs are available. -func (reader *H264Reader) NextNAL() (*NAL, error) { - if !reader.nalPrefixParsed { - _, err := reader.bitStreamStartsWithH264Prefix() - if err != nil { - return nil, err - } - - reader.nalPrefixParsed = true - } - - for { - buffer, err := reader.read(1) - if err != nil { - break - } - - n := len(buffer) - - if n != 1 { - break - } - readByte := buffer[0] - nalFound := reader.processByte(readByte) - if nalFound { - nal := newNal(reader.nalBuffer) - nal.parseHeader() - if nal.UnitType == NalUnitTypeSEI { - reader.nalBuffer = nil - continue - } - break - } - - reader.nalBuffer = append(reader.nalBuffer, readByte) - } - - if len(reader.nalBuffer) == 0 { - return nil, io.EOF - } - - nal := newNal(reader.nalBuffer) - reader.nalBuffer = nil - nal.parseHeader() - - return nal, nil -} - -func (reader *H264Reader) processByte(readByte byte) (nalFound bool) { - nalFound = false - - switch readByte { - case 0: - reader.countOfConsecutiveZeroBytes++ - case 1: - if reader.countOfConsecutiveZeroBytes >= 2 { - countOfConsecutiveZeroBytesInPrefix := 2 - if reader.countOfConsecutiveZeroBytes > 2 { - countOfConsecutiveZeroBytesInPrefix = 3 - } - - if nalUnitLength := len(reader.nalBuffer) - countOfConsecutiveZeroBytesInPrefix; nalUnitLength > 0 { - reader.nalBuffer = reader.nalBuffer[0:nalUnitLength] - nalFound = true - } - } - - reader.countOfConsecutiveZeroBytes = 0 - default: - reader.countOfConsecutiveZeroBytes = 0 - } - - return nalFound -} - -func newNal(data []byte) *NAL { - return &NAL{PictureOrderCount: 0, ForbiddenZeroBit: false, RefIdc: 0, UnitType: NalUnitTypeUnspecified, Data: data} -} - -func (h *NAL) parseHeader() { - firstByte := h.Data[0] - h.ForbiddenZeroBit = (((firstByte & 0x80) >> 7) == 1) // 0x80 = 0b10000000 - h.RefIdc = (firstByte & 0x60) >> 5 // 0x60 = 0b01100000 - h.UnitType = NalUnitType((firstByte & 0x1F) >> 0) // 0x1F = 0b00011111 -} diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/h264reader/nalunittype.go b/vendor/github.com/pion/webrtc/v3/pkg/media/h264reader/nalunittype.go deleted file mode 100644 index 7d87342b..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/h264reader/nalunittype.go +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package h264reader - -import "strconv" - -// NalUnitType is the type of a NAL -type NalUnitType uint8 - -// Enums for NalUnitTypes -const ( - NalUnitTypeUnspecified NalUnitType = 0 // Unspecified - NalUnitTypeCodedSliceNonIdr NalUnitType = 1 // Coded slice of a non-IDR picture - NalUnitTypeCodedSliceDataPartitionA NalUnitType = 2 // Coded slice data partition A - NalUnitTypeCodedSliceDataPartitionB NalUnitType = 3 // Coded slice data partition B - NalUnitTypeCodedSliceDataPartitionC NalUnitType = 4 // Coded slice data partition C - NalUnitTypeCodedSliceIdr NalUnitType = 5 // Coded slice of an IDR picture - NalUnitTypeSEI NalUnitType = 6 // Supplemental enhancement information (SEI) - NalUnitTypeSPS NalUnitType = 7 // Sequence parameter set - NalUnitTypePPS NalUnitType = 8 // Picture parameter set - NalUnitTypeAUD NalUnitType = 9 // Access unit delimiter - NalUnitTypeEndOfSequence NalUnitType = 10 // End of sequence - NalUnitTypeEndOfStream NalUnitType = 11 // End of stream - NalUnitTypeFiller NalUnitType = 12 // Filler data - NalUnitTypeSpsExt NalUnitType = 13 // Sequence parameter set extension - NalUnitTypeCodedSliceAux NalUnitType = 19 // Coded slice of an auxiliary coded picture without partitioning - // 14..18 // Reserved - // 20..23 // Reserved - // 24..31 // Unspecified -) - -func (n *NalUnitType) String() string { - var str string - switch *n { - case NalUnitTypeUnspecified: - str = "Unspecified" - case NalUnitTypeCodedSliceNonIdr: - str = "CodedSliceNonIdr" - case NalUnitTypeCodedSliceDataPartitionA: - str = "CodedSliceDataPartitionA" - case NalUnitTypeCodedSliceDataPartitionB: - str = "CodedSliceDataPartitionB" - case NalUnitTypeCodedSliceDataPartitionC: - str = "CodedSliceDataPartitionC" - case NalUnitTypeCodedSliceIdr: - str = "CodedSliceIdr" - case NalUnitTypeSEI: - str = "SEI" - case NalUnitTypeSPS: - str = "SPS" - case NalUnitTypePPS: - str = "PPS" - case NalUnitTypeAUD: - str = "AUD" - case NalUnitTypeEndOfSequence: - str = "EndOfSequence" - case NalUnitTypeEndOfStream: - str = "EndOfStream" - case NalUnitTypeFiller: - str = "Filler" - case NalUnitTypeSpsExt: - str = "SpsExt" - case NalUnitTypeCodedSliceAux: - str = "NalUnitTypeCodedSliceAux" - default: - str = "Unknown" - } - str = str + "(" + strconv.FormatInt(int64(*n), 10) + ")" - return str -} diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/h264writer/h264writer.go b/vendor/github.com/pion/webrtc/v3/pkg/media/h264writer/h264writer.go deleted file mode 100644 index cc8f64ba..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/h264writer/h264writer.go +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package h264writer implements H264 media container writer -package h264writer - -import ( - "bytes" - "encoding/binary" - "io" - "os" - - "github.com/pion/rtp" - "github.com/pion/rtp/codecs" -) - -type ( - // H264Writer is used to take RTP packets, parse them and - // write the data to an io.Writer. - // Currently it only supports non-interleaved mode - // Therefore, only 1-23, 24 (STAP-A), 28 (FU-A) NAL types are allowed. - // https://tools.ietf.org/html/rfc6184#section-5.2 - H264Writer struct { - writer io.Writer - hasKeyFrame bool - cachedPacket *codecs.H264Packet - } -) - -// New builds a new H264 writer -func New(filename string) (*H264Writer, error) { - f, err := os.Create(filename) //nolint:gosec - if err != nil { - return nil, err - } - - return NewWith(f), nil -} - -// NewWith initializes a new H264 writer with an io.Writer output -func NewWith(w io.Writer) *H264Writer { - return &H264Writer{ - writer: w, - } -} - -// WriteRTP adds a new packet and writes the appropriate headers for it -func (h *H264Writer) WriteRTP(packet *rtp.Packet) error { - if len(packet.Payload) == 0 { - return nil - } - - if !h.hasKeyFrame { - if h.hasKeyFrame = isKeyFrame(packet.Payload); !h.hasKeyFrame { - // key frame not defined yet. discarding packet - return nil - } - } - - if h.cachedPacket == nil { - h.cachedPacket = &codecs.H264Packet{} - } - - data, err := h.cachedPacket.Unmarshal(packet.Payload) - if err != nil { - return err - } - - _, err = h.writer.Write(data) - - return err -} - -// Close closes the underlying writer -func (h *H264Writer) Close() error { - h.cachedPacket = nil - if h.writer != nil { - if closer, ok := h.writer.(io.Closer); ok { - return closer.Close() - } - } - - return nil -} - -func isKeyFrame(data []byte) bool { - const ( - typeSTAPA = 24 - typeSPS = 7 - naluTypeBitmask = 0x1F - ) - - var word uint32 - - payload := bytes.NewReader(data) - if err := binary.Read(payload, binary.BigEndian, &word); err != nil { - return false - } - - naluType := (word >> 24) & naluTypeBitmask - if naluType == typeSTAPA && word&naluTypeBitmask == typeSPS { - return true - } else if naluType == typeSPS { - return true - } - - return false -} diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/ivfwriter/ivfwriter.go b/vendor/github.com/pion/webrtc/v3/pkg/media/ivfwriter/ivfwriter.go deleted file mode 100644 index 6d7b506e..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/ivfwriter/ivfwriter.go +++ /dev/null @@ -1,233 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package ivfwriter implements IVF media container writer -package ivfwriter - -import ( - "encoding/binary" - "errors" - "io" - "os" - - "github.com/pion/rtp" - "github.com/pion/rtp/codecs" - "github.com/pion/rtp/pkg/frame" -) - -var ( - errFileNotOpened = errors.New("file not opened") - errInvalidNilPacket = errors.New("invalid nil packet") - errCodecAlreadySet = errors.New("codec is already set") - errNoSuchCodec = errors.New("no codec for this MimeType") -) - -const ( - mimeTypeVP8 = "video/VP8" - mimeTypeAV1 = "video/AV1" - - ivfFileHeaderSignature = "DKIF" -) - -// IVFWriter is used to take RTP packets and write them to an IVF on disk -type IVFWriter struct { - ioWriter io.Writer - count uint64 - seenKeyFrame bool - - isVP8, isAV1 bool - - // VP8 - currentFrame []byte - - // AV1 - av1Frame frame.AV1 -} - -// New builds a new IVF writer -func New(fileName string, opts ...Option) (*IVFWriter, error) { - f, err := os.Create(fileName) //nolint:gosec - if err != nil { - return nil, err - } - writer, err := NewWith(f, opts...) - if err != nil { - return nil, err - } - writer.ioWriter = f - return writer, nil -} - -// NewWith initialize a new IVF writer with an io.Writer output -func NewWith(out io.Writer, opts ...Option) (*IVFWriter, error) { - if out == nil { - return nil, errFileNotOpened - } - - writer := &IVFWriter{ - ioWriter: out, - seenKeyFrame: false, - } - - for _, o := range opts { - if err := o(writer); err != nil { - return nil, err - } - } - - if !writer.isAV1 && !writer.isVP8 { - writer.isVP8 = true - } - - if err := writer.writeHeader(); err != nil { - return nil, err - } - return writer, nil -} - -func (i *IVFWriter) writeHeader() error { - header := make([]byte, 32) - copy(header[0:], ivfFileHeaderSignature) // DKIF - binary.LittleEndian.PutUint16(header[4:], 0) // Version - binary.LittleEndian.PutUint16(header[6:], 32) // Header size - - // FOURCC - if i.isVP8 { - copy(header[8:], "VP80") - } else if i.isAV1 { - copy(header[8:], "AV01") - } - - binary.LittleEndian.PutUint16(header[12:], 640) // Width in pixels - binary.LittleEndian.PutUint16(header[14:], 480) // Height in pixels - binary.LittleEndian.PutUint32(header[16:], 30) // Framerate denominator - binary.LittleEndian.PutUint32(header[20:], 1) // Framerate numerator - binary.LittleEndian.PutUint32(header[24:], 900) // Frame count, will be updated on first Close() call - binary.LittleEndian.PutUint32(header[28:], 0) // Unused - - _, err := i.ioWriter.Write(header) - return err -} - -func (i *IVFWriter) writeFrame(frame []byte) error { - frameHeader := make([]byte, 12) - binary.LittleEndian.PutUint32(frameHeader[0:], uint32(len(frame))) // Frame length - binary.LittleEndian.PutUint64(frameHeader[4:], i.count) // PTS - i.count++ - - if _, err := i.ioWriter.Write(frameHeader); err != nil { - return err - } - _, err := i.ioWriter.Write(frame) - return err -} - -// WriteRTP adds a new packet and writes the appropriate headers for it -func (i *IVFWriter) WriteRTP(packet *rtp.Packet) error { - if i.ioWriter == nil { - return errFileNotOpened - } else if len(packet.Payload) == 0 { - return nil - } - - if i.isVP8 { - vp8Packet := codecs.VP8Packet{} - if _, err := vp8Packet.Unmarshal(packet.Payload); err != nil { - return err - } - - isKeyFrame := vp8Packet.Payload[0] & 0x01 - switch { - case !i.seenKeyFrame && isKeyFrame == 1: - return nil - case i.currentFrame == nil && vp8Packet.S != 1: - return nil - } - - i.seenKeyFrame = true - i.currentFrame = append(i.currentFrame, vp8Packet.Payload[0:]...) - - if !packet.Marker { - return nil - } else if len(i.currentFrame) == 0 { - return nil - } - - if err := i.writeFrame(i.currentFrame); err != nil { - return err - } - i.currentFrame = nil - } else if i.isAV1 { - av1Packet := &codecs.AV1Packet{} - if _, err := av1Packet.Unmarshal(packet.Payload); err != nil { - return err - } - - obus, err := i.av1Frame.ReadFrames(av1Packet) - if err != nil { - return err - } - - for j := range obus { - if err := i.writeFrame(obus[j]); err != nil { - return err - } - } - } - - return nil -} - -// Close stops the recording -func (i *IVFWriter) Close() error { - if i.ioWriter == nil { - // Returns no error as it may be convenient to call - // Close() multiple times - return nil - } - - defer func() { - i.ioWriter = nil - }() - - if ws, ok := i.ioWriter.(io.WriteSeeker); ok { - // Update the framecount - if _, err := ws.Seek(24, 0); err != nil { - return err - } - buff := make([]byte, 4) - binary.LittleEndian.PutUint32(buff, uint32(i.count)) - if _, err := ws.Write(buff); err != nil { - return err - } - } - - if closer, ok := i.ioWriter.(io.Closer); ok { - return closer.Close() - } - - return nil -} - -// An Option configures a SampleBuilder. -type Option func(i *IVFWriter) error - -// WithCodec configures if IVFWriter is writing AV1 or VP8 packets to disk -func WithCodec(mimeType string) Option { - return func(i *IVFWriter) error { - if i.isVP8 || i.isAV1 { - return errCodecAlreadySet - } - - switch mimeType { - case mimeTypeVP8: - i.isVP8 = true - case mimeTypeAV1: - i.isAV1 = true - default: - return errNoSuchCodec - } - - return nil - } -} diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/media.go b/vendor/github.com/pion/webrtc/v3/pkg/media/media.go deleted file mode 100644 index 2ed5573f..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/media.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package media provides media writer and filters -package media - -import ( - "time" - - "github.com/pion/rtp" -) - -// A Sample contains encoded media and timing information -type Sample struct { - Data []byte - Timestamp time.Time - Duration time.Duration - PacketTimestamp uint32 - PrevDroppedPackets uint16 -} - -// Writer defines an interface to handle -// the creation of media files -type Writer interface { - // Add the content of an RTP packet to the media - WriteRTP(packet *rtp.Packet) error - // Close the media - // Note: Close implementation must be idempotent - Close() error -} diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/oggreader/oggreader.go b/vendor/github.com/pion/webrtc/v3/pkg/media/oggreader/oggreader.go deleted file mode 100644 index 50d1a7cd..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/oggreader/oggreader.go +++ /dev/null @@ -1,218 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package oggreader implements the Ogg media container reader -package oggreader - -import ( - "encoding/binary" - "errors" - "io" -) - -const ( - pageHeaderTypeBeginningOfStream = 0x02 - pageHeaderSignature = "OggS" - - idPageSignature = "OpusHead" - - pageHeaderLen = 27 - idPagePayloadLength = 19 -) - -var ( - errNilStream = errors.New("stream is nil") - errBadIDPageSignature = errors.New("bad header signature") - errBadIDPageType = errors.New("wrong header, expected beginning of stream") - errBadIDPageLength = errors.New("payload for id page must be 19 bytes") - errBadIDPagePayloadSignature = errors.New("bad payload signature") - errShortPageHeader = errors.New("not enough data for payload header") - errChecksumMismatch = errors.New("expected and actual checksum do not match") -) - -// OggReader is used to read Ogg files and return page payloads -type OggReader struct { - stream io.Reader - bytesReadSuccesfully int64 - checksumTable *[256]uint32 - doChecksum bool -} - -// OggHeader is the metadata from the first two pages -// in the file (ID and Comment) -// -// https://tools.ietf.org/html/rfc7845.html#section-3 -type OggHeader struct { - ChannelMap uint8 - Channels uint8 - OutputGain uint16 - PreSkip uint16 - SampleRate uint32 - Version uint8 -} - -// OggPageHeader is the metadata for a Page -// Pages are the fundamental unit of multiplexing in an Ogg stream -// -// https://tools.ietf.org/html/rfc7845.html#section-1 -type OggPageHeader struct { - GranulePosition uint64 - - sig [4]byte - version uint8 - headerType uint8 - serial uint32 - index uint32 - segmentsCount uint8 -} - -// NewWith returns a new Ogg reader and Ogg header -// with an io.Reader input -func NewWith(in io.Reader) (*OggReader, *OggHeader, error) { - return newWith(in /* doChecksum */, true) -} - -func newWith(in io.Reader, doChecksum bool) (*OggReader, *OggHeader, error) { - if in == nil { - return nil, nil, errNilStream - } - - reader := &OggReader{ - stream: in, - checksumTable: generateChecksumTable(), - doChecksum: doChecksum, - } - - header, err := reader.readHeaders() - if err != nil { - return nil, nil, err - } - - return reader, header, nil -} - -func (o *OggReader) readHeaders() (*OggHeader, error) { - payload, pageHeader, err := o.ParseNextPage() - if err != nil { - return nil, err - } - - header := &OggHeader{} - if string(pageHeader.sig[:]) != pageHeaderSignature { - return nil, errBadIDPageSignature - } - - if pageHeader.headerType != pageHeaderTypeBeginningOfStream { - return nil, errBadIDPageType - } - - if len(payload) != idPagePayloadLength { - return nil, errBadIDPageLength - } - - if s := string(payload[:8]); s != idPageSignature { - return nil, errBadIDPagePayloadSignature - } - - header.Version = payload[8] - header.Channels = payload[9] - header.PreSkip = binary.LittleEndian.Uint16(payload[10:12]) - header.SampleRate = binary.LittleEndian.Uint32(payload[12:16]) - header.OutputGain = binary.LittleEndian.Uint16(payload[16:18]) - header.ChannelMap = payload[18] - - return header, nil -} - -// ParseNextPage reads from stream and returns Ogg page payload, header, -// and an error if there is incomplete page data. -func (o *OggReader) ParseNextPage() ([]byte, *OggPageHeader, error) { - h := make([]byte, pageHeaderLen) - - n, err := io.ReadFull(o.stream, h) - if err != nil { - return nil, nil, err - } else if n < len(h) { - return nil, nil, errShortPageHeader - } - - pageHeader := &OggPageHeader{ - sig: [4]byte{h[0], h[1], h[2], h[3]}, - } - - pageHeader.version = h[4] - pageHeader.headerType = h[5] - pageHeader.GranulePosition = binary.LittleEndian.Uint64(h[6 : 6+8]) - pageHeader.serial = binary.LittleEndian.Uint32(h[14 : 14+4]) - pageHeader.index = binary.LittleEndian.Uint32(h[18 : 18+4]) - pageHeader.segmentsCount = h[26] - - sizeBuffer := make([]byte, pageHeader.segmentsCount) - if _, err = io.ReadFull(o.stream, sizeBuffer); err != nil { - return nil, nil, err - } - - payloadSize := 0 - for _, s := range sizeBuffer { - payloadSize += int(s) - } - - payload := make([]byte, payloadSize) - if _, err = io.ReadFull(o.stream, payload); err != nil { - return nil, nil, err - } - - if o.doChecksum { - var checksum uint32 - updateChecksum := func(v byte) { - checksum = (checksum << 8) ^ o.checksumTable[byte(checksum>>24)^v] - } - - for index := range h { - // Don't include expected checksum in our generation - if index > 21 && index < 26 { - updateChecksum(0) - continue - } - - updateChecksum(h[index]) - } - for _, s := range sizeBuffer { - updateChecksum(s) - } - for index := range payload { - updateChecksum(payload[index]) - } - - if binary.LittleEndian.Uint32(h[22:22+4]) != checksum { - return nil, nil, errChecksumMismatch - } - } - - return payload, pageHeader, nil -} - -// ResetReader resets the internal stream of OggReader. This is useful -// for live streams, where the end of the file might be read without the -// data being finished. -func (o *OggReader) ResetReader(reset func(bytesRead int64) io.Reader) { - o.stream = reset(o.bytesReadSuccesfully) -} - -func generateChecksumTable() *[256]uint32 { - var table [256]uint32 - const poly = 0x04c11db7 - - for i := range table { - r := uint32(i) << 24 - for j := 0; j < 8; j++ { - if (r & 0x80000000) != 0 { - r = (r << 1) ^ poly - } else { - r <<= 1 - } - table[i] = (r & 0xffffffff) - } - } - return &table -} diff --git a/vendor/github.com/pion/webrtc/v3/pkg/media/oggwriter/oggwriter.go b/vendor/github.com/pion/webrtc/v3/pkg/media/oggwriter/oggwriter.go deleted file mode 100644 index 16952f15..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/media/oggwriter/oggwriter.go +++ /dev/null @@ -1,267 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package oggwriter implements OGG media container writer -package oggwriter - -import ( - "encoding/binary" - "errors" - "io" - "os" - - "github.com/pion/randutil" - "github.com/pion/rtp" - "github.com/pion/rtp/codecs" -) - -const ( - pageHeaderTypeContinuationOfStream = 0x00 - pageHeaderTypeBeginningOfStream = 0x02 - pageHeaderTypeEndOfStream = 0x04 - defaultPreSkip = 3840 // 3840 recommended in the RFC - idPageSignature = "OpusHead" - commentPageSignature = "OpusTags" - pageHeaderSignature = "OggS" -) - -var ( - errFileNotOpened = errors.New("file not opened") - errInvalidNilPacket = errors.New("invalid nil packet") -) - -// OggWriter is used to take RTP packets and write them to an OGG on disk -type OggWriter struct { - stream io.Writer - fd *os.File - sampleRate uint32 - channelCount uint16 - serial uint32 - pageIndex uint32 - checksumTable *[256]uint32 - previousGranulePosition uint64 - previousTimestamp uint32 - lastPayloadSize int -} - -// New builds a new OGG Opus writer -func New(fileName string, sampleRate uint32, channelCount uint16) (*OggWriter, error) { - f, err := os.Create(fileName) //nolint:gosec - if err != nil { - return nil, err - } - writer, err := NewWith(f, sampleRate, channelCount) - if err != nil { - return nil, f.Close() - } - writer.fd = f - return writer, nil -} - -// NewWith initialize a new OGG Opus writer with an io.Writer output -func NewWith(out io.Writer, sampleRate uint32, channelCount uint16) (*OggWriter, error) { - if out == nil { - return nil, errFileNotOpened - } - - writer := &OggWriter{ - stream: out, - sampleRate: sampleRate, - channelCount: channelCount, - serial: randutil.NewMathRandomGenerator().Uint32(), - checksumTable: generateChecksumTable(), - - // Timestamp and Granule MUST start from 1 - // Only headers can have 0 values - previousTimestamp: 1, - previousGranulePosition: 1, - } - if err := writer.writeHeaders(); err != nil { - return nil, err - } - - return writer, nil -} - -/* - ref: https://tools.ietf.org/html/rfc7845.html - https://git.xiph.org/?p=opus-tools.git;a=blob;f=src/opus_header.c#l219 - - Page 0 Pages 1 ... n Pages (n+1) ... - +------------+ +---+ +---+ ... +---+ +-----------+ +---------+ +-- - | | | | | | | | | | | | | - |+----------+| |+-----------------+| |+-------------------+ +----- - |||ID Header|| || Comment Header || ||Audio Data Packet 1| | ... - |+----------+| |+-----------------+| |+-------------------+ +----- - | | | | | | | | | | | | | - +------------+ +---+ +---+ ... +---+ +-----------+ +---------+ +-- - ^ ^ ^ - | | | - | | Mandatory Page Break - | | - | ID header is contained on a single page - | - 'Beginning Of Stream' - - Figure 1: Example Packet Organization for a Logical Ogg Opus Stream -*/ - -func (i *OggWriter) writeHeaders() error { - // ID Header - oggIDHeader := make([]byte, 19) - - copy(oggIDHeader[0:], idPageSignature) // Magic Signature 'OpusHead' - oggIDHeader[8] = 1 // Version - oggIDHeader[9] = uint8(i.channelCount) // Channel count - binary.LittleEndian.PutUint16(oggIDHeader[10:], defaultPreSkip) // pre-skip - binary.LittleEndian.PutUint32(oggIDHeader[12:], i.sampleRate) // original sample rate, any valid sample e.g 48000 - binary.LittleEndian.PutUint16(oggIDHeader[16:], 0) // output gain - oggIDHeader[18] = 0 // channel map 0 = one stream: mono or stereo - - // Reference: https://tools.ietf.org/html/rfc7845.html#page-6 - // RFC specifies that the ID Header page should have a granule position of 0 and a Header Type set to 2 (StartOfStream) - data := i.createPage(oggIDHeader, pageHeaderTypeBeginningOfStream, 0, i.pageIndex) - if err := i.writeToStream(data); err != nil { - return err - } - i.pageIndex++ - - // Comment Header - oggCommentHeader := make([]byte, 21) - copy(oggCommentHeader[0:], commentPageSignature) // Magic Signature 'OpusTags' - binary.LittleEndian.PutUint32(oggCommentHeader[8:], 5) // Vendor Length - copy(oggCommentHeader[12:], "pion") // Vendor name 'pion' - binary.LittleEndian.PutUint32(oggCommentHeader[17:], 0) // User Comment List Length - - // RFC specifies that the page where the CommentHeader completes should have a granule position of 0 - data = i.createPage(oggCommentHeader, pageHeaderTypeContinuationOfStream, 0, i.pageIndex) - if err := i.writeToStream(data); err != nil { - return err - } - i.pageIndex++ - - return nil -} - -const ( - pageHeaderSize = 27 -) - -func (i *OggWriter) createPage(payload []uint8, headerType uint8, granulePos uint64, pageIndex uint32) []byte { - i.lastPayloadSize = len(payload) - page := make([]byte, pageHeaderSize+1+i.lastPayloadSize) - - copy(page[0:], pageHeaderSignature) // page headers starts with 'OggS' - page[4] = 0 // Version - page[5] = headerType // 1 = continuation, 2 = beginning of stream, 4 = end of stream - binary.LittleEndian.PutUint64(page[6:], granulePos) // granule position - binary.LittleEndian.PutUint32(page[14:], i.serial) // Bitstream serial number - binary.LittleEndian.PutUint32(page[18:], pageIndex) // Page sequence number - page[26] = 1 // Number of segments in page, giving always 1 segment - page[27] = uint8(i.lastPayloadSize) // Segment Table inserting at 27th position since page header length is 27 - copy(page[28:], payload) // inserting at 28th since Segment Table(1) + header length(27) - - var checksum uint32 - for index := range page { - checksum = (checksum << 8) ^ i.checksumTable[byte(checksum>>24)^page[index]] - } - binary.LittleEndian.PutUint32(page[22:], checksum) // Checksum - generating for page data and inserting at 22th position into 32 bits - - return page -} - -// WriteRTP adds a new packet and writes the appropriate headers for it -func (i *OggWriter) WriteRTP(packet *rtp.Packet) error { - if packet == nil { - return errInvalidNilPacket - } - if len(packet.Payload) == 0 { - return nil - } - - opusPacket := codecs.OpusPacket{} - if _, err := opusPacket.Unmarshal(packet.Payload); err != nil { - // Only handle Opus packets - return err - } - - payload := opusPacket.Payload[0:] - - // Should be equivalent to sampleRate * duration - if i.previousTimestamp != 1 { - increment := packet.Timestamp - i.previousTimestamp - i.previousGranulePosition += uint64(increment) - } - i.previousTimestamp = packet.Timestamp - - data := i.createPage(payload, pageHeaderTypeContinuationOfStream, i.previousGranulePosition, i.pageIndex) - i.pageIndex++ - return i.writeToStream(data) -} - -// Close stops the recording -func (i *OggWriter) Close() error { - defer func() { - i.fd = nil - i.stream = nil - }() - - // Returns no error has it may be convenient to call - // Close() multiple times - if i.fd == nil { - // Close stream if we are operating on a stream - if closer, ok := i.stream.(io.Closer); ok { - return closer.Close() - } - return nil - } - - // Seek back one page, we need to update the header and generate new CRC - pageOffset, err := i.fd.Seek(-1*int64(i.lastPayloadSize+pageHeaderSize+1), 2) - if err != nil { - return err - } - - payload := make([]byte, i.lastPayloadSize) - if _, err := i.fd.ReadAt(payload, pageOffset+pageHeaderSize+1); err != nil { - return err - } - - data := i.createPage(payload, pageHeaderTypeEndOfStream, i.previousGranulePosition, i.pageIndex-1) - if err := i.writeToStream(data); err != nil { - return err - } - - // Update the last page if we are operating on files - // to mark it as the EOS - return i.fd.Close() -} - -// Wraps writing to the stream and maintains state -// so we can set values for EOS -func (i *OggWriter) writeToStream(p []byte) error { - if i.stream == nil { - return errFileNotOpened - } - - _, err := i.stream.Write(p) - return err -} - -func generateChecksumTable() *[256]uint32 { - var table [256]uint32 - const poly = 0x04c11db7 - - for i := range table { - r := uint32(i) << 24 - for j := 0; j < 8; j++ { - if (r & 0x80000000) != 0 { - r = (r << 1) ^ poly - } else { - r <<= 1 - } - table[i] = (r & 0xffffffff) - } - } - return &table -} diff --git a/vendor/github.com/pion/webrtc/v3/pkg/rtcerr/errors.go b/vendor/github.com/pion/webrtc/v3/pkg/rtcerr/errors.go deleted file mode 100644 index 36205c7d..00000000 --- a/vendor/github.com/pion/webrtc/v3/pkg/rtcerr/errors.go +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package rtcerr implements the error wrappers defined throughout the -// WebRTC 1.0 specifications. -package rtcerr - -import ( - "fmt" -) - -// UnknownError indicates the operation failed for an unknown transient reason. -type UnknownError struct { - Err error -} - -func (e *UnknownError) Error() string { - return fmt.Sprintf("UnknownError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *UnknownError) Unwrap() error { - return e.Err -} - -// InvalidStateError indicates the object is in an invalid state. -type InvalidStateError struct { - Err error -} - -func (e *InvalidStateError) Error() string { - return fmt.Sprintf("InvalidStateError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *InvalidStateError) Unwrap() error { - return e.Err -} - -// InvalidAccessError indicates the object does not support the operation or -// argument. -type InvalidAccessError struct { - Err error -} - -func (e *InvalidAccessError) Error() string { - return fmt.Sprintf("InvalidAccessError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *InvalidAccessError) Unwrap() error { - return e.Err -} - -// NotSupportedError indicates the operation is not supported. -type NotSupportedError struct { - Err error -} - -func (e *NotSupportedError) Error() string { - return fmt.Sprintf("NotSupportedError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *NotSupportedError) Unwrap() error { - return e.Err -} - -// InvalidModificationError indicates the object cannot be modified in this way. -type InvalidModificationError struct { - Err error -} - -func (e *InvalidModificationError) Error() string { - return fmt.Sprintf("InvalidModificationError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *InvalidModificationError) Unwrap() error { - return e.Err -} - -// SyntaxError indicates the string did not match the expected pattern. -type SyntaxError struct { - Err error -} - -func (e *SyntaxError) Error() string { - return fmt.Sprintf("SyntaxError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *SyntaxError) Unwrap() error { - return e.Err -} - -// TypeError indicates an error when a value is not of the expected type. -type TypeError struct { - Err error -} - -func (e *TypeError) Error() string { - return fmt.Sprintf("TypeError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *TypeError) Unwrap() error { - return e.Err -} - -// OperationError indicates the operation failed for an operation-specific -// reason. -type OperationError struct { - Err error -} - -func (e *OperationError) Error() string { - return fmt.Sprintf("OperationError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *OperationError) Unwrap() error { - return e.Err -} - -// NotReadableError indicates the input/output read operation failed. -type NotReadableError struct { - Err error -} - -func (e *NotReadableError) Error() string { - return fmt.Sprintf("NotReadableError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *NotReadableError) Unwrap() error { - return e.Err -} - -// RangeError indicates an error when a value is not in the set or range -// of allowed values. -type RangeError struct { - Err error -} - -func (e *RangeError) Error() string { - return fmt.Sprintf("RangeError: %v", e.Err) -} - -// Unwrap returns the result of calling the Unwrap method on err, if err's type contains -// an Unwrap method returning error. Otherwise, Unwrap returns nil. -func (e *RangeError) Unwrap() error { - return e.Err -} diff --git a/vendor/github.com/pion/webrtc/v3/renovate.json b/vendor/github.com/pion/webrtc/v3/renovate.json deleted file mode 100644 index f1bb98c6..00000000 --- a/vendor/github.com/pion/webrtc/v3/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "github>pion/renovate-config" - ] -} diff --git a/vendor/github.com/pion/webrtc/v3/rtcpfeedback.go b/vendor/github.com/pion/webrtc/v3/rtcpfeedback.go deleted file mode 100644 index ab6f555a..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtcpfeedback.go +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -const ( - // TypeRTCPFBTransportCC .. - TypeRTCPFBTransportCC = "transport-cc" - - // TypeRTCPFBGoogREMB .. - TypeRTCPFBGoogREMB = "goog-remb" - - // TypeRTCPFBACK .. - TypeRTCPFBACK = "ack" - - // TypeRTCPFBCCM .. - TypeRTCPFBCCM = "ccm" - - // TypeRTCPFBNACK .. - TypeRTCPFBNACK = "nack" -) - -// RTCPFeedback signals the connection to use additional RTCP packet types. -// https://draft.ortc.org/#dom-rtcrtcpfeedback -type RTCPFeedback struct { - // Type is the type of feedback. - // see: https://draft.ortc.org/#dom-rtcrtcpfeedback - // valid: ack, ccm, nack, goog-remb, transport-cc - Type string - - // The parameter value depends on the type. - // For example, type="nack" parameter="pli" will send Picture Loss Indicator packets. - Parameter string -} diff --git a/vendor/github.com/pion/webrtc/v3/rtcpmuxpolicy.go b/vendor/github.com/pion/webrtc/v3/rtcpmuxpolicy.go deleted file mode 100644 index bd68ab56..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtcpmuxpolicy.go +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "encoding/json" -) - -// RTCPMuxPolicy affects what ICE candidates are gathered to support -// non-multiplexed RTCP. -type RTCPMuxPolicy int - -const ( - // RTCPMuxPolicyNegotiate indicates to gather ICE candidates for both - // RTP and RTCP candidates. If the remote-endpoint is capable of - // multiplexing RTCP, multiplex RTCP on the RTP candidates. If it is not, - // use both the RTP and RTCP candidates separately. - RTCPMuxPolicyNegotiate RTCPMuxPolicy = iota + 1 - - // RTCPMuxPolicyRequire indicates to gather ICE candidates only for - // RTP and multiplex RTCP on the RTP candidates. If the remote endpoint is - // not capable of rtcp-mux, session negotiation will fail. - RTCPMuxPolicyRequire -) - -// This is done this way because of a linter. -const ( - rtcpMuxPolicyNegotiateStr = "negotiate" - rtcpMuxPolicyRequireStr = "require" -) - -func newRTCPMuxPolicy(raw string) RTCPMuxPolicy { - switch raw { - case rtcpMuxPolicyNegotiateStr: - return RTCPMuxPolicyNegotiate - case rtcpMuxPolicyRequireStr: - return RTCPMuxPolicyRequire - default: - return RTCPMuxPolicy(Unknown) - } -} - -func (t RTCPMuxPolicy) String() string { - switch t { - case RTCPMuxPolicyNegotiate: - return rtcpMuxPolicyNegotiateStr - case RTCPMuxPolicyRequire: - return rtcpMuxPolicyRequireStr - default: - return ErrUnknownType.Error() - } -} - -// UnmarshalJSON parses the JSON-encoded data and stores the result -func (t *RTCPMuxPolicy) UnmarshalJSON(b []byte) error { - var val string - if err := json.Unmarshal(b, &val); err != nil { - return err - } - - *t = newRTCPMuxPolicy(val) - return nil -} - -// MarshalJSON returns the JSON encoding -func (t RTCPMuxPolicy) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpcapabilities.go b/vendor/github.com/pion/webrtc/v3/rtpcapabilities.go deleted file mode 100644 index 3ac52e45..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpcapabilities.go +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPCapabilities represents the capabilities of a transceiver -// -// https://w3c.github.io/webrtc-pc/#rtcrtpcapabilities -type RTPCapabilities struct { - Codecs []RTPCodecCapability - HeaderExtensions []RTPHeaderExtensionCapability -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpcodec.go b/vendor/github.com/pion/webrtc/v3/rtpcodec.go deleted file mode 100644 index 5692d5f5..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpcodec.go +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "strings" - - "github.com/pion/webrtc/v3/internal/fmtp" -) - -// RTPCodecType determines the type of a codec -type RTPCodecType int - -const ( - - // RTPCodecTypeAudio indicates this is an audio codec - RTPCodecTypeAudio RTPCodecType = iota + 1 - - // RTPCodecTypeVideo indicates this is a video codec - RTPCodecTypeVideo -) - -func (t RTPCodecType) String() string { - switch t { - case RTPCodecTypeAudio: - return "audio" - case RTPCodecTypeVideo: - return "video" //nolint: goconst - default: - return ErrUnknownType.Error() - } -} - -// NewRTPCodecType creates a RTPCodecType from a string -func NewRTPCodecType(r string) RTPCodecType { - switch { - case strings.EqualFold(r, RTPCodecTypeAudio.String()): - return RTPCodecTypeAudio - case strings.EqualFold(r, RTPCodecTypeVideo.String()): - return RTPCodecTypeVideo - default: - return RTPCodecType(0) - } -} - -// RTPCodecCapability provides information about codec capabilities. -// -// https://w3c.github.io/webrtc-pc/#dictionary-rtcrtpcodeccapability-members -type RTPCodecCapability struct { - MimeType string - ClockRate uint32 - Channels uint16 - SDPFmtpLine string - RTCPFeedback []RTCPFeedback -} - -// RTPHeaderExtensionCapability is used to define a RFC5285 RTP header extension supported by the codec. -// -// https://w3c.github.io/webrtc-pc/#dom-rtcrtpcapabilities-headerextensions -type RTPHeaderExtensionCapability struct { - URI string -} - -// RTPHeaderExtensionParameter represents a negotiated RFC5285 RTP header extension. -// -// https://w3c.github.io/webrtc-pc/#dictionary-rtcrtpheaderextensionparameters-members -type RTPHeaderExtensionParameter struct { - URI string - ID int -} - -// RTPCodecParameters is a sequence containing the media codecs that an RtpSender -// will choose from, as well as entries for RTX, RED and FEC mechanisms. This also -// includes the PayloadType that has been negotiated -// -// https://w3c.github.io/webrtc-pc/#rtcrtpcodecparameters -type RTPCodecParameters struct { - RTPCodecCapability - PayloadType PayloadType - - statsID string -} - -// RTPParameters is a list of negotiated codecs and header extensions -// -// https://w3c.github.io/webrtc-pc/#dictionary-rtcrtpparameters-members -type RTPParameters struct { - HeaderExtensions []RTPHeaderExtensionParameter - Codecs []RTPCodecParameters -} - -type codecMatchType int - -const ( - codecMatchNone codecMatchType = 0 - codecMatchPartial codecMatchType = 1 - codecMatchExact codecMatchType = 2 -) - -// Do a fuzzy find for a codec in the list of codecs -// Used for lookup up a codec in an existing list to find a match -// Returns codecMatchExact, codecMatchPartial, or codecMatchNone -func codecParametersFuzzySearch(needle RTPCodecParameters, haystack []RTPCodecParameters) (RTPCodecParameters, codecMatchType) { - needleFmtp := fmtp.Parse(needle.RTPCodecCapability.MimeType, needle.RTPCodecCapability.SDPFmtpLine) - - // First attempt to match on MimeType + SDPFmtpLine - for _, c := range haystack { - cfmtp := fmtp.Parse(c.RTPCodecCapability.MimeType, c.RTPCodecCapability.SDPFmtpLine) - if needleFmtp.Match(cfmtp) { - return c, codecMatchExact - } - } - - // Fallback to just MimeType - for _, c := range haystack { - if strings.EqualFold(c.RTPCodecCapability.MimeType, needle.RTPCodecCapability.MimeType) { - return c, codecMatchPartial - } - } - - return RTPCodecParameters{}, codecMatchNone -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpcodingparameters.go b/vendor/github.com/pion/webrtc/v3/rtpcodingparameters.go deleted file mode 100644 index f03d8c35..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpcodingparameters.go +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPRtxParameters dictionary contains information relating to retransmission (RTX) settings. -// https://draft.ortc.org/#dom-rtcrtprtxparameters -type RTPRtxParameters struct { - SSRC SSRC `json:"ssrc"` -} - -// RTPCodingParameters provides information relating to both encoding and decoding. -// This is a subset of the RFC since Pion WebRTC doesn't implement encoding/decoding itself -// http://draft.ortc.org/#dom-rtcrtpcodingparameters -type RTPCodingParameters struct { - RID string `json:"rid"` - SSRC SSRC `json:"ssrc"` - PayloadType PayloadType `json:"payloadType"` - RTX RTPRtxParameters `json:"rtx"` -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpdecodingparameters.go b/vendor/github.com/pion/webrtc/v3/rtpdecodingparameters.go deleted file mode 100644 index 0c45f896..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpdecodingparameters.go +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPDecodingParameters provides information relating to both encoding and decoding. -// This is a subset of the RFC since Pion WebRTC doesn't implement decoding itself -// http://draft.ortc.org/#dom-rtcrtpdecodingparameters -type RTPDecodingParameters struct { - RTPCodingParameters -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpencodingparameters.go b/vendor/github.com/pion/webrtc/v3/rtpencodingparameters.go deleted file mode 100644 index ffd4a8d7..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpencodingparameters.go +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPEncodingParameters provides information relating to both encoding and decoding. -// This is a subset of the RFC since Pion WebRTC doesn't implement encoding itself -// http://draft.ortc.org/#dom-rtcrtpencodingparameters -type RTPEncodingParameters struct { - RTPCodingParameters -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiveparameters.go b/vendor/github.com/pion/webrtc/v3/rtpreceiveparameters.go deleted file mode 100644 index 26a66761..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpreceiveparameters.go +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPReceiveParameters contains the RTP stack settings used by receivers -type RTPReceiveParameters struct { - Encodings []RTPDecodingParameters -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiver.go b/vendor/github.com/pion/webrtc/v3/rtpreceiver.go deleted file mode 100644 index dac154be..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpreceiver.go +++ /dev/null @@ -1,439 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "fmt" - "io" - "sync" - "time" - - "github.com/pion/interceptor" - "github.com/pion/rtcp" - "github.com/pion/srtp/v2" - "github.com/pion/webrtc/v3/internal/util" -) - -// trackStreams maintains a mapping of RTP/RTCP streams to a specific track -// a RTPReceiver may contain multiple streams if we are dealing with Simulcast -type trackStreams struct { - track *TrackRemote - - streamInfo, repairStreamInfo *interceptor.StreamInfo - - rtpReadStream *srtp.ReadStreamSRTP - rtpInterceptor interceptor.RTPReader - - rtcpReadStream *srtp.ReadStreamSRTCP - rtcpInterceptor interceptor.RTCPReader - - repairReadStream *srtp.ReadStreamSRTP - repairInterceptor interceptor.RTPReader - - repairRtcpReadStream *srtp.ReadStreamSRTCP - repairRtcpInterceptor interceptor.RTCPReader -} - -// RTPReceiver allows an application to inspect the receipt of a TrackRemote -type RTPReceiver struct { - kind RTPCodecType - transport *DTLSTransport - - tracks []trackStreams - - closed, received chan interface{} - mu sync.RWMutex - - tr *RTPTransceiver - - // A reference to the associated api object - api *API -} - -// NewRTPReceiver constructs a new RTPReceiver -func (api *API) NewRTPReceiver(kind RTPCodecType, transport *DTLSTransport) (*RTPReceiver, error) { - if transport == nil { - return nil, errRTPReceiverDTLSTransportNil - } - - r := &RTPReceiver{ - kind: kind, - transport: transport, - api: api, - closed: make(chan interface{}), - received: make(chan interface{}), - tracks: []trackStreams{}, - } - - return r, nil -} - -func (r *RTPReceiver) setRTPTransceiver(tr *RTPTransceiver) { - r.mu.Lock() - defer r.mu.Unlock() - r.tr = tr -} - -// Transport returns the currently-configured *DTLSTransport or nil -// if one has not yet been configured -func (r *RTPReceiver) Transport() *DTLSTransport { - r.mu.RLock() - defer r.mu.RUnlock() - return r.transport -} - -func (r *RTPReceiver) getParameters() RTPParameters { - parameters := r.api.mediaEngine.getRTPParametersByKind(r.kind, []RTPTransceiverDirection{RTPTransceiverDirectionRecvonly}) - if r.tr != nil { - parameters.Codecs = r.tr.getCodecs() - } - return parameters -} - -// GetParameters describes the current configuration for the encoding and -// transmission of media on the receiver's track. -func (r *RTPReceiver) GetParameters() RTPParameters { - r.mu.RLock() - defer r.mu.RUnlock() - return r.getParameters() -} - -// Track returns the RtpTransceiver TrackRemote -func (r *RTPReceiver) Track() *TrackRemote { - r.mu.RLock() - defer r.mu.RUnlock() - - if len(r.tracks) != 1 { - return nil - } - return r.tracks[0].track -} - -// Tracks returns the RtpTransceiver tracks -// A RTPReceiver to support Simulcast may now have multiple tracks -func (r *RTPReceiver) Tracks() []*TrackRemote { - r.mu.RLock() - defer r.mu.RUnlock() - - var tracks []*TrackRemote - for i := range r.tracks { - tracks = append(tracks, r.tracks[i].track) - } - return tracks -} - -// configureReceive initialize the track -func (r *RTPReceiver) configureReceive(parameters RTPReceiveParameters) { - r.mu.Lock() - defer r.mu.Unlock() - - for i := range parameters.Encodings { - t := trackStreams{ - track: newTrackRemote( - r.kind, - parameters.Encodings[i].SSRC, - parameters.Encodings[i].RID, - r, - ), - } - - r.tracks = append(r.tracks, t) - } -} - -// startReceive starts all the transports -func (r *RTPReceiver) startReceive(parameters RTPReceiveParameters) error { - r.mu.Lock() - defer r.mu.Unlock() - select { - case <-r.received: - return errRTPReceiverReceiveAlreadyCalled - default: - } - defer close(r.received) - - globalParams := r.getParameters() - codec := RTPCodecCapability{} - if len(globalParams.Codecs) != 0 { - codec = globalParams.Codecs[0].RTPCodecCapability - } - - for i := range parameters.Encodings { - if parameters.Encodings[i].RID != "" { - // RID based tracks will be set up in receiveForRid - continue - } - - var t *trackStreams - for idx, ts := range r.tracks { - if ts.track != nil && parameters.Encodings[i].SSRC != 0 && ts.track.SSRC() == parameters.Encodings[i].SSRC { - t = &r.tracks[idx] - break - } - } - if t == nil { - return fmt.Errorf("%w: %d", errRTPReceiverWithSSRCTrackStreamNotFound, parameters.Encodings[i].SSRC) - } - - if parameters.Encodings[i].SSRC != 0 { - t.streamInfo = createStreamInfo("", parameters.Encodings[i].SSRC, 0, codec, globalParams.HeaderExtensions) - var err error - if t.rtpReadStream, t.rtpInterceptor, t.rtcpReadStream, t.rtcpInterceptor, err = r.transport.streamsForSSRC(parameters.Encodings[i].SSRC, *t.streamInfo); err != nil { - return err - } - } - - if rtxSsrc := parameters.Encodings[i].RTX.SSRC; rtxSsrc != 0 { - streamInfo := createStreamInfo("", rtxSsrc, 0, codec, globalParams.HeaderExtensions) - rtpReadStream, rtpInterceptor, rtcpReadStream, rtcpInterceptor, err := r.transport.streamsForSSRC(rtxSsrc, *streamInfo) - if err != nil { - return err - } - - if err = r.receiveForRtx(rtxSsrc, "", streamInfo, rtpReadStream, rtpInterceptor, rtcpReadStream, rtcpInterceptor); err != nil { - return err - } - } - } - - return nil -} - -// Receive initialize the track and starts all the transports -func (r *RTPReceiver) Receive(parameters RTPReceiveParameters) error { - r.configureReceive(parameters) - return r.startReceive(parameters) -} - -// Read reads incoming RTCP for this RTPReceiver -func (r *RTPReceiver) Read(b []byte) (n int, a interceptor.Attributes, err error) { - select { - case <-r.received: - return r.tracks[0].rtcpInterceptor.Read(b, a) - case <-r.closed: - return 0, nil, io.ErrClosedPipe - } -} - -// ReadSimulcast reads incoming RTCP for this RTPReceiver for given rid -func (r *RTPReceiver) ReadSimulcast(b []byte, rid string) (n int, a interceptor.Attributes, err error) { - select { - case <-r.received: - for _, t := range r.tracks { - if t.track != nil && t.track.rid == rid { - return t.rtcpInterceptor.Read(b, a) - } - } - return 0, nil, fmt.Errorf("%w: %s", errRTPReceiverForRIDTrackStreamNotFound, rid) - case <-r.closed: - return 0, nil, io.ErrClosedPipe - } -} - -// ReadRTCP is a convenience method that wraps Read and unmarshal for you. -// It also runs any configured interceptors. -func (r *RTPReceiver) ReadRTCP() ([]rtcp.Packet, interceptor.Attributes, error) { - b := make([]byte, r.api.settingEngine.getReceiveMTU()) - i, attributes, err := r.Read(b) - if err != nil { - return nil, nil, err - } - - pkts, err := rtcp.Unmarshal(b[:i]) - if err != nil { - return nil, nil, err - } - - return pkts, attributes, nil -} - -// ReadSimulcastRTCP is a convenience method that wraps ReadSimulcast and unmarshal for you -func (r *RTPReceiver) ReadSimulcastRTCP(rid string) ([]rtcp.Packet, interceptor.Attributes, error) { - b := make([]byte, r.api.settingEngine.getReceiveMTU()) - i, attributes, err := r.ReadSimulcast(b, rid) - if err != nil { - return nil, nil, err - } - - pkts, err := rtcp.Unmarshal(b[:i]) - return pkts, attributes, err -} - -func (r *RTPReceiver) haveReceived() bool { - select { - case <-r.received: - return true - default: - return false - } -} - -// Stop irreversibly stops the RTPReceiver -func (r *RTPReceiver) Stop() error { - r.mu.Lock() - defer r.mu.Unlock() - var err error - - select { - case <-r.closed: - return err - default: - } - - select { - case <-r.received: - for i := range r.tracks { - errs := []error{} - - if r.tracks[i].rtcpReadStream != nil { - errs = append(errs, r.tracks[i].rtcpReadStream.Close()) - } - - if r.tracks[i].rtpReadStream != nil { - errs = append(errs, r.tracks[i].rtpReadStream.Close()) - } - - if r.tracks[i].repairReadStream != nil { - errs = append(errs, r.tracks[i].repairReadStream.Close()) - } - - if r.tracks[i].repairRtcpReadStream != nil { - errs = append(errs, r.tracks[i].repairRtcpReadStream.Close()) - } - - if r.tracks[i].streamInfo != nil { - r.api.interceptor.UnbindRemoteStream(r.tracks[i].streamInfo) - } - - if r.tracks[i].repairStreamInfo != nil { - r.api.interceptor.UnbindRemoteStream(r.tracks[i].repairStreamInfo) - } - - err = util.FlattenErrs(errs) - } - default: - } - - close(r.closed) - return err -} - -func (r *RTPReceiver) streamsForTrack(t *TrackRemote) *trackStreams { - for i := range r.tracks { - if r.tracks[i].track == t { - return &r.tracks[i] - } - } - return nil -} - -// readRTP should only be called by a track, this only exists so we can keep state in one place -func (r *RTPReceiver) readRTP(b []byte, reader *TrackRemote) (n int, a interceptor.Attributes, err error) { - <-r.received - if t := r.streamsForTrack(reader); t != nil { - return t.rtpInterceptor.Read(b, a) - } - - return 0, nil, fmt.Errorf("%w: %d", errRTPReceiverWithSSRCTrackStreamNotFound, reader.SSRC()) -} - -// receiveForRid is the sibling of Receive expect for RIDs instead of SSRCs -// It populates all the internal state for the given RID -func (r *RTPReceiver) receiveForRid(rid string, params RTPParameters, streamInfo *interceptor.StreamInfo, rtpReadStream *srtp.ReadStreamSRTP, rtpInterceptor interceptor.RTPReader, rtcpReadStream *srtp.ReadStreamSRTCP, rtcpInterceptor interceptor.RTCPReader) (*TrackRemote, error) { - r.mu.Lock() - defer r.mu.Unlock() - - for i := range r.tracks { - if r.tracks[i].track.RID() == rid { - r.tracks[i].track.mu.Lock() - r.tracks[i].track.kind = r.kind - r.tracks[i].track.codec = params.Codecs[0] - r.tracks[i].track.params = params - r.tracks[i].track.ssrc = SSRC(streamInfo.SSRC) - r.tracks[i].track.mu.Unlock() - - r.tracks[i].streamInfo = streamInfo - r.tracks[i].rtpReadStream = rtpReadStream - r.tracks[i].rtpInterceptor = rtpInterceptor - r.tracks[i].rtcpReadStream = rtcpReadStream - r.tracks[i].rtcpInterceptor = rtcpInterceptor - - return r.tracks[i].track, nil - } - } - - return nil, fmt.Errorf("%w: %s", errRTPReceiverForRIDTrackStreamNotFound, rid) -} - -// receiveForRtx starts a routine that processes the repair stream -// These packets aren't exposed to the user yet, but we need to process them for -// TWCC -func (r *RTPReceiver) receiveForRtx(ssrc SSRC, rsid string, streamInfo *interceptor.StreamInfo, rtpReadStream *srtp.ReadStreamSRTP, rtpInterceptor interceptor.RTPReader, rtcpReadStream *srtp.ReadStreamSRTCP, rtcpInterceptor interceptor.RTCPReader) error { - var track *trackStreams - if ssrc != 0 && len(r.tracks) == 1 { - track = &r.tracks[0] - } else { - for i := range r.tracks { - if r.tracks[i].track.RID() == rsid { - track = &r.tracks[i] - } - } - } - - if track == nil { - return fmt.Errorf("%w: ssrc(%d) rsid(%s)", errRTPReceiverForRIDTrackStreamNotFound, ssrc, rsid) - } - - track.repairStreamInfo = streamInfo - track.repairReadStream = rtpReadStream - track.repairInterceptor = rtpInterceptor - track.repairRtcpReadStream = rtcpReadStream - track.repairRtcpInterceptor = rtcpInterceptor - - go func() { - b := make([]byte, r.api.settingEngine.getReceiveMTU()) - for { - if _, _, readErr := track.repairInterceptor.Read(b, nil); readErr != nil { - return - } - } - }() - return nil -} - -// SetReadDeadline sets the max amount of time the RTCP stream will block before returning. 0 is forever. -func (r *RTPReceiver) SetReadDeadline(t time.Time) error { - r.mu.RLock() - defer r.mu.RUnlock() - - return r.tracks[0].rtcpReadStream.SetReadDeadline(t) -} - -// SetReadDeadlineSimulcast sets the max amount of time the RTCP stream for a given rid will block before returning. 0 is forever. -func (r *RTPReceiver) SetReadDeadlineSimulcast(deadline time.Time, rid string) error { - r.mu.RLock() - defer r.mu.RUnlock() - - for _, t := range r.tracks { - if t.track != nil && t.track.rid == rid { - return t.rtcpReadStream.SetReadDeadline(deadline) - } - } - return fmt.Errorf("%w: %s", errRTPReceiverForRIDTrackStreamNotFound, rid) -} - -// setRTPReadDeadline sets the max amount of time the RTP stream will block before returning. 0 is forever. -// This should be fired by calling SetReadDeadline on the TrackRemote -func (r *RTPReceiver) setRTPReadDeadline(deadline time.Time, reader *TrackRemote) error { - r.mu.RLock() - defer r.mu.RUnlock() - - if t := r.streamsForTrack(reader); t != nil { - return t.rtpReadStream.SetReadDeadline(deadline) - } - return fmt.Errorf("%w: %d", errRTPReceiverWithSSRCTrackStreamNotFound, reader.SSRC()) -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiver_go.go b/vendor/github.com/pion/webrtc/v3/rtpreceiver_go.go deleted file mode 100644 index 4d150f0f..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpreceiver_go.go +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import "github.com/pion/interceptor" - -// SetRTPParameters applies provided RTPParameters the RTPReceiver's tracks. -// -// This method is part of the ORTC API. It is not -// meant to be used together with the basic WebRTC API. -// -// The amount of provided codecs must match the number of tracks on the receiver. -func (r *RTPReceiver) SetRTPParameters(params RTPParameters) { - headerExtensions := make([]interceptor.RTPHeaderExtension, 0, len(params.HeaderExtensions)) - for _, h := range params.HeaderExtensions { - headerExtensions = append(headerExtensions, interceptor.RTPHeaderExtension{ID: h.ID, URI: h.URI}) - } - - r.mu.Lock() - defer r.mu.Unlock() - - for ndx, codec := range params.Codecs { - currentTrack := r.tracks[ndx].track - - r.tracks[ndx].streamInfo.RTPHeaderExtensions = headerExtensions - - currentTrack.mu.Lock() - currentTrack.codec = codec - currentTrack.params = params - currentTrack.mu.Unlock() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpreceiver_js.go b/vendor/github.com/pion/webrtc/v3/rtpreceiver_js.go deleted file mode 100644 index 44cef72d..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpreceiver_js.go +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import "syscall/js" - -// RTPReceiver allows an application to inspect the receipt of a TrackRemote -type RTPReceiver struct { - // Pointer to the underlying JavaScript RTCRTPReceiver object. - underlying js.Value -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpsender.go b/vendor/github.com/pion/webrtc/v3/rtpsender.go deleted file mode 100644 index 49ae4e82..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpsender.go +++ /dev/null @@ -1,454 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "fmt" - "io" - "sync" - "time" - - "github.com/pion/interceptor" - "github.com/pion/randutil" - "github.com/pion/rtcp" - "github.com/pion/rtp" - "github.com/pion/webrtc/v3/internal/util" -) - -type trackEncoding struct { - track TrackLocal - - srtpStream *srtpWriterFuture - - rtcpInterceptor interceptor.RTCPReader - streamInfo interceptor.StreamInfo - - context TrackLocalContext - - ssrc SSRC -} - -// RTPSender allows an application to control how a given Track is encoded and transmitted to a remote peer -type RTPSender struct { - trackEncodings []*trackEncoding - - transport *DTLSTransport - - payloadType PayloadType - kind RTPCodecType - - // nolint:godox - // TODO(sgotti) remove this when in future we'll avoid replacing - // a transceiver sender since we can just check the - // transceiver negotiation status - negotiated bool - - // A reference to the associated api object - api *API - id string - - rtpTransceiver *RTPTransceiver - - mu sync.RWMutex - sendCalled, stopCalled chan struct{} -} - -// NewRTPSender constructs a new RTPSender -func (api *API) NewRTPSender(track TrackLocal, transport *DTLSTransport) (*RTPSender, error) { - if track == nil { - return nil, errRTPSenderTrackNil - } else if transport == nil { - return nil, errRTPSenderDTLSTransportNil - } - - id, err := randutil.GenerateCryptoRandomString(32, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - if err != nil { - return nil, err - } - - r := &RTPSender{ - transport: transport, - api: api, - sendCalled: make(chan struct{}), - stopCalled: make(chan struct{}), - id: id, - kind: track.Kind(), - } - - r.addEncoding(track) - - return r, nil -} - -func (r *RTPSender) isNegotiated() bool { - r.mu.RLock() - defer r.mu.RUnlock() - return r.negotiated -} - -func (r *RTPSender) setNegotiated() { - r.mu.Lock() - defer r.mu.Unlock() - r.negotiated = true -} - -func (r *RTPSender) setRTPTransceiver(rtpTransceiver *RTPTransceiver) { - r.mu.Lock() - defer r.mu.Unlock() - r.rtpTransceiver = rtpTransceiver -} - -// Transport returns the currently-configured *DTLSTransport or nil -// if one has not yet been configured -func (r *RTPSender) Transport() *DTLSTransport { - r.mu.RLock() - defer r.mu.RUnlock() - return r.transport -} - -func (r *RTPSender) getParameters() RTPSendParameters { - var encodings []RTPEncodingParameters - for _, trackEncoding := range r.trackEncodings { - var rid string - if trackEncoding.track != nil { - rid = trackEncoding.track.RID() - } - encodings = append(encodings, RTPEncodingParameters{ - RTPCodingParameters: RTPCodingParameters{ - RID: rid, - SSRC: trackEncoding.ssrc, - PayloadType: r.payloadType, - }, - }) - } - sendParameters := RTPSendParameters{ - RTPParameters: r.api.mediaEngine.getRTPParametersByKind( - r.kind, - []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}, - ), - Encodings: encodings, - } - if r.rtpTransceiver != nil { - sendParameters.Codecs = r.rtpTransceiver.getCodecs() - } else { - sendParameters.Codecs = r.api.mediaEngine.getCodecsByKind(r.kind) - } - return sendParameters -} - -// GetParameters describes the current configuration for the encoding and -// transmission of media on the sender's track. -func (r *RTPSender) GetParameters() RTPSendParameters { - r.mu.RLock() - defer r.mu.RUnlock() - return r.getParameters() -} - -// AddEncoding adds an encoding to RTPSender. Used by simulcast senders. -func (r *RTPSender) AddEncoding(track TrackLocal) error { - r.mu.Lock() - defer r.mu.Unlock() - - if track == nil { - return errRTPSenderTrackNil - } - - if track.RID() == "" { - return errRTPSenderRidNil - } - - if r.hasStopped() { - return errRTPSenderStopped - } - - if r.hasSent() { - return errRTPSenderSendAlreadyCalled - } - - var refTrack TrackLocal - if len(r.trackEncodings) != 0 { - refTrack = r.trackEncodings[0].track - } - if refTrack == nil || refTrack.RID() == "" { - return errRTPSenderNoBaseEncoding - } - - if refTrack.ID() != track.ID() || refTrack.StreamID() != track.StreamID() || refTrack.Kind() != track.Kind() { - return errRTPSenderBaseEncodingMismatch - } - - for _, encoding := range r.trackEncodings { - if encoding.track == nil { - continue - } - - if encoding.track.RID() == track.RID() { - return errRTPSenderRIDCollision - } - } - - r.addEncoding(track) - return nil -} - -func (r *RTPSender) addEncoding(track TrackLocal) { - ssrc := SSRC(randutil.NewMathRandomGenerator().Uint32()) - trackEncoding := &trackEncoding{ - track: track, - srtpStream: &srtpWriterFuture{ssrc: ssrc}, - ssrc: ssrc, - } - trackEncoding.srtpStream.rtpSender = r - trackEncoding.rtcpInterceptor = r.api.interceptor.BindRTCPReader( - interceptor.RTPReaderFunc(func(in []byte, a interceptor.Attributes) (n int, attributes interceptor.Attributes, err error) { - n, err = trackEncoding.srtpStream.Read(in) - return n, a, err - }), - ) - - r.trackEncodings = append(r.trackEncodings, trackEncoding) -} - -// Track returns the RTCRtpTransceiver track, or nil -func (r *RTPSender) Track() TrackLocal { - r.mu.RLock() - defer r.mu.RUnlock() - - if len(r.trackEncodings) == 0 { - return nil - } - - return r.trackEncodings[0].track -} - -// ReplaceTrack replaces the track currently being used as the sender's source with a new TrackLocal. -// The new track must be of the same media kind (audio, video, etc) and switching the track should not -// require negotiation. -func (r *RTPSender) ReplaceTrack(track TrackLocal) error { - r.mu.Lock() - defer r.mu.Unlock() - - if track != nil && r.kind != track.Kind() { - return ErrRTPSenderNewTrackHasIncorrectKind - } - - // cannot replace simulcast envelope - if track != nil && len(r.trackEncodings) > 1 { - return ErrRTPSenderNewTrackHasIncorrectEnvelope - } - - var replacedTrack TrackLocal - var context *TrackLocalContext - if len(r.trackEncodings) != 0 { - replacedTrack = r.trackEncodings[0].track - context = &r.trackEncodings[0].context - } - if r.hasSent() && replacedTrack != nil { - if err := replacedTrack.Unbind(*context); err != nil { - return err - } - } - - if !r.hasSent() || track == nil { - r.trackEncodings[0].track = track - return nil - } - - codec, err := track.Bind(TrackLocalContext{ - id: context.id, - params: r.api.mediaEngine.getRTPParametersByKind(track.Kind(), []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}), - ssrc: context.ssrc, - writeStream: context.writeStream, - rtcpInterceptor: context.rtcpInterceptor, - }) - if err != nil { - // Re-bind the original track - if _, reBindErr := replacedTrack.Bind(*context); reBindErr != nil { - return reBindErr - } - - return err - } - - // Codec has changed - if r.payloadType != codec.PayloadType { - context.params.Codecs = []RTPCodecParameters{codec} - } - - r.trackEncodings[0].track = track - return nil -} - -// Send Attempts to set the parameters controlling the sending of media. -func (r *RTPSender) Send(parameters RTPSendParameters) error { - r.mu.Lock() - defer r.mu.Unlock() - - switch { - case r.hasSent(): - return errRTPSenderSendAlreadyCalled - case r.trackEncodings[0].track == nil: - return errRTPSenderTrackRemoved - } - - for idx, trackEncoding := range r.trackEncodings { - writeStream := &interceptorToTrackLocalWriter{} - trackEncoding.context = TrackLocalContext{ - id: r.id, - params: r.api.mediaEngine.getRTPParametersByKind(trackEncoding.track.Kind(), []RTPTransceiverDirection{RTPTransceiverDirectionSendonly}), - ssrc: parameters.Encodings[idx].SSRC, - writeStream: writeStream, - rtcpInterceptor: trackEncoding.rtcpInterceptor, - } - - codec, err := trackEncoding.track.Bind(trackEncoding.context) - if err != nil { - return err - } - trackEncoding.context.params.Codecs = []RTPCodecParameters{codec} - - trackEncoding.streamInfo = *createStreamInfo( - r.id, - parameters.Encodings[idx].SSRC, - codec.PayloadType, - codec.RTPCodecCapability, - parameters.HeaderExtensions, - ) - srtpStream := trackEncoding.srtpStream - rtpInterceptor := r.api.interceptor.BindLocalStream( - &trackEncoding.streamInfo, - interceptor.RTPWriterFunc(func(header *rtp.Header, payload []byte, attributes interceptor.Attributes) (int, error) { - return srtpStream.WriteRTP(header, payload) - }), - ) - writeStream.interceptor.Store(rtpInterceptor) - } - - close(r.sendCalled) - return nil -} - -// Stop irreversibly stops the RTPSender -func (r *RTPSender) Stop() error { - r.mu.Lock() - - if stopped := r.hasStopped(); stopped { - r.mu.Unlock() - return nil - } - - close(r.stopCalled) - r.mu.Unlock() - - if !r.hasSent() { - return nil - } - - if err := r.ReplaceTrack(nil); err != nil { - return err - } - - errs := []error{} - for _, trackEncoding := range r.trackEncodings { - r.api.interceptor.UnbindLocalStream(&trackEncoding.streamInfo) - errs = append(errs, trackEncoding.srtpStream.Close()) - } - - return util.FlattenErrs(errs) -} - -// Read reads incoming RTCP for this RTPSender -func (r *RTPSender) Read(b []byte) (n int, a interceptor.Attributes, err error) { - select { - case <-r.sendCalled: - return r.trackEncodings[0].rtcpInterceptor.Read(b, a) - case <-r.stopCalled: - return 0, nil, io.ErrClosedPipe - } -} - -// ReadRTCP is a convenience method that wraps Read and unmarshals for you. -func (r *RTPSender) ReadRTCP() ([]rtcp.Packet, interceptor.Attributes, error) { - b := make([]byte, r.api.settingEngine.getReceiveMTU()) - i, attributes, err := r.Read(b) - if err != nil { - return nil, nil, err - } - - pkts, err := rtcp.Unmarshal(b[:i]) - if err != nil { - return nil, nil, err - } - - return pkts, attributes, nil -} - -// ReadSimulcast reads incoming RTCP for this RTPSender for given rid -func (r *RTPSender) ReadSimulcast(b []byte, rid string) (n int, a interceptor.Attributes, err error) { - select { - case <-r.sendCalled: - for _, t := range r.trackEncodings { - if t.track != nil && t.track.RID() == rid { - return t.rtcpInterceptor.Read(b, a) - } - } - return 0, nil, fmt.Errorf("%w: %s", errRTPSenderNoTrackForRID, rid) - case <-r.stopCalled: - return 0, nil, io.ErrClosedPipe - } -} - -// ReadSimulcastRTCP is a convenience method that wraps ReadSimulcast and unmarshal for you -func (r *RTPSender) ReadSimulcastRTCP(rid string) ([]rtcp.Packet, interceptor.Attributes, error) { - b := make([]byte, r.api.settingEngine.getReceiveMTU()) - i, attributes, err := r.ReadSimulcast(b, rid) - if err != nil { - return nil, nil, err - } - - pkts, err := rtcp.Unmarshal(b[:i]) - return pkts, attributes, err -} - -// SetReadDeadline sets the deadline for the Read operation. -// Setting to zero means no deadline. -func (r *RTPSender) SetReadDeadline(t time.Time) error { - return r.trackEncodings[0].srtpStream.SetReadDeadline(t) -} - -// SetReadDeadlineSimulcast sets the max amount of time the RTCP stream for a given rid will block before returning. 0 is forever. -func (r *RTPSender) SetReadDeadlineSimulcast(deadline time.Time, rid string) error { - r.mu.RLock() - defer r.mu.RUnlock() - - for _, t := range r.trackEncodings { - if t.track != nil && t.track.RID() == rid { - return t.srtpStream.SetReadDeadline(deadline) - } - } - return fmt.Errorf("%w: %s", errRTPSenderNoTrackForRID, rid) -} - -// hasSent tells if data has been ever sent for this instance -func (r *RTPSender) hasSent() bool { - select { - case <-r.sendCalled: - return true - default: - return false - } -} - -// hasStopped tells if stop has been called -func (r *RTPSender) hasStopped() bool { - select { - case <-r.stopCalled: - return true - default: - return false - } -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpsender_js.go b/vendor/github.com/pion/webrtc/v3/rtpsender_js.go deleted file mode 100644 index 46ea599f..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpsender_js.go +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import "syscall/js" - -// RTPSender allows an application to control how a given Track is encoded and transmitted to a remote peer -type RTPSender struct { - // Pointer to the underlying JavaScript RTCRTPSender object. - underlying js.Value -} diff --git a/vendor/github.com/pion/webrtc/v3/rtpsendparameters.go b/vendor/github.com/pion/webrtc/v3/rtpsendparameters.go deleted file mode 100644 index b955c61c..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtpsendparameters.go +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPSendParameters contains the RTP stack settings used by receivers -type RTPSendParameters struct { - RTPParameters - Encodings []RTPEncodingParameters -} diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiver.go b/vendor/github.com/pion/webrtc/v3/rtptransceiver.go deleted file mode 100644 index 02ddf792..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtptransceiver.go +++ /dev/null @@ -1,293 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "fmt" - "sync" - "sync/atomic" - - "github.com/pion/rtp" -) - -// RTPTransceiver represents a combination of an RTPSender and an RTPReceiver that share a common mid. -type RTPTransceiver struct { - mid atomic.Value // string - sender atomic.Value // *RTPSender - receiver atomic.Value // *RTPReceiver - direction atomic.Value // RTPTransceiverDirection - currentDirection atomic.Value // RTPTransceiverDirection - - codecs []RTPCodecParameters // User provided codecs via SetCodecPreferences - - stopped bool - kind RTPCodecType - - api *API - mu sync.RWMutex -} - -func newRTPTransceiver( - receiver *RTPReceiver, - sender *RTPSender, - direction RTPTransceiverDirection, - kind RTPCodecType, - api *API, -) *RTPTransceiver { - t := &RTPTransceiver{kind: kind, api: api} - t.setReceiver(receiver) - t.setSender(sender) - t.setDirection(direction) - t.setCurrentDirection(RTPTransceiverDirection(Unknown)) - return t -} - -// SetCodecPreferences sets preferred list of supported codecs -// if codecs is empty or nil we reset to default from MediaEngine -func (t *RTPTransceiver) SetCodecPreferences(codecs []RTPCodecParameters) error { - t.mu.Lock() - defer t.mu.Unlock() - - for _, codec := range codecs { - if _, matchType := codecParametersFuzzySearch(codec, t.api.mediaEngine.getCodecsByKind(t.kind)); matchType == codecMatchNone { - return fmt.Errorf("%w %s", errRTPTransceiverCodecUnsupported, codec.MimeType) - } - } - - t.codecs = codecs - return nil -} - -// Codecs returns list of supported codecs -func (t *RTPTransceiver) getCodecs() []RTPCodecParameters { - t.mu.RLock() - defer t.mu.RUnlock() - - mediaEngineCodecs := t.api.mediaEngine.getCodecsByKind(t.kind) - if len(t.codecs) == 0 { - return mediaEngineCodecs - } - - filteredCodecs := []RTPCodecParameters{} - for _, codec := range t.codecs { - if c, matchType := codecParametersFuzzySearch(codec, mediaEngineCodecs); matchType != codecMatchNone { - if codec.PayloadType == 0 { - codec.PayloadType = c.PayloadType - } - filteredCodecs = append(filteredCodecs, codec) - } - } - - return filteredCodecs -} - -// Sender returns the RTPTransceiver's RTPSender if it has one -func (t *RTPTransceiver) Sender() *RTPSender { - if v, ok := t.sender.Load().(*RTPSender); ok { - return v - } - - return nil -} - -// SetSender sets the RTPSender and Track to current transceiver -func (t *RTPTransceiver) SetSender(s *RTPSender, track TrackLocal) error { - t.setSender(s) - return t.setSendingTrack(track) -} - -func (t *RTPTransceiver) setSender(s *RTPSender) { - if s != nil { - s.setRTPTransceiver(t) - } - - if prevSender := t.Sender(); prevSender != nil { - prevSender.setRTPTransceiver(nil) - } - - t.sender.Store(s) -} - -// Receiver returns the RTPTransceiver's RTPReceiver if it has one -func (t *RTPTransceiver) Receiver() *RTPReceiver { - if v, ok := t.receiver.Load().(*RTPReceiver); ok { - return v - } - - return nil -} - -// SetMid sets the RTPTransceiver's mid. If it was already set, will return an error. -func (t *RTPTransceiver) SetMid(mid string) error { - if currentMid := t.Mid(); currentMid != "" { - return fmt.Errorf("%w: %s to %s", errRTPTransceiverCannotChangeMid, currentMid, mid) - } - t.mid.Store(mid) - return nil -} - -// Mid gets the Transceiver's mid value. When not already set, this value will be set in CreateOffer or CreateAnswer. -func (t *RTPTransceiver) Mid() string { - if v, ok := t.mid.Load().(string); ok { - return v - } - return "" -} - -// Kind returns RTPTransceiver's kind. -func (t *RTPTransceiver) Kind() RTPCodecType { - return t.kind -} - -// Direction returns the RTPTransceiver's current direction -func (t *RTPTransceiver) Direction() RTPTransceiverDirection { - if direction, ok := t.direction.Load().(RTPTransceiverDirection); ok { - return direction - } - return RTPTransceiverDirection(0) -} - -// Stop irreversibly stops the RTPTransceiver -func (t *RTPTransceiver) Stop() error { - if sender := t.Sender(); sender != nil { - if err := sender.Stop(); err != nil { - return err - } - } - if receiver := t.Receiver(); receiver != nil { - if err := receiver.Stop(); err != nil { - return err - } - } - - t.setDirection(RTPTransceiverDirectionInactive) - t.setCurrentDirection(RTPTransceiverDirectionInactive) - return nil -} - -func (t *RTPTransceiver) setReceiver(r *RTPReceiver) { - if r != nil { - r.setRTPTransceiver(t) - } - - if prevReceiver := t.Receiver(); prevReceiver != nil { - prevReceiver.setRTPTransceiver(nil) - } - - t.receiver.Store(r) -} - -func (t *RTPTransceiver) setDirection(d RTPTransceiverDirection) { - t.direction.Store(d) -} - -func (t *RTPTransceiver) setCurrentDirection(d RTPTransceiverDirection) { - t.currentDirection.Store(d) -} - -func (t *RTPTransceiver) getCurrentDirection() RTPTransceiverDirection { - if v, ok := t.currentDirection.Load().(RTPTransceiverDirection); ok { - return v - } - return RTPTransceiverDirection(Unknown) -} - -func (t *RTPTransceiver) setSendingTrack(track TrackLocal) error { - if err := t.Sender().ReplaceTrack(track); err != nil { - return err - } - if track == nil { - t.setSender(nil) - } - - switch { - case track != nil && t.Direction() == RTPTransceiverDirectionRecvonly: - t.setDirection(RTPTransceiverDirectionSendrecv) - case track != nil && t.Direction() == RTPTransceiverDirectionInactive: - t.setDirection(RTPTransceiverDirectionSendonly) - case track == nil && t.Direction() == RTPTransceiverDirectionSendrecv: - t.setDirection(RTPTransceiverDirectionRecvonly) - case track != nil && t.Direction() == RTPTransceiverDirectionSendonly: - // Handle the case where a sendonly transceiver was added by a negotiation - // initiated by remote peer. For example a remote peer added a transceiver - // with direction recvonly. - case track != nil && t.Direction() == RTPTransceiverDirectionSendrecv: - // Similar to above, but for sendrecv transceiver. - case track == nil && t.Direction() == RTPTransceiverDirectionSendonly: - t.setDirection(RTPTransceiverDirectionInactive) - default: - return errRTPTransceiverSetSendingInvalidState - } - return nil -} - -func findByMid(mid string, localTransceivers []*RTPTransceiver) (*RTPTransceiver, []*RTPTransceiver) { - for i, t := range localTransceivers { - if t.Mid() == mid { - return t, append(localTransceivers[:i], localTransceivers[i+1:]...) - } - } - - return nil, localTransceivers -} - -// Given a direction+type pluck a transceiver from the passed list -// if no entry satisfies the requested type+direction return a inactive Transceiver -func satisfyTypeAndDirection(remoteKind RTPCodecType, remoteDirection RTPTransceiverDirection, localTransceivers []*RTPTransceiver) (*RTPTransceiver, []*RTPTransceiver) { - // Get direction order from most preferred to least - getPreferredDirections := func() []RTPTransceiverDirection { - switch remoteDirection { - case RTPTransceiverDirectionSendrecv: - return []RTPTransceiverDirection{RTPTransceiverDirectionRecvonly, RTPTransceiverDirectionSendrecv, RTPTransceiverDirectionSendonly} - case RTPTransceiverDirectionSendonly: - return []RTPTransceiverDirection{RTPTransceiverDirectionRecvonly, RTPTransceiverDirectionSendrecv} - case RTPTransceiverDirectionRecvonly: - return []RTPTransceiverDirection{RTPTransceiverDirectionSendonly, RTPTransceiverDirectionSendrecv} - default: - return []RTPTransceiverDirection{} - } - } - - for _, possibleDirection := range getPreferredDirections() { - for i := range localTransceivers { - t := localTransceivers[i] - if t.Mid() == "" && t.kind == remoteKind && possibleDirection == t.Direction() { - return t, append(localTransceivers[:i], localTransceivers[i+1:]...) - } - } - } - - return nil, localTransceivers -} - -// handleUnknownRTPPacket consumes a single RTP Packet and returns information that is helpful -// for demuxing and handling an unknown SSRC (usually for Simulcast) -func handleUnknownRTPPacket(buf []byte, midExtensionID, streamIDExtensionID, repairStreamIDExtensionID uint8, mid, rid, rsid *string) (payloadType PayloadType, err error) { - rp := &rtp.Packet{} - if err = rp.Unmarshal(buf); err != nil { - return - } - - if !rp.Header.Extension { - return - } - - payloadType = PayloadType(rp.PayloadType) - if payload := rp.GetExtension(midExtensionID); payload != nil { - *mid = string(payload) - } - - if payload := rp.GetExtension(streamIDExtensionID); payload != nil { - *rid = string(payload) - } - - if payload := rp.GetExtension(repairStreamIDExtensionID); payload != nil { - *rsid = string(payload) - } - - return -} diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiver_js.go b/vendor/github.com/pion/webrtc/v3/rtptransceiver_js.go deleted file mode 100644 index 43e129af..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtptransceiver_js.go +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import ( - "syscall/js" -) - -// RTPTransceiver represents a combination of an RTPSender and an RTPReceiver that share a common mid. -type RTPTransceiver struct { - // Pointer to the underlying JavaScript RTCRTPTransceiver object. - underlying js.Value -} - -// Direction returns the RTPTransceiver's current direction -func (r *RTPTransceiver) Direction() RTPTransceiverDirection { - return NewRTPTransceiverDirection(r.underlying.Get("direction").String()) -} - -// Sender returns the RTPTransceiver's RTPSender if it has one -func (r *RTPTransceiver) Sender() *RTPSender { - underlying := r.underlying.Get("sender") - if underlying.IsNull() { - return nil - } - - return &RTPSender{underlying: underlying} -} - -// Receiver returns the RTPTransceiver's RTPReceiver if it has one -func (r *RTPTransceiver) Receiver() *RTPReceiver { - underlying := r.underlying.Get("receiver") - if underlying.IsNull() { - return nil - } - - return &RTPReceiver{underlying: underlying} -} diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiverdirection.go b/vendor/github.com/pion/webrtc/v3/rtptransceiverdirection.go deleted file mode 100644 index 752cd5b9..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtptransceiverdirection.go +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPTransceiverDirection indicates the direction of the RTPTransceiver. -type RTPTransceiverDirection int - -const ( - // RTPTransceiverDirectionSendrecv indicates the RTPSender will offer - // to send RTP and the RTPReceiver will offer to receive RTP. - RTPTransceiverDirectionSendrecv RTPTransceiverDirection = iota + 1 - - // RTPTransceiverDirectionSendonly indicates the RTPSender will offer - // to send RTP. - RTPTransceiverDirectionSendonly - - // RTPTransceiverDirectionRecvonly indicates the RTPReceiver will - // offer to receive RTP. - RTPTransceiverDirectionRecvonly - - // RTPTransceiverDirectionInactive indicates the RTPSender won't offer - // to send RTP and the RTPReceiver won't offer to receive RTP. - RTPTransceiverDirectionInactive -) - -// This is done this way because of a linter. -const ( - rtpTransceiverDirectionSendrecvStr = "sendrecv" - rtpTransceiverDirectionSendonlyStr = "sendonly" - rtpTransceiverDirectionRecvonlyStr = "recvonly" - rtpTransceiverDirectionInactiveStr = "inactive" -) - -// NewRTPTransceiverDirection defines a procedure for creating a new -// RTPTransceiverDirection from a raw string naming the transceiver direction. -func NewRTPTransceiverDirection(raw string) RTPTransceiverDirection { - switch raw { - case rtpTransceiverDirectionSendrecvStr: - return RTPTransceiverDirectionSendrecv - case rtpTransceiverDirectionSendonlyStr: - return RTPTransceiverDirectionSendonly - case rtpTransceiverDirectionRecvonlyStr: - return RTPTransceiverDirectionRecvonly - case rtpTransceiverDirectionInactiveStr: - return RTPTransceiverDirectionInactive - default: - return RTPTransceiverDirection(Unknown) - } -} - -func (t RTPTransceiverDirection) String() string { - switch t { - case RTPTransceiverDirectionSendrecv: - return rtpTransceiverDirectionSendrecvStr - case RTPTransceiverDirectionSendonly: - return rtpTransceiverDirectionSendonlyStr - case RTPTransceiverDirectionRecvonly: - return rtpTransceiverDirectionRecvonlyStr - case RTPTransceiverDirectionInactive: - return rtpTransceiverDirectionInactiveStr - default: - return ErrUnknownType.Error() - } -} - -// Revers indicate the opposite direction -func (t RTPTransceiverDirection) Revers() RTPTransceiverDirection { - switch t { - case RTPTransceiverDirectionSendonly: - return RTPTransceiverDirectionRecvonly - case RTPTransceiverDirectionRecvonly: - return RTPTransceiverDirectionSendonly - default: - return t - } -} - -func haveRTPTransceiverDirectionIntersection(haystack []RTPTransceiverDirection, needle []RTPTransceiverDirection) bool { - for _, n := range needle { - for _, h := range haystack { - if n == h { - return true - } - } - } - return false -} diff --git a/vendor/github.com/pion/webrtc/v3/rtptransceiverinit.go b/vendor/github.com/pion/webrtc/v3/rtptransceiverinit.go deleted file mode 100644 index 3aac1dc1..00000000 --- a/vendor/github.com/pion/webrtc/v3/rtptransceiverinit.go +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// RTPTransceiverInit dictionary is used when calling the WebRTC function addTransceiver() to provide configuration options for the new transceiver. -type RTPTransceiverInit struct { - Direction RTPTransceiverDirection - SendEncodings []RTPEncodingParameters - // Streams []*Track -} - -// RtpTransceiverInit is a temporary mapping while we fix case sensitivity -// Deprecated: Use RTPTransceiverInit instead -type RtpTransceiverInit = RTPTransceiverInit //nolint: stylecheck,golint diff --git a/vendor/github.com/pion/webrtc/v3/sctpcapabilities.go b/vendor/github.com/pion/webrtc/v3/sctpcapabilities.go deleted file mode 100644 index c4c5ff5e..00000000 --- a/vendor/github.com/pion/webrtc/v3/sctpcapabilities.go +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// SCTPCapabilities indicates the capabilities of the SCTPTransport. -type SCTPCapabilities struct { - MaxMessageSize uint32 `json:"maxMessageSize"` -} diff --git a/vendor/github.com/pion/webrtc/v3/sctptransport.go b/vendor/github.com/pion/webrtc/v3/sctptransport.go deleted file mode 100644 index c96fd173..00000000 --- a/vendor/github.com/pion/webrtc/v3/sctptransport.go +++ /dev/null @@ -1,420 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "errors" - "io" - "math" - "sync" - "time" - - "github.com/pion/datachannel" - "github.com/pion/logging" - "github.com/pion/sctp" - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -const sctpMaxChannels = uint16(65535) - -// SCTPTransport provides details about the SCTP transport. -type SCTPTransport struct { - lock sync.RWMutex - - dtlsTransport *DTLSTransport - - // State represents the current state of the SCTP transport. - state SCTPTransportState - - // SCTPTransportState doesn't have an enum to distinguish between New/Connecting - // so we need a dedicated field - isStarted bool - - // MaxMessageSize represents the maximum size of data that can be passed to - // DataChannel's send() method. - maxMessageSize float64 - - // MaxChannels represents the maximum amount of DataChannel's that can - // be used simultaneously. - maxChannels *uint16 - - // OnStateChange func() - - onErrorHandler func(error) - - sctpAssociation *sctp.Association - onDataChannelHandler func(*DataChannel) - onDataChannelOpenedHandler func(*DataChannel) - - // DataChannels - dataChannels []*DataChannel - dataChannelsOpened uint32 - dataChannelsRequested uint32 - dataChannelsAccepted uint32 - - api *API - log logging.LeveledLogger -} - -// NewSCTPTransport creates a new SCTPTransport. -// This constructor is part of the ORTC API. It is not -// meant to be used together with the basic WebRTC API. -func (api *API) NewSCTPTransport(dtls *DTLSTransport) *SCTPTransport { - res := &SCTPTransport{ - dtlsTransport: dtls, - state: SCTPTransportStateConnecting, - api: api, - log: api.settingEngine.LoggerFactory.NewLogger("ortc"), - } - - res.updateMessageSize() - res.updateMaxChannels() - - return res -} - -// Transport returns the DTLSTransport instance the SCTPTransport is sending over. -func (r *SCTPTransport) Transport() *DTLSTransport { - r.lock.RLock() - defer r.lock.RUnlock() - - return r.dtlsTransport -} - -// GetCapabilities returns the SCTPCapabilities of the SCTPTransport. -func (r *SCTPTransport) GetCapabilities() SCTPCapabilities { - return SCTPCapabilities{ - MaxMessageSize: 0, - } -} - -// Start the SCTPTransport. Since both local and remote parties must mutually -// create an SCTPTransport, SCTP SO (Simultaneous Open) is used to establish -// a connection over SCTP. -func (r *SCTPTransport) Start(SCTPCapabilities) error { - if r.isStarted { - return nil - } - r.isStarted = true - - dtlsTransport := r.Transport() - if dtlsTransport == nil || dtlsTransport.conn == nil { - return errSCTPTransportDTLS - } - - sctpAssociation, err := sctp.Client(sctp.Config{ - NetConn: dtlsTransport.conn, - MaxReceiveBufferSize: r.api.settingEngine.sctp.maxReceiveBufferSize, - LoggerFactory: r.api.settingEngine.LoggerFactory, - }) - if err != nil { - return err - } - - r.lock.Lock() - r.sctpAssociation = sctpAssociation - r.state = SCTPTransportStateConnected - dataChannels := append([]*DataChannel{}, r.dataChannels...) - r.lock.Unlock() - - var openedDCCount uint32 - for _, d := range dataChannels { - if d.ReadyState() == DataChannelStateConnecting { - err := d.open(r) - if err != nil { - r.log.Warnf("failed to open data channel: %s", err) - continue - } - openedDCCount++ - } - } - - r.lock.Lock() - r.dataChannelsOpened += openedDCCount - r.lock.Unlock() - - go r.acceptDataChannels(sctpAssociation) - - return nil -} - -// Stop stops the SCTPTransport -func (r *SCTPTransport) Stop() error { - r.lock.Lock() - defer r.lock.Unlock() - if r.sctpAssociation == nil { - return nil - } - err := r.sctpAssociation.Close() - if err != nil { - return err - } - - r.sctpAssociation = nil - r.state = SCTPTransportStateClosed - - return nil -} - -func (r *SCTPTransport) acceptDataChannels(a *sctp.Association) { - r.lock.RLock() - dataChannels := make([]*datachannel.DataChannel, 0, len(r.dataChannels)) - for _, dc := range r.dataChannels { - dc.mu.Lock() - isNil := dc.dataChannel == nil - dc.mu.Unlock() - if isNil { - continue - } - dataChannels = append(dataChannels, dc.dataChannel) - } - r.lock.RUnlock() -ACCEPT: - for { - dc, err := datachannel.Accept(a, &datachannel.Config{ - LoggerFactory: r.api.settingEngine.LoggerFactory, - }, dataChannels...) - if err != nil { - if !errors.Is(err, io.EOF) { - r.log.Errorf("Failed to accept data channel: %v", err) - r.onError(err) - } - return - } - for _, ch := range dataChannels { - if ch.StreamIdentifier() == dc.StreamIdentifier() { - continue ACCEPT - } - } - - var ( - maxRetransmits *uint16 - maxPacketLifeTime *uint16 - ) - val := uint16(dc.Config.ReliabilityParameter) - ordered := true - - switch dc.Config.ChannelType { - case datachannel.ChannelTypeReliable: - ordered = true - case datachannel.ChannelTypeReliableUnordered: - ordered = false - case datachannel.ChannelTypePartialReliableRexmit: - ordered = true - maxRetransmits = &val - case datachannel.ChannelTypePartialReliableRexmitUnordered: - ordered = false - maxRetransmits = &val - case datachannel.ChannelTypePartialReliableTimed: - ordered = true - maxPacketLifeTime = &val - case datachannel.ChannelTypePartialReliableTimedUnordered: - ordered = false - maxPacketLifeTime = &val - default: - } - - sid := dc.StreamIdentifier() - rtcDC, err := r.api.newDataChannel(&DataChannelParameters{ - ID: &sid, - Label: dc.Config.Label, - Protocol: dc.Config.Protocol, - Negotiated: dc.Config.Negotiated, - Ordered: ordered, - MaxPacketLifeTime: maxPacketLifeTime, - MaxRetransmits: maxRetransmits, - }, r, r.api.settingEngine.LoggerFactory.NewLogger("ortc")) - if err != nil { - r.log.Errorf("Failed to accept data channel: %v", err) - r.onError(err) - return - } - - <-r.onDataChannel(rtcDC) - rtcDC.handleOpen(dc, true, dc.Config.Negotiated) - - r.lock.Lock() - r.dataChannelsOpened++ - handler := r.onDataChannelOpenedHandler - r.lock.Unlock() - - if handler != nil { - handler(rtcDC) - } - } -} - -// OnError sets an event handler which is invoked when -// the SCTP connection error occurs. -func (r *SCTPTransport) OnError(f func(err error)) { - r.lock.Lock() - defer r.lock.Unlock() - r.onErrorHandler = f -} - -func (r *SCTPTransport) onError(err error) { - r.lock.RLock() - handler := r.onErrorHandler - r.lock.RUnlock() - - if handler != nil { - go handler(err) - } -} - -// OnDataChannel sets an event handler which is invoked when a data -// channel message arrives from a remote peer. -func (r *SCTPTransport) OnDataChannel(f func(*DataChannel)) { - r.lock.Lock() - defer r.lock.Unlock() - r.onDataChannelHandler = f -} - -// OnDataChannelOpened sets an event handler which is invoked when a data -// channel is opened -func (r *SCTPTransport) OnDataChannelOpened(f func(*DataChannel)) { - r.lock.Lock() - defer r.lock.Unlock() - r.onDataChannelOpenedHandler = f -} - -func (r *SCTPTransport) onDataChannel(dc *DataChannel) (done chan struct{}) { - r.lock.Lock() - r.dataChannels = append(r.dataChannels, dc) - r.dataChannelsAccepted++ - handler := r.onDataChannelHandler - r.lock.Unlock() - - done = make(chan struct{}) - if handler == nil || dc == nil { - close(done) - return - } - - // Run this synchronously to allow setup done in onDataChannelFn() - // to complete before datachannel event handlers might be called. - go func() { - handler(dc) - close(done) - }() - - return -} - -func (r *SCTPTransport) updateMessageSize() { - r.lock.Lock() - defer r.lock.Unlock() - - var remoteMaxMessageSize float64 = 65536 // pion/webrtc#758 - var canSendSize float64 = 65536 // pion/webrtc#758 - - r.maxMessageSize = r.calcMessageSize(remoteMaxMessageSize, canSendSize) -} - -func (r *SCTPTransport) calcMessageSize(remoteMaxMessageSize, canSendSize float64) float64 { - switch { - case remoteMaxMessageSize == 0 && - canSendSize == 0: - return math.Inf(1) - - case remoteMaxMessageSize == 0: - return canSendSize - - case canSendSize == 0: - return remoteMaxMessageSize - - case canSendSize > remoteMaxMessageSize: - return remoteMaxMessageSize - - default: - return canSendSize - } -} - -func (r *SCTPTransport) updateMaxChannels() { - val := sctpMaxChannels - r.maxChannels = &val -} - -// MaxChannels is the maximum number of RTCDataChannels that can be open simultaneously. -func (r *SCTPTransport) MaxChannels() uint16 { - r.lock.Lock() - defer r.lock.Unlock() - - if r.maxChannels == nil { - return sctpMaxChannels - } - - return *r.maxChannels -} - -// State returns the current state of the SCTPTransport -func (r *SCTPTransport) State() SCTPTransportState { - r.lock.RLock() - defer r.lock.RUnlock() - return r.state -} - -func (r *SCTPTransport) collectStats(collector *statsReportCollector) { - collector.Collecting() - - stats := TransportStats{ - Timestamp: statsTimestampFrom(time.Now()), - Type: StatsTypeTransport, - ID: "sctpTransport", - } - - association := r.association() - if association != nil { - stats.BytesSent = association.BytesSent() - stats.BytesReceived = association.BytesReceived() - } - - collector.Collect(stats.ID, stats) -} - -func (r *SCTPTransport) generateAndSetDataChannelID(dtlsRole DTLSRole, idOut **uint16) error { - var id uint16 - if dtlsRole != DTLSRoleClient { - id++ - } - - max := r.MaxChannels() - - r.lock.Lock() - defer r.lock.Unlock() - - // Create map of ids so we can compare without double-looping each time. - idsMap := make(map[uint16]struct{}, len(r.dataChannels)) - for _, dc := range r.dataChannels { - if dc.ID() == nil { - continue - } - - idsMap[*dc.ID()] = struct{}{} - } - - for ; id < max-1; id += 2 { - if _, ok := idsMap[id]; ok { - continue - } - *idOut = &id - return nil - } - - return &rtcerr.OperationError{Err: ErrMaxDataChannelID} -} - -func (r *SCTPTransport) association() *sctp.Association { - if r == nil { - return nil - } - r.lock.RLock() - association := r.sctpAssociation - r.lock.RUnlock() - return association -} diff --git a/vendor/github.com/pion/webrtc/v3/sctptransport_js.go b/vendor/github.com/pion/webrtc/v3/sctptransport_js.go deleted file mode 100644 index 7ab6c390..00000000 --- a/vendor/github.com/pion/webrtc/v3/sctptransport_js.go +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -import "syscall/js" - -// SCTPTransport provides details about the SCTP transport. -type SCTPTransport struct { - // Pointer to the underlying JavaScript SCTPTransport object. - underlying js.Value -} - -// Transport returns the DTLSTransport instance the SCTPTransport is sending over. -func (r *SCTPTransport) Transport() *DTLSTransport { - underlying := r.underlying.Get("transport") - if underlying.IsNull() || underlying.IsUndefined() { - return nil - } - - return &DTLSTransport{ - underlying: underlying, - } -} diff --git a/vendor/github.com/pion/webrtc/v3/sctptransportstate.go b/vendor/github.com/pion/webrtc/v3/sctptransportstate.go deleted file mode 100644 index 5dd51d6f..00000000 --- a/vendor/github.com/pion/webrtc/v3/sctptransportstate.go +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -// SCTPTransportState indicates the state of the SCTP transport. -type SCTPTransportState int - -const ( - // SCTPTransportStateConnecting indicates the SCTPTransport is in the - // process of negotiating an association. This is the initial state of the - // SCTPTransportState when an SCTPTransport is created. - SCTPTransportStateConnecting SCTPTransportState = iota + 1 - - // SCTPTransportStateConnected indicates the negotiation of an - // association is completed. - SCTPTransportStateConnected - - // SCTPTransportStateClosed indicates a SHUTDOWN or ABORT chunk is - // received or when the SCTP association has been closed intentionally, - // such as by closing the peer connection or applying a remote description - // that rejects data or changes the SCTP port. - SCTPTransportStateClosed -) - -// This is done this way because of a linter. -const ( - sctpTransportStateConnectingStr = "connecting" - sctpTransportStateConnectedStr = "connected" - sctpTransportStateClosedStr = "closed" -) - -func newSCTPTransportState(raw string) SCTPTransportState { - switch raw { - case sctpTransportStateConnectingStr: - return SCTPTransportStateConnecting - case sctpTransportStateConnectedStr: - return SCTPTransportStateConnected - case sctpTransportStateClosedStr: - return SCTPTransportStateClosed - default: - return SCTPTransportState(Unknown) - } -} - -func (s SCTPTransportState) String() string { - switch s { - case SCTPTransportStateConnecting: - return sctpTransportStateConnectingStr - case SCTPTransportStateConnected: - return sctpTransportStateConnectedStr - case SCTPTransportStateClosed: - return sctpTransportStateClosedStr - default: - return ErrUnknownType.Error() - } -} diff --git a/vendor/github.com/pion/webrtc/v3/sdp.go b/vendor/github.com/pion/webrtc/v3/sdp.go deleted file mode 100644 index a1c8daab..00000000 --- a/vendor/github.com/pion/webrtc/v3/sdp.go +++ /dev/null @@ -1,842 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "errors" - "fmt" - "net/url" - "regexp" - "strconv" - "strings" - "sync/atomic" - - "github.com/pion/ice/v2" - "github.com/pion/logging" - "github.com/pion/sdp/v3" -) - -// trackDetails represents any media source that can be represented in a SDP -// This isn't keyed by SSRC because it also needs to support rid based sources -type trackDetails struct { - mid string - kind RTPCodecType - streamID string - id string - ssrcs []SSRC - repairSsrc *SSRC - rids []string -} - -func trackDetailsForSSRC(trackDetails []trackDetails, ssrc SSRC) *trackDetails { - for i := range trackDetails { - for j := range trackDetails[i].ssrcs { - if trackDetails[i].ssrcs[j] == ssrc { - return &trackDetails[i] - } - } - } - return nil -} - -func trackDetailsForRID(trackDetails []trackDetails, mid, rid string) *trackDetails { - for i := range trackDetails { - if trackDetails[i].mid != mid { - continue - } - - for j := range trackDetails[i].rids { - if trackDetails[i].rids[j] == rid { - return &trackDetails[i] - } - } - } - return nil -} - -func filterTrackWithSSRC(incomingTracks []trackDetails, ssrc SSRC) []trackDetails { - filtered := []trackDetails{} - doesTrackHaveSSRC := func(t trackDetails) bool { - for i := range t.ssrcs { - if t.ssrcs[i] == ssrc { - return true - } - } - - return false - } - - for i := range incomingTracks { - if !doesTrackHaveSSRC(incomingTracks[i]) { - filtered = append(filtered, incomingTracks[i]) - } - } - - return filtered -} - -// extract all trackDetails from an SDP. -func trackDetailsFromSDP(log logging.LeveledLogger, s *sdp.SessionDescription) (incomingTracks []trackDetails) { // nolint:gocognit - for _, media := range s.MediaDescriptions { - tracksInMediaSection := []trackDetails{} - rtxRepairFlows := map[uint64]uint64{} - - // Plan B can have multiple tracks in a signle media section - streamID := "" - trackID := "" - - // If media section is recvonly or inactive skip - if _, ok := media.Attribute(sdp.AttrKeyRecvOnly); ok { - continue - } else if _, ok := media.Attribute(sdp.AttrKeyInactive); ok { - continue - } - - midValue := getMidValue(media) - if midValue == "" { - continue - } - - codecType := NewRTPCodecType(media.MediaName.Media) - if codecType == 0 { - continue - } - - for _, attr := range media.Attributes { - switch attr.Key { - case sdp.AttrKeySSRCGroup: - split := strings.Split(attr.Value, " ") - if split[0] == sdp.SemanticTokenFlowIdentification { - // Add rtx ssrcs to blacklist, to avoid adding them as tracks - // Essentially lines like `a=ssrc-group:FID 2231627014 632943048` are processed by this section - // as this declares that the second SSRC (632943048) is a rtx repair flow (RFC4588) for the first - // (2231627014) as specified in RFC5576 - if len(split) == 3 { - baseSsrc, err := strconv.ParseUint(split[1], 10, 32) - if err != nil { - log.Warnf("Failed to parse SSRC: %v", err) - continue - } - rtxRepairFlow, err := strconv.ParseUint(split[2], 10, 32) - if err != nil { - log.Warnf("Failed to parse SSRC: %v", err) - continue - } - rtxRepairFlows[rtxRepairFlow] = baseSsrc - tracksInMediaSection = filterTrackWithSSRC(tracksInMediaSection, SSRC(rtxRepairFlow)) // Remove if rtx was added as track before - } - } - - // Handle `a=msid: ` for Unified plan. The first value is the same as MediaStream.id - // in the browser and can be used to figure out which tracks belong to the same stream. The browser should - // figure this out automatically when an ontrack event is emitted on RTCPeerConnection. - case sdp.AttrKeyMsid: - split := strings.Split(attr.Value, " ") - if len(split) == 2 { - streamID = split[0] - trackID = split[1] - } - - case sdp.AttrKeySSRC: - split := strings.Split(attr.Value, " ") - ssrc, err := strconv.ParseUint(split[0], 10, 32) - if err != nil { - log.Warnf("Failed to parse SSRC: %v", err) - continue - } - - if _, ok := rtxRepairFlows[ssrc]; ok { - continue // This ssrc is a RTX repair flow, ignore - } - - if len(split) == 3 && strings.HasPrefix(split[1], "msid:") { - streamID = split[1][len("msid:"):] - trackID = split[2] - } - - isNewTrack := true - trackDetails := &trackDetails{} - for i := range tracksInMediaSection { - for j := range tracksInMediaSection[i].ssrcs { - if tracksInMediaSection[i].ssrcs[j] == SSRC(ssrc) { - trackDetails = &tracksInMediaSection[i] - isNewTrack = false - } - } - } - - trackDetails.mid = midValue - trackDetails.kind = codecType - trackDetails.streamID = streamID - trackDetails.id = trackID - trackDetails.ssrcs = []SSRC{SSRC(ssrc)} - - for r, baseSsrc := range rtxRepairFlows { - if baseSsrc == ssrc { - repairSsrc := SSRC(r) - trackDetails.repairSsrc = &repairSsrc - } - } - - if isNewTrack { - tracksInMediaSection = append(tracksInMediaSection, *trackDetails) - } - } - } - - if rids := getRids(media); len(rids) != 0 && trackID != "" && streamID != "" { - simulcastTrack := trackDetails{ - mid: midValue, - kind: codecType, - streamID: streamID, - id: trackID, - rids: []string{}, - } - for rid := range rids { - simulcastTrack.rids = append(simulcastTrack.rids, rid) - } - - tracksInMediaSection = []trackDetails{simulcastTrack} - } - - incomingTracks = append(incomingTracks, tracksInMediaSection...) - } - - return incomingTracks -} - -func trackDetailsToRTPReceiveParameters(t *trackDetails) RTPReceiveParameters { - encodingSize := len(t.ssrcs) - if len(t.rids) >= encodingSize { - encodingSize = len(t.rids) - } - - encodings := make([]RTPDecodingParameters, encodingSize) - for i := range encodings { - if len(t.rids) > i { - encodings[i].RID = t.rids[i] - } - if len(t.ssrcs) > i { - encodings[i].SSRC = t.ssrcs[i] - } - - if t.repairSsrc != nil { - encodings[i].RTX.SSRC = *t.repairSsrc - } - } - - return RTPReceiveParameters{Encodings: encodings} -} - -func getRids(media *sdp.MediaDescription) map[string]string { - rids := map[string]string{} - for _, attr := range media.Attributes { - if attr.Key == sdpAttributeRid { - split := strings.Split(attr.Value, " ") - rids[split[0]] = attr.Value - } - } - return rids -} - -func addCandidatesToMediaDescriptions(candidates []ICECandidate, m *sdp.MediaDescription, iceGatheringState ICEGatheringState) error { - appendCandidateIfNew := func(c ice.Candidate, attributes []sdp.Attribute) { - marshaled := c.Marshal() - for _, a := range attributes { - if marshaled == a.Value { - return - } - } - - m.WithValueAttribute("candidate", marshaled) - } - - for _, c := range candidates { - candidate, err := c.toICE() - if err != nil { - return err - } - - candidate.SetComponent(1) - appendCandidateIfNew(candidate, m.Attributes) - - candidate.SetComponent(2) - appendCandidateIfNew(candidate, m.Attributes) - } - - if iceGatheringState != ICEGatheringStateComplete { - return nil - } - for _, a := range m.Attributes { - if a.Key == "end-of-candidates" { - return nil - } - } - - m.WithPropertyAttribute("end-of-candidates") - return nil -} - -func addDataMediaSection(d *sdp.SessionDescription, shouldAddCandidates bool, dtlsFingerprints []DTLSFingerprint, midValue string, iceParams ICEParameters, candidates []ICECandidate, dtlsRole sdp.ConnectionRole, iceGatheringState ICEGatheringState) error { - media := (&sdp.MediaDescription{ - MediaName: sdp.MediaName{ - Media: mediaSectionApplication, - Port: sdp.RangedPort{Value: 9}, - Protos: []string{"UDP", "DTLS", "SCTP"}, - Formats: []string{"webrtc-datachannel"}, - }, - ConnectionInformation: &sdp.ConnectionInformation{ - NetworkType: "IN", - AddressType: "IP4", - Address: &sdp.Address{ - Address: "0.0.0.0", - }, - }, - }). - WithValueAttribute(sdp.AttrKeyConnectionSetup, dtlsRole.String()). - WithValueAttribute(sdp.AttrKeyMID, midValue). - WithPropertyAttribute(RTPTransceiverDirectionSendrecv.String()). - WithPropertyAttribute("sctp-port:5000"). - WithICECredentials(iceParams.UsernameFragment, iceParams.Password) - - for _, f := range dtlsFingerprints { - media = media.WithFingerprint(f.Algorithm, strings.ToUpper(f.Value)) - } - - if shouldAddCandidates { - if err := addCandidatesToMediaDescriptions(candidates, media, iceGatheringState); err != nil { - return err - } - } - - d.WithMedia(media) - return nil -} - -func populateLocalCandidates(sessionDescription *SessionDescription, i *ICEGatherer, iceGatheringState ICEGatheringState) *SessionDescription { - if sessionDescription == nil || i == nil { - return sessionDescription - } - - candidates, err := i.GetLocalCandidates() - if err != nil { - return sessionDescription - } - - parsed := sessionDescription.parsed - if len(parsed.MediaDescriptions) > 0 { - m := parsed.MediaDescriptions[0] - if err = addCandidatesToMediaDescriptions(candidates, m, iceGatheringState); err != nil { - return sessionDescription - } - } - - sdp, err := parsed.Marshal() - if err != nil { - return sessionDescription - } - - return &SessionDescription{ - SDP: string(sdp), - Type: sessionDescription.Type, - parsed: parsed, - } -} - -func addSenderSDP( - mediaSection mediaSection, - isPlanB bool, - media *sdp.MediaDescription, -) { - for _, mt := range mediaSection.transceivers { - sender := mt.Sender() - if sender == nil { - continue - } - - track := sender.Track() - if track == nil { - continue - } - - sendParameters := sender.GetParameters() - for _, encoding := range sendParameters.Encodings { - media = media.WithMediaSource(uint32(encoding.SSRC), track.StreamID() /* cname */, track.StreamID() /* streamLabel */, track.ID()) - if !isPlanB { - media = media.WithPropertyAttribute("msid:" + track.StreamID() + " " + track.ID()) - } - } - - if len(sendParameters.Encodings) > 1 { - sendRids := make([]string, 0, len(sendParameters.Encodings)) - - for _, encoding := range sendParameters.Encodings { - media.WithValueAttribute(sdpAttributeRid, encoding.RID+" send") - sendRids = append(sendRids, encoding.RID) - } - // Simulcast - media.WithValueAttribute("simulcast", "send "+strings.Join(sendRids, ";")) - } - - if !isPlanB { - break - } - } -} - -func addTransceiverSDP( - d *sdp.SessionDescription, - isPlanB bool, - shouldAddCandidates bool, - dtlsFingerprints []DTLSFingerprint, - mediaEngine *MediaEngine, - midValue string, - iceParams ICEParameters, - candidates []ICECandidate, - dtlsRole sdp.ConnectionRole, - iceGatheringState ICEGatheringState, - mediaSection mediaSection, -) (bool, error) { - transceivers := mediaSection.transceivers - if len(transceivers) < 1 { - return false, errSDPZeroTransceivers - } - // Use the first transceiver to generate the section attributes - t := transceivers[0] - media := sdp.NewJSEPMediaDescription(t.kind.String(), []string{}). - WithValueAttribute(sdp.AttrKeyConnectionSetup, dtlsRole.String()). - WithValueAttribute(sdp.AttrKeyMID, midValue). - WithICECredentials(iceParams.UsernameFragment, iceParams.Password). - WithPropertyAttribute(sdp.AttrKeyRTCPMux). - WithPropertyAttribute(sdp.AttrKeyRTCPRsize) - - codecs := t.getCodecs() - for _, codec := range codecs { - name := strings.TrimPrefix(codec.MimeType, "audio/") - name = strings.TrimPrefix(name, "video/") - media.WithCodec(uint8(codec.PayloadType), name, codec.ClockRate, codec.Channels, codec.SDPFmtpLine) - - for _, feedback := range codec.RTPCodecCapability.RTCPFeedback { - media.WithValueAttribute("rtcp-fb", fmt.Sprintf("%d %s %s", codec.PayloadType, feedback.Type, feedback.Parameter)) - } - } - if len(codecs) == 0 { - // If we are sender and we have no codecs throw an error early - if t.Sender() != nil { - return false, ErrSenderWithNoCodecs - } - - // Explicitly reject track if we don't have the codec - // We need to include connection information even if we're rejecting a track, otherwise Firefox will fail to - // parse the SDP with an error like: - // SIPCC Failed to parse SDP: SDP Parse Error on line 50: c= connection line not specified for every media level, validation failed. - // In addition this makes our SDP compliant with RFC 4566 Section 5.7: https://datatracker.ietf.org/doc/html/rfc4566#section-5.7 - d.WithMedia(&sdp.MediaDescription{ - MediaName: sdp.MediaName{ - Media: t.kind.String(), - Port: sdp.RangedPort{Value: 0}, - Protos: []string{"UDP", "TLS", "RTP", "SAVPF"}, - Formats: []string{"0"}, - }, - ConnectionInformation: &sdp.ConnectionInformation{ - NetworkType: "IN", - AddressType: "IP4", - Address: &sdp.Address{ - Address: "0.0.0.0", - }, - }, - }) - return false, nil - } - - directions := []RTPTransceiverDirection{} - if t.Sender() != nil { - directions = append(directions, RTPTransceiverDirectionSendonly) - } - if t.Receiver() != nil { - directions = append(directions, RTPTransceiverDirectionRecvonly) - } - - parameters := mediaEngine.getRTPParametersByKind(t.kind, directions) - for _, rtpExtension := range parameters.HeaderExtensions { - extURL, err := url.Parse(rtpExtension.URI) - if err != nil { - return false, err - } - media.WithExtMap(sdp.ExtMap{Value: rtpExtension.ID, URI: extURL}) - } - - if len(mediaSection.ridMap) > 0 { - recvRids := make([]string, 0, len(mediaSection.ridMap)) - - for rid := range mediaSection.ridMap { - media.WithValueAttribute(sdpAttributeRid, rid+" recv") - recvRids = append(recvRids, rid) - } - // Simulcast - media.WithValueAttribute("simulcast", "recv "+strings.Join(recvRids, ";")) - } - - addSenderSDP(mediaSection, isPlanB, media) - - media = media.WithPropertyAttribute(t.Direction().String()) - - for _, fingerprint := range dtlsFingerprints { - media = media.WithFingerprint(fingerprint.Algorithm, strings.ToUpper(fingerprint.Value)) - } - - if shouldAddCandidates { - if err := addCandidatesToMediaDescriptions(candidates, media, iceGatheringState); err != nil { - return false, err - } - } - - d.WithMedia(media) - - return true, nil -} - -type mediaSection struct { - id string - transceivers []*RTPTransceiver - data bool - ridMap map[string]string -} - -// populateSDP serializes a PeerConnections state into an SDP -func populateSDP(d *sdp.SessionDescription, isPlanB bool, dtlsFingerprints []DTLSFingerprint, mediaDescriptionFingerprint bool, isICELite bool, isExtmapAllowMixed bool, mediaEngine *MediaEngine, connectionRole sdp.ConnectionRole, candidates []ICECandidate, iceParams ICEParameters, mediaSections []mediaSection, iceGatheringState ICEGatheringState) (*sdp.SessionDescription, error) { - var err error - mediaDtlsFingerprints := []DTLSFingerprint{} - - if mediaDescriptionFingerprint { - mediaDtlsFingerprints = dtlsFingerprints - } - - bundleValue := "BUNDLE" - bundleCount := 0 - appendBundle := func(midValue string) { - bundleValue += " " + midValue - bundleCount++ - } - - for i, m := range mediaSections { - if m.data && len(m.transceivers) != 0 { - return nil, errSDPMediaSectionMediaDataChanInvalid - } else if !isPlanB && len(m.transceivers) > 1 { - return nil, errSDPMediaSectionMultipleTrackInvalid - } - - shouldAddID := true - shouldAddCandidates := i == 0 - if m.data { - if err = addDataMediaSection(d, shouldAddCandidates, mediaDtlsFingerprints, m.id, iceParams, candidates, connectionRole, iceGatheringState); err != nil { - return nil, err - } - } else { - shouldAddID, err = addTransceiverSDP(d, isPlanB, shouldAddCandidates, mediaDtlsFingerprints, mediaEngine, m.id, iceParams, candidates, connectionRole, iceGatheringState, m) - if err != nil { - return nil, err - } - } - - if shouldAddID { - appendBundle(m.id) - } - } - - if !mediaDescriptionFingerprint { - for _, fingerprint := range dtlsFingerprints { - d.WithFingerprint(fingerprint.Algorithm, strings.ToUpper(fingerprint.Value)) - } - } - - if isICELite { - // RFC 5245 S15.3 - d = d.WithValueAttribute(sdp.AttrKeyICELite, "") - } - - if isExtmapAllowMixed { - d = d.WithPropertyAttribute(sdp.AttrKeyExtMapAllowMixed) - } - - return d.WithValueAttribute(sdp.AttrKeyGroup, bundleValue), nil -} - -func getMidValue(media *sdp.MediaDescription) string { - for _, attr := range media.Attributes { - if attr.Key == "mid" { - return attr.Value - } - } - return "" -} - -// SessionDescription contains a MediaSection with Multiple SSRCs, it is Plan-B -func descriptionIsPlanB(desc *SessionDescription, log logging.LeveledLogger) bool { - if desc == nil || desc.parsed == nil { - return false - } - - // Store all MIDs that already contain a track - midWithTrack := map[string]bool{} - - for _, trackDetail := range trackDetailsFromSDP(log, desc.parsed) { - if _, ok := midWithTrack[trackDetail.mid]; ok { - return true - } - midWithTrack[trackDetail.mid] = true - } - - return false -} - -// SessionDescription contains a MediaSection with name `audio`, `video` or `data` -// If only one SSRC is set we can't know if it is Plan-B or Unified. If users have -// set fallback mode assume it is Plan-B -func descriptionPossiblyPlanB(desc *SessionDescription) bool { - if desc == nil || desc.parsed == nil { - return false - } - - detectionRegex := regexp.MustCompile(`(?i)^(audio|video|data)$`) - for _, media := range desc.parsed.MediaDescriptions { - if len(detectionRegex.FindStringSubmatch(getMidValue(media))) == 2 { - return true - } - } - return false -} - -func getPeerDirection(media *sdp.MediaDescription) RTPTransceiverDirection { - for _, a := range media.Attributes { - if direction := NewRTPTransceiverDirection(a.Key); direction != RTPTransceiverDirection(Unknown) { - return direction - } - } - return RTPTransceiverDirection(Unknown) -} - -func extractFingerprint(desc *sdp.SessionDescription) (string, string, error) { - fingerprints := []string{} - - if fingerprint, haveFingerprint := desc.Attribute("fingerprint"); haveFingerprint { - fingerprints = append(fingerprints, fingerprint) - } - - for _, m := range desc.MediaDescriptions { - if fingerprint, haveFingerprint := m.Attribute("fingerprint"); haveFingerprint { - fingerprints = append(fingerprints, fingerprint) - } - } - - if len(fingerprints) < 1 { - return "", "", ErrSessionDescriptionNoFingerprint - } - - for _, m := range fingerprints { - if m != fingerprints[0] { - return "", "", ErrSessionDescriptionConflictingFingerprints - } - } - - parts := strings.Split(fingerprints[0], " ") - if len(parts) != 2 { - return "", "", ErrSessionDescriptionInvalidFingerprint - } - return parts[1], parts[0], nil -} - -func extractICEDetails(desc *sdp.SessionDescription, log logging.LeveledLogger) (string, string, []ICECandidate, error) { // nolint:gocognit - candidates := []ICECandidate{} - remotePwds := []string{} - remoteUfrags := []string{} - - if ufrag, haveUfrag := desc.Attribute("ice-ufrag"); haveUfrag { - remoteUfrags = append(remoteUfrags, ufrag) - } - if pwd, havePwd := desc.Attribute("ice-pwd"); havePwd { - remotePwds = append(remotePwds, pwd) - } - - for _, m := range desc.MediaDescriptions { - if ufrag, haveUfrag := m.Attribute("ice-ufrag"); haveUfrag { - remoteUfrags = append(remoteUfrags, ufrag) - } - if pwd, havePwd := m.Attribute("ice-pwd"); havePwd { - remotePwds = append(remotePwds, pwd) - } - - for _, a := range m.Attributes { - if a.IsICECandidate() { - c, err := ice.UnmarshalCandidate(a.Value) - if err != nil { - if errors.Is(err, ice.ErrUnknownCandidateTyp) || errors.Is(err, ice.ErrDetermineNetworkType) { - log.Warnf("Discarding remote candidate: %s", err) - continue - } - return "", "", nil, err - } - - candidate, err := newICECandidateFromICE(c) - if err != nil { - return "", "", nil, err - } - - candidates = append(candidates, candidate) - } - } - } - - if len(remoteUfrags) == 0 { - return "", "", nil, ErrSessionDescriptionMissingIceUfrag - } else if len(remotePwds) == 0 { - return "", "", nil, ErrSessionDescriptionMissingIcePwd - } - - for _, m := range remoteUfrags { - if m != remoteUfrags[0] { - return "", "", nil, ErrSessionDescriptionConflictingIceUfrag - } - } - - for _, m := range remotePwds { - if m != remotePwds[0] { - return "", "", nil, ErrSessionDescriptionConflictingIcePwd - } - } - - return remoteUfrags[0], remotePwds[0], candidates, nil -} - -func haveApplicationMediaSection(desc *sdp.SessionDescription) bool { - for _, m := range desc.MediaDescriptions { - if m.MediaName.Media == mediaSectionApplication { - return true - } - } - - return false -} - -func getByMid(searchMid string, desc *SessionDescription) *sdp.MediaDescription { - for _, m := range desc.parsed.MediaDescriptions { - if mid, ok := m.Attribute(sdp.AttrKeyMID); ok && mid == searchMid { - return m - } - } - return nil -} - -// haveDataChannel return MediaDescription with MediaName equal application -func haveDataChannel(desc *SessionDescription) *sdp.MediaDescription { - for _, d := range desc.parsed.MediaDescriptions { - if d.MediaName.Media == mediaSectionApplication { - return d - } - } - return nil -} - -func codecsFromMediaDescription(m *sdp.MediaDescription) (out []RTPCodecParameters, err error) { - s := &sdp.SessionDescription{ - MediaDescriptions: []*sdp.MediaDescription{m}, - } - - for _, payloadStr := range m.MediaName.Formats { - payloadType, err := strconv.ParseUint(payloadStr, 10, 8) - if err != nil { - return nil, err - } - - codec, err := s.GetCodecForPayloadType(uint8(payloadType)) - if err != nil { - if payloadType == 0 { - continue - } - return nil, err - } - - channels := uint16(0) - val, err := strconv.ParseUint(codec.EncodingParameters, 10, 16) - if err == nil { - channels = uint16(val) - } - - feedback := []RTCPFeedback{} - for _, raw := range codec.RTCPFeedback { - split := strings.Split(raw, " ") - entry := RTCPFeedback{Type: split[0]} - if len(split) == 2 { - entry.Parameter = split[1] - } - - feedback = append(feedback, entry) - } - - out = append(out, RTPCodecParameters{ - RTPCodecCapability: RTPCodecCapability{m.MediaName.Media + "/" + codec.Name, codec.ClockRate, channels, codec.Fmtp, feedback}, - PayloadType: PayloadType(payloadType), - }) - } - - return out, nil -} - -func rtpExtensionsFromMediaDescription(m *sdp.MediaDescription) (map[string]int, error) { - out := map[string]int{} - - for _, a := range m.Attributes { - if a.Key == sdp.AttrKeyExtMap { - e := sdp.ExtMap{} - if err := e.Unmarshal(a.String()); err != nil { - return nil, err - } - - out[e.URI.String()] = e.Value - } - } - - return out, nil -} - -// updateSDPOrigin saves sdp.Origin in PeerConnection when creating 1st local SDP; -// for subsequent calling, it updates Origin for SessionDescription from saved one -// and increments session version by one. -// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-25#section-5.2.2 -func updateSDPOrigin(origin *sdp.Origin, d *sdp.SessionDescription) { - if atomic.CompareAndSwapUint64(&origin.SessionVersion, 0, d.Origin.SessionVersion) { // store - atomic.StoreUint64(&origin.SessionID, d.Origin.SessionID) - } else { // load - for { // awaiting for saving session id - d.Origin.SessionID = atomic.LoadUint64(&origin.SessionID) - if d.Origin.SessionID != 0 { - break - } - } - d.Origin.SessionVersion = atomic.AddUint64(&origin.SessionVersion, 1) - } -} - -func isIceLiteSet(desc *sdp.SessionDescription) bool { - for _, a := range desc.Attributes { - if strings.TrimSpace(a.Key) == sdp.AttrKeyICELite { - return true - } - } - - return false -} - -func isExtMapAllowMixedSet(desc *sdp.SessionDescription) bool { - for _, a := range desc.Attributes { - if strings.TrimSpace(a.Key) == sdp.AttrKeyExtMapAllowMixed { - return true - } - } - - return false -} diff --git a/vendor/github.com/pion/webrtc/v3/sdpsemantics.go b/vendor/github.com/pion/webrtc/v3/sdpsemantics.go deleted file mode 100644 index 6d633504..00000000 --- a/vendor/github.com/pion/webrtc/v3/sdpsemantics.go +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "encoding/json" -) - -// SDPSemantics determines which style of SDP offers and answers -// can be used -type SDPSemantics int - -const ( - // SDPSemanticsUnifiedPlan uses unified-plan offers and answers - // (the default in Chrome since M72) - // https://tools.ietf.org/html/draft-roach-mmusic-unified-plan-00 - SDPSemanticsUnifiedPlan SDPSemantics = iota - - // SDPSemanticsPlanB uses plan-b offers and answers - // NB: This format should be considered deprecated - // https://tools.ietf.org/html/draft-uberti-rtcweb-plan-00 - SDPSemanticsPlanB - - // SDPSemanticsUnifiedPlanWithFallback prefers unified-plan - // offers and answers, but will respond to a plan-b offer - // with a plan-b answer - SDPSemanticsUnifiedPlanWithFallback -) - -const ( - sdpSemanticsUnifiedPlanWithFallback = "unified-plan-with-fallback" - sdpSemanticsUnifiedPlan = "unified-plan" - sdpSemanticsPlanB = "plan-b" -) - -func newSDPSemantics(raw string) SDPSemantics { - switch raw { - case sdpSemanticsUnifiedPlan: - return SDPSemanticsUnifiedPlan - case sdpSemanticsPlanB: - return SDPSemanticsPlanB - case sdpSemanticsUnifiedPlanWithFallback: - return SDPSemanticsUnifiedPlanWithFallback - default: - return SDPSemantics(Unknown) - } -} - -func (s SDPSemantics) String() string { - switch s { - case SDPSemanticsUnifiedPlanWithFallback: - return sdpSemanticsUnifiedPlanWithFallback - case SDPSemanticsUnifiedPlan: - return sdpSemanticsUnifiedPlan - case SDPSemanticsPlanB: - return sdpSemanticsPlanB - default: - return ErrUnknownType.Error() - } -} - -// UnmarshalJSON parses the JSON-encoded data and stores the result -func (s *SDPSemantics) UnmarshalJSON(b []byte) error { - var val string - if err := json.Unmarshal(b, &val); err != nil { - return err - } - - *s = newSDPSemantics(val) - return nil -} - -// MarshalJSON returns the JSON encoding -func (s SDPSemantics) MarshalJSON() ([]byte, error) { - return json.Marshal(s.String()) -} diff --git a/vendor/github.com/pion/webrtc/v3/sdptype.go b/vendor/github.com/pion/webrtc/v3/sdptype.go deleted file mode 100644 index 0c6d1d46..00000000 --- a/vendor/github.com/pion/webrtc/v3/sdptype.go +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "encoding/json" - "strings" -) - -// SDPType describes the type of an SessionDescription. -type SDPType int - -const ( - // SDPTypeOffer indicates that a description MUST be treated as an SDP - // offer. - SDPTypeOffer SDPType = iota + 1 - - // SDPTypePranswer indicates that a description MUST be treated as an - // SDP answer, but not a final answer. A description used as an SDP - // pranswer may be applied as a response to an SDP offer, or an update to - // a previously sent SDP pranswer. - SDPTypePranswer - - // SDPTypeAnswer indicates that a description MUST be treated as an SDP - // final answer, and the offer-answer exchange MUST be considered complete. - // A description used as an SDP answer may be applied as a response to an - // SDP offer or as an update to a previously sent SDP pranswer. - SDPTypeAnswer - - // SDPTypeRollback indicates that a description MUST be treated as - // canceling the current SDP negotiation and moving the SDP offer and - // answer back to what it was in the previous stable state. Note the - // local or remote SDP descriptions in the previous stable state could be - // null if there has not yet been a successful offer-answer negotiation. - SDPTypeRollback -) - -// This is done this way because of a linter. -const ( - sdpTypeOfferStr = "offer" - sdpTypePranswerStr = "pranswer" - sdpTypeAnswerStr = "answer" - sdpTypeRollbackStr = "rollback" -) - -// NewSDPType creates an SDPType from a string -func NewSDPType(raw string) SDPType { - switch raw { - case sdpTypeOfferStr: - return SDPTypeOffer - case sdpTypePranswerStr: - return SDPTypePranswer - case sdpTypeAnswerStr: - return SDPTypeAnswer - case sdpTypeRollbackStr: - return SDPTypeRollback - default: - return SDPType(Unknown) - } -} - -func (t SDPType) String() string { - switch t { - case SDPTypeOffer: - return sdpTypeOfferStr - case SDPTypePranswer: - return sdpTypePranswerStr - case SDPTypeAnswer: - return sdpTypeAnswerStr - case SDPTypeRollback: - return sdpTypeRollbackStr - default: - return ErrUnknownType.Error() - } -} - -// MarshalJSON enables JSON marshaling of a SDPType -func (t SDPType) MarshalJSON() ([]byte, error) { - return json.Marshal(t.String()) -} - -// UnmarshalJSON enables JSON unmarshaling of a SDPType -func (t *SDPType) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - switch strings.ToLower(s) { - default: - return ErrUnknownType - case "offer": - *t = SDPTypeOffer - case "pranswer": - *t = SDPTypePranswer - case "answer": - *t = SDPTypeAnswer - case "rollback": - *t = SDPTypeRollback - } - - return nil -} diff --git a/vendor/github.com/pion/webrtc/v3/sessiondescription.go b/vendor/github.com/pion/webrtc/v3/sessiondescription.go deleted file mode 100644 index 12cdf0dd..00000000 --- a/vendor/github.com/pion/webrtc/v3/sessiondescription.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "github.com/pion/sdp/v3" -) - -// SessionDescription is used to expose local and remote session descriptions. -type SessionDescription struct { - Type SDPType `json:"type"` - SDP string `json:"sdp"` - - // This will never be initialized by callers, internal use only - parsed *sdp.SessionDescription -} - -// Unmarshal is a helper to deserialize the sdp -func (sd *SessionDescription) Unmarshal() (*sdp.SessionDescription, error) { - sd.parsed = &sdp.SessionDescription{} - err := sd.parsed.Unmarshal([]byte(sd.SDP)) - return sd.parsed, err -} diff --git a/vendor/github.com/pion/webrtc/v3/settingengine.go b/vendor/github.com/pion/webrtc/v3/settingengine.go deleted file mode 100644 index b11c625e..00000000 --- a/vendor/github.com/pion/webrtc/v3/settingengine.go +++ /dev/null @@ -1,423 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "context" - "crypto/x509" - "io" - "net" - "time" - - "github.com/pion/dtls/v2" - dtlsElliptic "github.com/pion/dtls/v2/pkg/crypto/elliptic" - "github.com/pion/ice/v2" - "github.com/pion/logging" - "github.com/pion/transport/v2" - "github.com/pion/transport/v2/packetio" - "github.com/pion/transport/v2/vnet" - "golang.org/x/net/proxy" -) - -// SettingEngine allows influencing behavior in ways that are not -// supported by the WebRTC API. This allows us to support additional -// use-cases without deviating from the WebRTC API elsewhere. -type SettingEngine struct { - ephemeralUDP struct { - PortMin uint16 - PortMax uint16 - } - detach struct { - DataChannels bool - } - timeout struct { - ICEDisconnectedTimeout *time.Duration - ICEFailedTimeout *time.Duration - ICEKeepaliveInterval *time.Duration - ICEHostAcceptanceMinWait *time.Duration - ICESrflxAcceptanceMinWait *time.Duration - ICEPrflxAcceptanceMinWait *time.Duration - ICERelayAcceptanceMinWait *time.Duration - } - candidates struct { - ICELite bool - ICENetworkTypes []NetworkType - InterfaceFilter func(string) bool - IPFilter func(net.IP) bool - NAT1To1IPs []string - NAT1To1IPCandidateType ICECandidateType - MulticastDNSMode ice.MulticastDNSMode - MulticastDNSHostName string - UsernameFragment string - Password string - IncludeLoopbackCandidate bool - } - replayProtection struct { - DTLS *uint - SRTP *uint - SRTCP *uint - } - dtls struct { - insecureSkipHelloVerify bool - disableInsecureSkipVerify bool - retransmissionInterval time.Duration - ellipticCurves []dtlsElliptic.Curve - connectContextMaker func() (context.Context, func()) - extendedMasterSecret dtls.ExtendedMasterSecretType - clientAuth *dtls.ClientAuthType - clientCAs *x509.CertPool - rootCAs *x509.CertPool - } - sctp struct { - maxReceiveBufferSize uint32 - } - sdpMediaLevelFingerprints bool - answeringDTLSRole DTLSRole - disableCertificateFingerprintVerification bool - disableSRTPReplayProtection bool - disableSRTCPReplayProtection bool - net transport.Net - BufferFactory func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser - LoggerFactory logging.LoggerFactory - iceTCPMux ice.TCPMux - iceUDPMux ice.UDPMux - iceProxyDialer proxy.Dialer - disableMediaEngineCopy bool - srtpProtectionProfiles []dtls.SRTPProtectionProfile - receiveMTU uint -} - -// getReceiveMTU returns the configured MTU. If SettingEngine's MTU is configured to 0 it returns the default -func (e *SettingEngine) getReceiveMTU() uint { - if e.receiveMTU != 0 { - return e.receiveMTU - } - - return receiveMTU -} - -// DetachDataChannels enables detaching data channels. When enabled -// data channels have to be detached in the OnOpen callback using the -// DataChannel.Detach method. -func (e *SettingEngine) DetachDataChannels() { - e.detach.DataChannels = true -} - -// SetSRTPProtectionProfiles allows the user to override the default SRTP Protection Profiles -// The default srtp protection profiles are provided by the function `defaultSrtpProtectionProfiles` -func (e *SettingEngine) SetSRTPProtectionProfiles(profiles ...dtls.SRTPProtectionProfile) { - e.srtpProtectionProfiles = profiles -} - -// SetICETimeouts sets the behavior around ICE Timeouts -// -// disconnectedTimeout: -// -// Duration without network activity before an Agent is considered disconnected. Default is 5 Seconds -// -// failedTimeout: -// -// Duration without network activity before an Agent is considered failed after disconnected. Default is 25 Seconds -// -// keepAliveInterval: -// -// How often the ICE Agent sends extra traffic if there is no activity, if media is flowing no traffic will be sent. Default is 2 seconds -func (e *SettingEngine) SetICETimeouts(disconnectedTimeout, failedTimeout, keepAliveInterval time.Duration) { - e.timeout.ICEDisconnectedTimeout = &disconnectedTimeout - e.timeout.ICEFailedTimeout = &failedTimeout - e.timeout.ICEKeepaliveInterval = &keepAliveInterval -} - -// SetHostAcceptanceMinWait sets the ICEHostAcceptanceMinWait -func (e *SettingEngine) SetHostAcceptanceMinWait(t time.Duration) { - e.timeout.ICEHostAcceptanceMinWait = &t -} - -// SetSrflxAcceptanceMinWait sets the ICESrflxAcceptanceMinWait -func (e *SettingEngine) SetSrflxAcceptanceMinWait(t time.Duration) { - e.timeout.ICESrflxAcceptanceMinWait = &t -} - -// SetPrflxAcceptanceMinWait sets the ICEPrflxAcceptanceMinWait -func (e *SettingEngine) SetPrflxAcceptanceMinWait(t time.Duration) { - e.timeout.ICEPrflxAcceptanceMinWait = &t -} - -// SetRelayAcceptanceMinWait sets the ICERelayAcceptanceMinWait -func (e *SettingEngine) SetRelayAcceptanceMinWait(t time.Duration) { - e.timeout.ICERelayAcceptanceMinWait = &t -} - -// SetEphemeralUDPPortRange limits the pool of ephemeral ports that -// ICE UDP connections can allocate from. This affects both host candidates, -// and the local address of server reflexive candidates. -// -// When portMin and portMax are left to the 0 default value, pion/ice candidate -// gatherer replaces them and uses 1 for portMin and 65535 for portMax. -func (e *SettingEngine) SetEphemeralUDPPortRange(portMin, portMax uint16) error { - if portMax < portMin { - return ice.ErrPort - } - - e.ephemeralUDP.PortMin = portMin - e.ephemeralUDP.PortMax = portMax - return nil -} - -// SetLite configures whether or not the ice agent should be a lite agent -func (e *SettingEngine) SetLite(lite bool) { - e.candidates.ICELite = lite -} - -// SetNetworkTypes configures what types of candidate networks are supported -// during local and server reflexive gathering. -func (e *SettingEngine) SetNetworkTypes(candidateTypes []NetworkType) { - e.candidates.ICENetworkTypes = candidateTypes -} - -// SetInterfaceFilter sets the filtering functions when gathering ICE candidates -// This can be used to exclude certain network interfaces from ICE. Which may be -// useful if you know a certain interface will never succeed, or if you wish to reduce -// the amount of information you wish to expose to the remote peer -func (e *SettingEngine) SetInterfaceFilter(filter func(string) bool) { - e.candidates.InterfaceFilter = filter -} - -// SetIPFilter sets the filtering functions when gathering ICE candidates -// This can be used to exclude certain ip from ICE. Which may be -// useful if you know a certain ip will never succeed, or if you wish to reduce -// the amount of information you wish to expose to the remote peer -func (e *SettingEngine) SetIPFilter(filter func(net.IP) bool) { - e.candidates.IPFilter = filter -} - -// SetNAT1To1IPs sets a list of external IP addresses of 1:1 (D)NAT -// and a candidate type for which the external IP address is used. -// This is useful when you host a server using Pion on an AWS EC2 instance -// which has a private address, behind a 1:1 DNAT with a public IP (e.g. -// Elastic IP). In this case, you can give the public IP address so that -// Pion will use the public IP address in its candidate instead of the private -// IP address. The second argument, candidateType, is used to tell Pion which -// type of candidate should use the given public IP address. -// Two types of candidates are supported: -// -// ICECandidateTypeHost: -// -// The public IP address will be used for the host candidate in the SDP. -// -// ICECandidateTypeSrflx: -// -// A server reflexive candidate with the given public IP address will be added to the SDP. -// -// Please note that if you choose ICECandidateTypeHost, then the private IP address -// won't be advertised with the peer. Also, this option cannot be used along with mDNS. -// -// If you choose ICECandidateTypeSrflx, it simply adds a server reflexive candidate -// with the public IP. The host candidate is still available along with mDNS -// capabilities unaffected. Also, you cannot give STUN server URL at the same time. -// It will result in an error otherwise. -func (e *SettingEngine) SetNAT1To1IPs(ips []string, candidateType ICECandidateType) { - e.candidates.NAT1To1IPs = ips - e.candidates.NAT1To1IPCandidateType = candidateType -} - -// SetIncludeLoopbackCandidate enable pion to gather loopback candidates, it is useful -// for some VM have public IP mapped to loopback interface -func (e *SettingEngine) SetIncludeLoopbackCandidate(include bool) { - e.candidates.IncludeLoopbackCandidate = include -} - -// SetAnsweringDTLSRole sets the DTLS role that is selected when offering -// The DTLS role controls if the WebRTC Client as a client or server. This -// may be useful when interacting with non-compliant clients or debugging issues. -// -// DTLSRoleActive: -// -// Act as DTLS Client, send the ClientHello and starts the handshake -// -// DTLSRolePassive: -// -// Act as DTLS Server, wait for ClientHello -func (e *SettingEngine) SetAnsweringDTLSRole(role DTLSRole) error { - if role != DTLSRoleClient && role != DTLSRoleServer { - return errSettingEngineSetAnsweringDTLSRole - } - - e.answeringDTLSRole = role - return nil -} - -// SetVNet sets the VNet instance that is passed to pion/ice -// -// VNet is a virtual network layer for Pion, allowing users to simulate -// different topologies, latency, loss and jitter. This can be useful for -// learning WebRTC concepts or testing your application in a lab environment -// Deprecated: Please use SetNet() -func (e *SettingEngine) SetVNet(vnet *vnet.Net) { - e.SetNet(vnet) -} - -// SetNet sets the Net instance that is passed to pion/ice -// -// Net is an network interface layer for Pion, allowing users to replace -// Pions network stack with a custom implementation. -func (e *SettingEngine) SetNet(net transport.Net) { - e.net = net -} - -// SetICEMulticastDNSMode controls if pion/ice queries and generates mDNS ICE Candidates -func (e *SettingEngine) SetICEMulticastDNSMode(multicastDNSMode ice.MulticastDNSMode) { - e.candidates.MulticastDNSMode = multicastDNSMode -} - -// SetMulticastDNSHostName sets a static HostName to be used by pion/ice instead of generating one on startup -// -// This should only be used for a single PeerConnection. Having multiple PeerConnections with the same HostName will cause -// undefined behavior -func (e *SettingEngine) SetMulticastDNSHostName(hostName string) { - e.candidates.MulticastDNSHostName = hostName -} - -// SetICECredentials sets a staic uFrag/uPwd to be used by pion/ice -// -// This is useful if you want to do signalless WebRTC session, or having a reproducible environment with static credentials -func (e *SettingEngine) SetICECredentials(usernameFragment, password string) { - e.candidates.UsernameFragment = usernameFragment - e.candidates.Password = password -} - -// DisableCertificateFingerprintVerification disables fingerprint verification after DTLS Handshake has finished -func (e *SettingEngine) DisableCertificateFingerprintVerification(isDisabled bool) { - e.disableCertificateFingerprintVerification = isDisabled -} - -// SetDTLSReplayProtectionWindow sets a replay attack protection window size of DTLS connection. -func (e *SettingEngine) SetDTLSReplayProtectionWindow(n uint) { - e.replayProtection.DTLS = &n -} - -// SetSRTPReplayProtectionWindow sets a replay attack protection window size of SRTP session. -func (e *SettingEngine) SetSRTPReplayProtectionWindow(n uint) { - e.disableSRTPReplayProtection = false - e.replayProtection.SRTP = &n -} - -// SetSRTCPReplayProtectionWindow sets a replay attack protection window size of SRTCP session. -func (e *SettingEngine) SetSRTCPReplayProtectionWindow(n uint) { - e.disableSRTCPReplayProtection = false - e.replayProtection.SRTCP = &n -} - -// DisableSRTPReplayProtection disables SRTP replay protection. -func (e *SettingEngine) DisableSRTPReplayProtection(isDisabled bool) { - e.disableSRTPReplayProtection = isDisabled -} - -// DisableSRTCPReplayProtection disables SRTCP replay protection. -func (e *SettingEngine) DisableSRTCPReplayProtection(isDisabled bool) { - e.disableSRTCPReplayProtection = isDisabled -} - -// SetSDPMediaLevelFingerprints configures the logic for DTLS Fingerprint insertion -// If true, fingerprints will be inserted in the sdp at the fingerprint -// level, instead of the session level. This helps with compatibility with -// some webrtc implementations. -func (e *SettingEngine) SetSDPMediaLevelFingerprints(sdpMediaLevelFingerprints bool) { - e.sdpMediaLevelFingerprints = sdpMediaLevelFingerprints -} - -// SetICETCPMux enables ICE-TCP when set to a non-nil value. Make sure that -// NetworkTypeTCP4 or NetworkTypeTCP6 is enabled as well. -func (e *SettingEngine) SetICETCPMux(tcpMux ice.TCPMux) { - e.iceTCPMux = tcpMux -} - -// SetICEUDPMux allows ICE traffic to come through a single UDP port, drastically -// simplifying deployments where ports will need to be opened/forwarded. -// UDPMux should be started prior to creating PeerConnections. -func (e *SettingEngine) SetICEUDPMux(udpMux ice.UDPMux) { - e.iceUDPMux = udpMux -} - -// SetICEProxyDialer sets the proxy dialer interface based on golang.org/x/net/proxy. -func (e *SettingEngine) SetICEProxyDialer(d proxy.Dialer) { - e.iceProxyDialer = d -} - -// DisableMediaEngineCopy stops the MediaEngine from being copied. This allows a user to modify -// the MediaEngine after the PeerConnection has been constructed. This is useful if you wish to -// modify codecs after signaling. Make sure not to share MediaEngines between PeerConnections. -func (e *SettingEngine) DisableMediaEngineCopy(isDisabled bool) { - e.disableMediaEngineCopy = isDisabled -} - -// SetReceiveMTU sets the size of read buffer that copies incoming packets. This is optional. -// Leave this 0 for the default receiveMTU -func (e *SettingEngine) SetReceiveMTU(receiveMTU uint) { - e.receiveMTU = receiveMTU -} - -// SetDTLSRetransmissionInterval sets the retranmission interval for DTLS. -func (e *SettingEngine) SetDTLSRetransmissionInterval(interval time.Duration) { - e.dtls.retransmissionInterval = interval -} - -// SetDTLSInsecureSkipHelloVerify sets the skip HelloVerify flag for DTLS. -// If true and when acting as DTLS server, will allow client to skip hello verify phase and -// receive ServerHello after initial ClientHello. This will mean faster connect times, -// but will have lower DoS attack resistance. -func (e *SettingEngine) SetDTLSInsecureSkipHelloVerify(skip bool) { - e.dtls.insecureSkipHelloVerify = skip -} - -// SetDTLSDisableInsecureSkipVerify sets the disable skip insecure verify flag for DTLS. -// This controls whether a client verifies the server's certificate chain and host name. -func (e *SettingEngine) SetDTLSDisableInsecureSkipVerify(disable bool) { - e.dtls.disableInsecureSkipVerify = disable -} - -// SetDTLSEllipticCurves sets the elliptic curves for DTLS. -func (e *SettingEngine) SetDTLSEllipticCurves(ellipticCurves ...dtlsElliptic.Curve) { - e.dtls.ellipticCurves = ellipticCurves -} - -// SetDTLSConnectContextMaker sets the context used during the DTLS Handshake. -// It can be used to extend or reduce the timeout on the DTLS Handshake. -// If nil, the default dtls.ConnectContextMaker is used. It can be implemented as following. -// -// func ConnectContextMaker() (context.Context, func()) { -// return context.WithTimeout(context.Background(), 30*time.Second) -// } -func (e *SettingEngine) SetDTLSConnectContextMaker(connectContextMaker func() (context.Context, func())) { - e.dtls.connectContextMaker = connectContextMaker -} - -// SetDTLSExtendedMasterSecret sets the extended master secret type for DTLS. -func (e *SettingEngine) SetDTLSExtendedMasterSecret(extendedMasterSecret dtls.ExtendedMasterSecretType) { - e.dtls.extendedMasterSecret = extendedMasterSecret -} - -// SetDTLSClientAuth sets the client auth type for DTLS. -func (e *SettingEngine) SetDTLSClientAuth(clientAuth dtls.ClientAuthType) { - e.dtls.clientAuth = &clientAuth -} - -// SetDTLSClientCAs sets the client CA certificate pool for DTLS certificate verification. -func (e *SettingEngine) SetDTLSClientCAs(clientCAs *x509.CertPool) { - e.dtls.clientCAs = clientCAs -} - -// SetDTLSRootCAs sets the root CA certificate pool for DTLS certificate verification. -func (e *SettingEngine) SetDTLSRootCAs(rootCAs *x509.CertPool) { - e.dtls.rootCAs = rootCAs -} - -// SetSCTPMaxReceiveBufferSize sets the maximum receive buffer size. -// Leave this 0 for the default maxReceiveBufferSize. -func (e *SettingEngine) SetSCTPMaxReceiveBufferSize(maxReceiveBufferSize uint32) { - e.sctp.maxReceiveBufferSize = maxReceiveBufferSize -} diff --git a/vendor/github.com/pion/webrtc/v3/settingengine_js.go b/vendor/github.com/pion/webrtc/v3/settingengine_js.go deleted file mode 100644 index 0069d04e..00000000 --- a/vendor/github.com/pion/webrtc/v3/settingengine_js.go +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build js && wasm -// +build js,wasm - -package webrtc - -// SettingEngine allows influencing behavior in ways that are not -// supported by the WebRTC API. This allows us to support additional -// use-cases without deviating from the WebRTC API elsewhere. -type SettingEngine struct { - detach struct { - DataChannels bool - } -} - -// DetachDataChannels enables detaching data channels. When enabled -// data channels have to be detached in the OnOpen callback using the -// DataChannel.Detach method. -func (e *SettingEngine) DetachDataChannels() { - e.detach.DataChannels = true -} diff --git a/vendor/github.com/pion/webrtc/v3/signalingstate.go b/vendor/github.com/pion/webrtc/v3/signalingstate.go deleted file mode 100644 index 42911c9a..00000000 --- a/vendor/github.com/pion/webrtc/v3/signalingstate.go +++ /dev/null @@ -1,191 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "fmt" - "sync/atomic" - - "github.com/pion/webrtc/v3/pkg/rtcerr" -) - -type stateChangeOp int - -const ( - stateChangeOpSetLocal stateChangeOp = iota + 1 - stateChangeOpSetRemote -) - -func (op stateChangeOp) String() string { - switch op { - case stateChangeOpSetLocal: - return "SetLocal" - case stateChangeOpSetRemote: - return "SetRemote" - default: - return "Unknown State Change Operation" - } -} - -// SignalingState indicates the signaling state of the offer/answer process. -type SignalingState int32 - -const ( - // SignalingStateStable indicates there is no offer/answer exchange in - // progress. This is also the initial state, in which case the local and - // remote descriptions are nil. - SignalingStateStable SignalingState = iota + 1 - - // SignalingStateHaveLocalOffer indicates that a local description, of - // type "offer", has been successfully applied. - SignalingStateHaveLocalOffer - - // SignalingStateHaveRemoteOffer indicates that a remote description, of - // type "offer", has been successfully applied. - SignalingStateHaveRemoteOffer - - // SignalingStateHaveLocalPranswer indicates that a remote description - // of type "offer" has been successfully applied and a local description - // of type "pranswer" has been successfully applied. - SignalingStateHaveLocalPranswer - - // SignalingStateHaveRemotePranswer indicates that a local description - // of type "offer" has been successfully applied and a remote description - // of type "pranswer" has been successfully applied. - SignalingStateHaveRemotePranswer - - // SignalingStateClosed indicates The PeerConnection has been closed. - SignalingStateClosed -) - -// This is done this way because of a linter. -const ( - signalingStateStableStr = "stable" - signalingStateHaveLocalOfferStr = "have-local-offer" - signalingStateHaveRemoteOfferStr = "have-remote-offer" - signalingStateHaveLocalPranswerStr = "have-local-pranswer" - signalingStateHaveRemotePranswerStr = "have-remote-pranswer" - signalingStateClosedStr = "closed" -) - -func newSignalingState(raw string) SignalingState { - switch raw { - case signalingStateStableStr: - return SignalingStateStable - case signalingStateHaveLocalOfferStr: - return SignalingStateHaveLocalOffer - case signalingStateHaveRemoteOfferStr: - return SignalingStateHaveRemoteOffer - case signalingStateHaveLocalPranswerStr: - return SignalingStateHaveLocalPranswer - case signalingStateHaveRemotePranswerStr: - return SignalingStateHaveRemotePranswer - case signalingStateClosedStr: - return SignalingStateClosed - default: - return SignalingState(Unknown) - } -} - -func (t SignalingState) String() string { - switch t { - case SignalingStateStable: - return signalingStateStableStr - case SignalingStateHaveLocalOffer: - return signalingStateHaveLocalOfferStr - case SignalingStateHaveRemoteOffer: - return signalingStateHaveRemoteOfferStr - case SignalingStateHaveLocalPranswer: - return signalingStateHaveLocalPranswerStr - case SignalingStateHaveRemotePranswer: - return signalingStateHaveRemotePranswerStr - case SignalingStateClosed: - return signalingStateClosedStr - default: - return ErrUnknownType.Error() - } -} - -// Get thread safe read value -func (t *SignalingState) Get() SignalingState { - return SignalingState(atomic.LoadInt32((*int32)(t))) -} - -// Set thread safe write value -func (t *SignalingState) Set(state SignalingState) { - atomic.StoreInt32((*int32)(t), int32(state)) -} - -func checkNextSignalingState(cur, next SignalingState, op stateChangeOp, sdpType SDPType) (SignalingState, error) { // nolint:gocognit - // Special case for rollbacks - if sdpType == SDPTypeRollback && cur == SignalingStateStable { - return cur, &rtcerr.InvalidModificationError{ - Err: errSignalingStateCannotRollback, - } - } - - // 4.3.1 valid state transitions - switch cur { // nolint:exhaustive - case SignalingStateStable: - switch op { - case stateChangeOpSetLocal: - // stable->SetLocal(offer)->have-local-offer - if sdpType == SDPTypeOffer && next == SignalingStateHaveLocalOffer { - return next, nil - } - case stateChangeOpSetRemote: - // stable->SetRemote(offer)->have-remote-offer - if sdpType == SDPTypeOffer && next == SignalingStateHaveRemoteOffer { - return next, nil - } - } - case SignalingStateHaveLocalOffer: - if op == stateChangeOpSetRemote { - switch sdpType { // nolint:exhaustive - // have-local-offer->SetRemote(answer)->stable - case SDPTypeAnswer: - if next == SignalingStateStable { - return next, nil - } - // have-local-offer->SetRemote(pranswer)->have-remote-pranswer - case SDPTypePranswer: - if next == SignalingStateHaveRemotePranswer { - return next, nil - } - } - } - case SignalingStateHaveRemotePranswer: - if op == stateChangeOpSetRemote && sdpType == SDPTypeAnswer { - // have-remote-pranswer->SetRemote(answer)->stable - if next == SignalingStateStable { - return next, nil - } - } - case SignalingStateHaveRemoteOffer: - if op == stateChangeOpSetLocal { - switch sdpType { // nolint:exhaustive - // have-remote-offer->SetLocal(answer)->stable - case SDPTypeAnswer: - if next == SignalingStateStable { - return next, nil - } - // have-remote-offer->SetLocal(pranswer)->have-local-pranswer - case SDPTypePranswer: - if next == SignalingStateHaveLocalPranswer { - return next, nil - } - } - } - case SignalingStateHaveLocalPranswer: - if op == stateChangeOpSetLocal && sdpType == SDPTypeAnswer { - // have-local-pranswer->SetLocal(answer)->stable - if next == SignalingStateStable { - return next, nil - } - } - } - return cur, &rtcerr.InvalidModificationError{ - Err: fmt.Errorf("%w: %s->%s(%s)->%s", errSignalingStateProposedTransitionInvalid, cur, op, sdpType, next), - } -} diff --git a/vendor/github.com/pion/webrtc/v3/srtp_writer_future.go b/vendor/github.com/pion/webrtc/v3/srtp_writer_future.go deleted file mode 100644 index 6855e8d3..00000000 --- a/vendor/github.com/pion/webrtc/v3/srtp_writer_future.go +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "io" - "sync" - "sync/atomic" - "time" - - "github.com/pion/rtp" - "github.com/pion/srtp/v2" -) - -// srtpWriterFuture blocks Read/Write calls until -// the SRTP Session is available -type srtpWriterFuture struct { - ssrc SSRC - rtpSender *RTPSender - rtcpReadStream atomic.Value // *srtp.ReadStreamSRTCP - rtpWriteStream atomic.Value // *srtp.WriteStreamSRTP - mu sync.Mutex - closed bool -} - -func (s *srtpWriterFuture) init(returnWhenNoSRTP bool) error { - if returnWhenNoSRTP { - select { - case <-s.rtpSender.stopCalled: - return io.ErrClosedPipe - case <-s.rtpSender.transport.srtpReady: - default: - return nil - } - } else { - select { - case <-s.rtpSender.stopCalled: - return io.ErrClosedPipe - case <-s.rtpSender.transport.srtpReady: - } - } - - s.mu.Lock() - defer s.mu.Unlock() - - if s.closed { - return io.ErrClosedPipe - } - - srtcpSession, err := s.rtpSender.transport.getSRTCPSession() - if err != nil { - return err - } - - rtcpReadStream, err := srtcpSession.OpenReadStream(uint32(s.ssrc)) - if err != nil { - return err - } - - srtpSession, err := s.rtpSender.transport.getSRTPSession() - if err != nil { - return err - } - - rtpWriteStream, err := srtpSession.OpenWriteStream() - if err != nil { - return err - } - - s.rtcpReadStream.Store(rtcpReadStream) - s.rtpWriteStream.Store(rtpWriteStream) - return nil -} - -func (s *srtpWriterFuture) Close() error { - s.mu.Lock() - defer s.mu.Unlock() - - if s.closed { - return nil - } - s.closed = true - - if value, ok := s.rtcpReadStream.Load().(*srtp.ReadStreamSRTCP); ok { - return value.Close() - } - - return nil -} - -func (s *srtpWriterFuture) Read(b []byte) (n int, err error) { - if value, ok := s.rtcpReadStream.Load().(*srtp.ReadStreamSRTCP); ok { - return value.Read(b) - } - - if err := s.init(false); err != nil || s.rtcpReadStream.Load() == nil { - return 0, err - } - - return s.Read(b) -} - -func (s *srtpWriterFuture) SetReadDeadline(t time.Time) error { - if value, ok := s.rtcpReadStream.Load().(*srtp.ReadStreamSRTCP); ok { - return value.SetReadDeadline(t) - } - - if err := s.init(false); err != nil || s.rtcpReadStream.Load() == nil { - return err - } - - return s.SetReadDeadline(t) -} - -func (s *srtpWriterFuture) WriteRTP(header *rtp.Header, payload []byte) (int, error) { - if value, ok := s.rtpWriteStream.Load().(*srtp.WriteStreamSRTP); ok { - return value.WriteRTP(header, payload) - } - - if err := s.init(true); err != nil || s.rtpWriteStream.Load() == nil { - return 0, err - } - - return s.WriteRTP(header, payload) -} - -func (s *srtpWriterFuture) Write(b []byte) (int, error) { - if value, ok := s.rtpWriteStream.Load().(*srtp.WriteStreamSRTP); ok { - return value.Write(b) - } - - if err := s.init(true); err != nil || s.rtpWriteStream.Load() == nil { - return 0, err - } - - return s.Write(b) -} diff --git a/vendor/github.com/pion/webrtc/v3/stats.go b/vendor/github.com/pion/webrtc/v3/stats.go deleted file mode 100644 index 5a43cb72..00000000 --- a/vendor/github.com/pion/webrtc/v3/stats.go +++ /dev/null @@ -1,1455 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "fmt" - "sync" - "time" - - "github.com/pion/ice/v2" -) - -// A Stats object contains a set of statistics copies out of a monitored component -// of the WebRTC stack at a specific time. -type Stats interface{} - -// StatsType indicates the type of the object that a Stats object represents. -type StatsType string - -const ( - // StatsTypeCodec is used by CodecStats. - StatsTypeCodec StatsType = "codec" - - // StatsTypeInboundRTP is used by InboundRTPStreamStats. - StatsTypeInboundRTP StatsType = "inbound-rtp" - - // StatsTypeOutboundRTP is used by OutboundRTPStreamStats. - StatsTypeOutboundRTP StatsType = "outbound-rtp" - - // StatsTypeRemoteInboundRTP is used by RemoteInboundRTPStreamStats. - StatsTypeRemoteInboundRTP StatsType = "remote-inbound-rtp" - - // StatsTypeRemoteOutboundRTP is used by RemoteOutboundRTPStreamStats. - StatsTypeRemoteOutboundRTP StatsType = "remote-outbound-rtp" - - // StatsTypeCSRC is used by RTPContributingSourceStats. - StatsTypeCSRC StatsType = "csrc" - - // StatsTypePeerConnection used by PeerConnectionStats. - StatsTypePeerConnection StatsType = "peer-connection" - - // StatsTypeDataChannel is used by DataChannelStats. - StatsTypeDataChannel StatsType = "data-channel" - - // StatsTypeStream is used by MediaStreamStats. - StatsTypeStream StatsType = "stream" - - // StatsTypeTrack is used by SenderVideoTrackAttachmentStats and SenderAudioTrackAttachmentStats. - StatsTypeTrack StatsType = "track" - - // StatsTypeSender is used by by the AudioSenderStats or VideoSenderStats depending on kind. - StatsTypeSender StatsType = "sender" - - // StatsTypeReceiver is used by the AudioReceiverStats or VideoReceiverStats depending on kind. - StatsTypeReceiver StatsType = "receiver" - - // StatsTypeTransport is used by TransportStats. - StatsTypeTransport StatsType = "transport" - - // StatsTypeCandidatePair is used by ICECandidatePairStats. - StatsTypeCandidatePair StatsType = "candidate-pair" - - // StatsTypeLocalCandidate is used by ICECandidateStats for the local candidate. - StatsTypeLocalCandidate StatsType = "local-candidate" - - // StatsTypeRemoteCandidate is used by ICECandidateStats for the remote candidate. - StatsTypeRemoteCandidate StatsType = "remote-candidate" - - // StatsTypeCertificate is used by CertificateStats. - StatsTypeCertificate StatsType = "certificate" -) - -// StatsTimestamp is a timestamp represented by the floating point number of -// milliseconds since the epoch. -type StatsTimestamp float64 - -// Time returns the time.Time represented by this timestamp. -func (s StatsTimestamp) Time() time.Time { - millis := float64(s) - nanos := int64(millis * float64(time.Millisecond)) - - return time.Unix(0, nanos).UTC() -} - -func statsTimestampFrom(t time.Time) StatsTimestamp { - return StatsTimestamp(t.UnixNano() / int64(time.Millisecond)) -} - -func statsTimestampNow() StatsTimestamp { - return statsTimestampFrom(time.Now()) -} - -// StatsReport collects Stats objects indexed by their ID. -type StatsReport map[string]Stats - -type statsReportCollector struct { - collectingGroup sync.WaitGroup - report StatsReport - mux sync.Mutex -} - -func newStatsReportCollector() *statsReportCollector { - return &statsReportCollector{report: make(StatsReport)} -} - -func (src *statsReportCollector) Collecting() { - src.collectingGroup.Add(1) -} - -func (src *statsReportCollector) Collect(id string, stats Stats) { - src.mux.Lock() - defer src.mux.Unlock() - - src.report[id] = stats - src.collectingGroup.Done() -} - -func (src *statsReportCollector) Done() { - src.collectingGroup.Done() -} - -func (src *statsReportCollector) Ready() StatsReport { - src.collectingGroup.Wait() - src.mux.Lock() - defer src.mux.Unlock() - return src.report -} - -// CodecType specifies whether a CodecStats objects represents a media format -// that is being encoded or decoded -type CodecType string - -const ( - // CodecTypeEncode means the attached CodecStats represents a media format that - // is being encoded, or that the implementation is prepared to encode. - CodecTypeEncode CodecType = "encode" - - // CodecTypeDecode means the attached CodecStats represents a media format - // that the implementation is prepared to decode. - CodecTypeDecode CodecType = "decode" -) - -// CodecStats contains statistics for a codec that is currently being used by RTP streams -// being sent or received by this PeerConnection object. -type CodecStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // PayloadType as used in RTP encoding or decoding - PayloadType PayloadType `json:"payloadType"` - - // CodecType of this CodecStats - CodecType CodecType `json:"codecType"` - - // TransportID is the unique identifier of the transport on which this codec is - // being used, which can be used to look up the corresponding TransportStats object. - TransportID string `json:"transportId"` - - // MimeType is the codec MIME media type/subtype. e.g., video/vp8 or equivalent. - MimeType string `json:"mimeType"` - - // ClockRate represents the media sampling rate. - ClockRate uint32 `json:"clockRate"` - - // Channels is 2 for stereo, missing for most other cases. - Channels uint8 `json:"channels"` - - // SDPFmtpLine is the a=fmtp line in the SDP corresponding to the codec, - // i.e., after the colon following the PT. - SDPFmtpLine string `json:"sdpFmtpLine"` - - // Implementation identifies the implementation used. This is useful for diagnosing - // interoperability issues. - Implementation string `json:"implementation"` -} - -// InboundRTPStreamStats contains statistics for an inbound RTP stream that is -// currently received with this PeerConnection object. -type InboundRTPStreamStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // SSRC is the 32-bit unsigned integer value used to identify the source of the - // stream of RTP packets that this stats object concerns. - SSRC SSRC `json:"ssrc"` - - // Kind is either "audio" or "video" - Kind string `json:"kind"` - - // It is a unique identifier that is associated to the object that was inspected - // to produce the TransportStats associated with this RTP stream. - TransportID string `json:"transportId"` - - // CodecID is a unique identifier that is associated to the object that was inspected - // to produce the CodecStats associated with this RTP stream. - CodecID string `json:"codecId"` - - // FIRCount counts the total number of Full Intra Request (FIR) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - FIRCount uint32 `json:"firCount"` - - // PLICount counts the total number of Picture Loss Indication (PLI) packets - // received by the sender. This metric is only valid for video and is sent by receiver. - PLICount uint32 `json:"pliCount"` - - // NACKCount counts the total number of Negative ACKnowledgement (NACK) packets - // received by the sender and is sent by receiver. - NACKCount uint32 `json:"nackCount"` - - // SLICount counts the total number of Slice Loss Indication (SLI) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - SLICount uint32 `json:"sliCount"` - - // QPSum is the sum of the QP values of frames passed. The count of frames is - // in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats. - QPSum uint64 `json:"qpSum"` - - // PacketsReceived is the total number of RTP packets received for this SSRC. - PacketsReceived uint32 `json:"packetsReceived"` - - // PacketsLost is the total number of RTP packets lost for this SSRC. Note that - // because of how this is estimated, it can be negative if more packets are received than sent. - PacketsLost int32 `json:"packetsLost"` - - // Jitter is the packet jitter measured in seconds for this SSRC - Jitter float64 `json:"jitter"` - - // PacketsDiscarded is the cumulative number of RTP packets discarded by the jitter - // buffer due to late or early-arrival, i.e., these packets are not played out. - // RTP packets discarded due to packet duplication are not reported in this metric. - PacketsDiscarded uint32 `json:"packetsDiscarded"` - - // PacketsRepaired is the cumulative number of lost RTP packets repaired after applying - // an error-resilience mechanism. It is measured for the primary source RTP packets - // and only counted for RTP packets that have no further chance of repair. - PacketsRepaired uint32 `json:"packetsRepaired"` - - // BurstPacketsLost is the cumulative number of RTP packets lost during loss bursts. - BurstPacketsLost uint32 `json:"burstPacketsLost"` - - // BurstPacketsDiscarded is the cumulative number of RTP packets discarded during discard bursts. - BurstPacketsDiscarded uint32 `json:"burstPacketsDiscarded"` - - // BurstLossCount is the cumulative number of bursts of lost RTP packets. - BurstLossCount uint32 `json:"burstLossCount"` - - // BurstDiscardCount is the cumulative number of bursts of discarded RTP packets. - BurstDiscardCount uint32 `json:"burstDiscardCount"` - - // BurstLossRate is the fraction of RTP packets lost during bursts to the - // total number of RTP packets expected in the bursts. - BurstLossRate float64 `json:"burstLossRate"` - - // BurstDiscardRate is the fraction of RTP packets discarded during bursts to - // the total number of RTP packets expected in bursts. - BurstDiscardRate float64 `json:"burstDiscardRate"` - - // GapLossRate is the fraction of RTP packets lost during the gap periods. - GapLossRate float64 `json:"gapLossRate"` - - // GapDiscardRate is the fraction of RTP packets discarded during the gap periods. - GapDiscardRate float64 `json:"gapDiscardRate"` - - // TrackID is the identifier of the stats object representing the receiving track, - // a ReceiverAudioTrackAttachmentStats or ReceiverVideoTrackAttachmentStats. - TrackID string `json:"trackId"` - - // ReceiverID is the stats ID used to look up the AudioReceiverStats or VideoReceiverStats - // object receiving this stream. - ReceiverID string `json:"receiverId"` - - // RemoteID is used for looking up the remote RemoteOutboundRTPStreamStats object - // for the same SSRC. - RemoteID string `json:"remoteId"` - - // FramesDecoded represents the total number of frames correctly decoded for this SSRC, - // i.e., frames that would be displayed if no frames are dropped. Only valid for video. - FramesDecoded uint32 `json:"framesDecoded"` - - // LastPacketReceivedTimestamp represents the timestamp at which the last packet was - // received for this SSRC. This differs from Timestamp, which represents the time - // at which the statistics were generated by the local endpoint. - LastPacketReceivedTimestamp StatsTimestamp `json:"lastPacketReceivedTimestamp"` - - // AverageRTCPInterval is the average RTCP interval between two consecutive compound RTCP packets. - // This is calculated by the sending endpoint when sending compound RTCP reports. - // Compound packets must contain at least a RTCP RR or SR packet and an SDES packet - // with the CNAME item. - AverageRTCPInterval float64 `json:"averageRtcpInterval"` - - // FECPacketsReceived is the total number of RTP FEC packets received for this SSRC. - // This counter can also be incremented when receiving FEC packets in-band with media packets (e.g., with Opus). - FECPacketsReceived uint32 `json:"fecPacketsReceived"` - - // BytesReceived is the total number of bytes received for this SSRC. - BytesReceived uint64 `json:"bytesReceived"` - - // PacketsFailedDecryption is the cumulative number of RTP packets that failed - // to be decrypted. These packets are not counted by PacketsDiscarded. - PacketsFailedDecryption uint32 `json:"packetsFailedDecryption"` - - // PacketsDuplicated is the cumulative number of packets discarded because they - // are duplicated. Duplicate packets are not counted in PacketsDiscarded. - // - // Duplicated packets have the same RTP sequence number and content as a previously - // received packet. If multiple duplicates of a packet are received, all of them are counted. - // An improved estimate of lost packets can be calculated by adding PacketsDuplicated to PacketsLost. - PacketsDuplicated uint32 `json:"packetsDuplicated"` - - // PerDSCPPacketsReceived is the total number of packets received for this SSRC, - // per Differentiated Services code point (DSCP) [RFC2474]. DSCPs are identified - // as decimal integers in string form. Note that due to network remapping and bleaching, - // these numbers are not expected to match the numbers seen on sending. Not all - // OSes make this information available. - PerDSCPPacketsReceived map[string]uint32 `json:"perDscpPacketsReceived"` -} - -// QualityLimitationReason lists the reason for limiting the resolution and/or framerate. -// Only valid for video. -type QualityLimitationReason string - -const ( - // QualityLimitationReasonNone means the resolution and/or framerate is not limited. - QualityLimitationReasonNone QualityLimitationReason = "none" - - // QualityLimitationReasonCPU means the resolution and/or framerate is primarily limited due to CPU load. - QualityLimitationReasonCPU QualityLimitationReason = "cpu" - - // QualityLimitationReasonBandwidth means the resolution and/or framerate is primarily limited due to congestion cues during bandwidth estimation. Typical, congestion control algorithms use inter-arrival time, round-trip time, packet or other congestion cues to perform bandwidth estimation. - QualityLimitationReasonBandwidth QualityLimitationReason = "bandwidth" - - // QualityLimitationReasonOther means the resolution and/or framerate is primarily limited for a reason other than the above. - QualityLimitationReasonOther QualityLimitationReason = "other" -) - -// OutboundRTPStreamStats contains statistics for an outbound RTP stream that is -// currently sent with this PeerConnection object. -type OutboundRTPStreamStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // SSRC is the 32-bit unsigned integer value used to identify the source of the - // stream of RTP packets that this stats object concerns. - SSRC SSRC `json:"ssrc"` - - // Kind is either "audio" or "video" - Kind string `json:"kind"` - - // It is a unique identifier that is associated to the object that was inspected - // to produce the TransportStats associated with this RTP stream. - TransportID string `json:"transportId"` - - // CodecID is a unique identifier that is associated to the object that was inspected - // to produce the CodecStats associated with this RTP stream. - CodecID string `json:"codecId"` - - // FIRCount counts the total number of Full Intra Request (FIR) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - FIRCount uint32 `json:"firCount"` - - // PLICount counts the total number of Picture Loss Indication (PLI) packets - // received by the sender. This metric is only valid for video and is sent by receiver. - PLICount uint32 `json:"pliCount"` - - // NACKCount counts the total number of Negative ACKnowledgement (NACK) packets - // received by the sender and is sent by receiver. - NACKCount uint32 `json:"nackCount"` - - // SLICount counts the total number of Slice Loss Indication (SLI) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - SLICount uint32 `json:"sliCount"` - - // QPSum is the sum of the QP values of frames passed. The count of frames is - // in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats. - QPSum uint64 `json:"qpSum"` - - // PacketsSent is the total number of RTP packets sent for this SSRC. - PacketsSent uint32 `json:"packetsSent"` - - // PacketsDiscardedOnSend is the total number of RTP packets for this SSRC that - // have been discarded due to socket errors, i.e. a socket error occurred when handing - // the packets to the socket. This might happen due to various reasons, including - // full buffer or no available memory. - PacketsDiscardedOnSend uint32 `json:"packetsDiscardedOnSend"` - - // FECPacketsSent is the total number of RTP FEC packets sent for this SSRC. - // This counter can also be incremented when sending FEC packets in-band with - // media packets (e.g., with Opus). - FECPacketsSent uint32 `json:"fecPacketsSent"` - - // BytesSent is the total number of bytes sent for this SSRC. - BytesSent uint64 `json:"bytesSent"` - - // BytesDiscardedOnSend is the total number of bytes for this SSRC that have - // been discarded due to socket errors, i.e. a socket error occurred when handing - // the packets containing the bytes to the socket. This might happen due to various - // reasons, including full buffer or no available memory. - BytesDiscardedOnSend uint64 `json:"bytesDiscardedOnSend"` - - // TrackID is the identifier of the stats object representing the current track - // attachment to the sender of this stream, a SenderAudioTrackAttachmentStats - // or SenderVideoTrackAttachmentStats. - TrackID string `json:"trackId"` - - // SenderID is the stats ID used to look up the AudioSenderStats or VideoSenderStats - // object sending this stream. - SenderID string `json:"senderId"` - - // RemoteID is used for looking up the remote RemoteInboundRTPStreamStats object - // for the same SSRC. - RemoteID string `json:"remoteId"` - - // LastPacketSentTimestamp represents the timestamp at which the last packet was - // sent for this SSRC. This differs from timestamp, which represents the time at - // which the statistics were generated by the local endpoint. - LastPacketSentTimestamp StatsTimestamp `json:"lastPacketSentTimestamp"` - - // TargetBitrate is the current target bitrate configured for this particular SSRC - // and is the Transport Independent Application Specific (TIAS) bitrate [RFC3890]. - // Typically, the target bitrate is a configuration parameter provided to the codec's - // encoder and does not count the size of the IP or other transport layers like TCP or UDP. - // It is measured in bits per second and the bitrate is calculated over a 1 second window. - TargetBitrate float64 `json:"targetBitrate"` - - // FramesEncoded represents the total number of frames successfully encoded for this RTP media stream. - // Only valid for video. - FramesEncoded uint32 `json:"framesEncoded"` - - // TotalEncodeTime is the total number of seconds that has been spent encoding the - // framesEncoded frames of this stream. The average encode time can be calculated by - // dividing this value with FramesEncoded. The time it takes to encode one frame is the - // time passed between feeding the encoder a frame and the encoder returning encoded data - // for that frame. This does not include any additional time it may take to packetize the resulting data. - TotalEncodeTime float64 `json:"totalEncodeTime"` - - // AverageRTCPInterval is the average RTCP interval between two consecutive compound RTCP - // packets. This is calculated by the sending endpoint when sending compound RTCP reports. - // Compound packets must contain at least a RTCP RR or SR packet and an SDES packet with the CNAME item. - AverageRTCPInterval float64 `json:"averageRtcpInterval"` - - // QualityLimitationReason is the current reason for limiting the resolution and/or framerate, - // or "none" if not limited. Only valid for video. - QualityLimitationReason QualityLimitationReason `json:"qualityLimitationReason"` - - // QualityLimitationDurations is record of the total time, in seconds, that this - // stream has spent in each quality limitation state. The record includes a mapping - // for all QualityLimitationReason types, including "none". Only valid for video. - QualityLimitationDurations map[string]float64 `json:"qualityLimitationDurations"` - - // PerDSCPPacketsSent is the total number of packets sent for this SSRC, per DSCP. - // DSCPs are identified as decimal integers in string form. - PerDSCPPacketsSent map[string]uint32 `json:"perDscpPacketsSent"` -} - -// RemoteInboundRTPStreamStats contains statistics for the remote endpoint's inbound -// RTP stream corresponding to an outbound stream that is currently sent with this -// PeerConnection object. It is measured at the remote endpoint and reported in an RTCP -// Receiver Report (RR) or RTCP Extended Report (XR). -type RemoteInboundRTPStreamStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // SSRC is the 32-bit unsigned integer value used to identify the source of the - // stream of RTP packets that this stats object concerns. - SSRC SSRC `json:"ssrc"` - - // Kind is either "audio" or "video" - Kind string `json:"kind"` - - // It is a unique identifier that is associated to the object that was inspected - // to produce the TransportStats associated with this RTP stream. - TransportID string `json:"transportId"` - - // CodecID is a unique identifier that is associated to the object that was inspected - // to produce the CodecStats associated with this RTP stream. - CodecID string `json:"codecId"` - - // FIRCount counts the total number of Full Intra Request (FIR) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - FIRCount uint32 `json:"firCount"` - - // PLICount counts the total number of Picture Loss Indication (PLI) packets - // received by the sender. This metric is only valid for video and is sent by receiver. - PLICount uint32 `json:"pliCount"` - - // NACKCount counts the total number of Negative ACKnowledgement (NACK) packets - // received by the sender and is sent by receiver. - NACKCount uint32 `json:"nackCount"` - - // SLICount counts the total number of Slice Loss Indication (SLI) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - SLICount uint32 `json:"sliCount"` - - // QPSum is the sum of the QP values of frames passed. The count of frames is - // in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats. - QPSum uint64 `json:"qpSum"` - - // PacketsReceived is the total number of RTP packets received for this SSRC. - PacketsReceived uint32 `json:"packetsReceived"` - - // PacketsLost is the total number of RTP packets lost for this SSRC. Note that - // because of how this is estimated, it can be negative if more packets are received than sent. - PacketsLost int32 `json:"packetsLost"` - - // Jitter is the packet jitter measured in seconds for this SSRC - Jitter float64 `json:"jitter"` - - // PacketsDiscarded is the cumulative number of RTP packets discarded by the jitter - // buffer due to late or early-arrival, i.e., these packets are not played out. - // RTP packets discarded due to packet duplication are not reported in this metric. - PacketsDiscarded uint32 `json:"packetsDiscarded"` - - // PacketsRepaired is the cumulative number of lost RTP packets repaired after applying - // an error-resilience mechanism. It is measured for the primary source RTP packets - // and only counted for RTP packets that have no further chance of repair. - PacketsRepaired uint32 `json:"packetsRepaired"` - - // BurstPacketsLost is the cumulative number of RTP packets lost during loss bursts. - BurstPacketsLost uint32 `json:"burstPacketsLost"` - - // BurstPacketsDiscarded is the cumulative number of RTP packets discarded during discard bursts. - BurstPacketsDiscarded uint32 `json:"burstPacketsDiscarded"` - - // BurstLossCount is the cumulative number of bursts of lost RTP packets. - BurstLossCount uint32 `json:"burstLossCount"` - - // BurstDiscardCount is the cumulative number of bursts of discarded RTP packets. - BurstDiscardCount uint32 `json:"burstDiscardCount"` - - // BurstLossRate is the fraction of RTP packets lost during bursts to the - // total number of RTP packets expected in the bursts. - BurstLossRate float64 `json:"burstLossRate"` - - // BurstDiscardRate is the fraction of RTP packets discarded during bursts to - // the total number of RTP packets expected in bursts. - BurstDiscardRate float64 `json:"burstDiscardRate"` - - // GapLossRate is the fraction of RTP packets lost during the gap periods. - GapLossRate float64 `json:"gapLossRate"` - - // GapDiscardRate is the fraction of RTP packets discarded during the gap periods. - GapDiscardRate float64 `json:"gapDiscardRate"` - - // LocalID is used for looking up the local OutboundRTPStreamStats object for the same SSRC. - LocalID string `json:"localId"` - - // RoundTripTime is the estimated round trip time for this SSRC based on the - // RTCP timestamps in the RTCP Receiver Report (RR) and measured in seconds. - RoundTripTime float64 `json:"roundTripTime"` - - // FractionLost is the the fraction packet loss reported for this SSRC. - FractionLost float64 `json:"fractionLost"` -} - -// RemoteOutboundRTPStreamStats contains statistics for the remote endpoint's outbound -// RTP stream corresponding to an inbound stream that is currently received with this -// PeerConnection object. It is measured at the remote endpoint and reported in an -// RTCP Sender Report (SR). -type RemoteOutboundRTPStreamStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // SSRC is the 32-bit unsigned integer value used to identify the source of the - // stream of RTP packets that this stats object concerns. - SSRC SSRC `json:"ssrc"` - - // Kind is either "audio" or "video" - Kind string `json:"kind"` - - // It is a unique identifier that is associated to the object that was inspected - // to produce the TransportStats associated with this RTP stream. - TransportID string `json:"transportId"` - - // CodecID is a unique identifier that is associated to the object that was inspected - // to produce the CodecStats associated with this RTP stream. - CodecID string `json:"codecId"` - - // FIRCount counts the total number of Full Intra Request (FIR) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - FIRCount uint32 `json:"firCount"` - - // PLICount counts the total number of Picture Loss Indication (PLI) packets - // received by the sender. This metric is only valid for video and is sent by receiver. - PLICount uint32 `json:"pliCount"` - - // NACKCount counts the total number of Negative ACKnowledgement (NACK) packets - // received by the sender and is sent by receiver. - NACKCount uint32 `json:"nackCount"` - - // SLICount counts the total number of Slice Loss Indication (SLI) packets received - // by the sender. This metric is only valid for video and is sent by receiver. - SLICount uint32 `json:"sliCount"` - - // QPSum is the sum of the QP values of frames passed. The count of frames is - // in FramesDecoded for inbound stream stats, and in FramesEncoded for outbound stream stats. - QPSum uint64 `json:"qpSum"` - - // PacketsSent is the total number of RTP packets sent for this SSRC. - PacketsSent uint32 `json:"packetsSent"` - - // PacketsDiscardedOnSend is the total number of RTP packets for this SSRC that - // have been discarded due to socket errors, i.e. a socket error occurred when handing - // the packets to the socket. This might happen due to various reasons, including - // full buffer or no available memory. - PacketsDiscardedOnSend uint32 `json:"packetsDiscardedOnSend"` - - // FECPacketsSent is the total number of RTP FEC packets sent for this SSRC. - // This counter can also be incremented when sending FEC packets in-band with - // media packets (e.g., with Opus). - FECPacketsSent uint32 `json:"fecPacketsSent"` - - // BytesSent is the total number of bytes sent for this SSRC. - BytesSent uint64 `json:"bytesSent"` - - // BytesDiscardedOnSend is the total number of bytes for this SSRC that have - // been discarded due to socket errors, i.e. a socket error occurred when handing - // the packets containing the bytes to the socket. This might happen due to various - // reasons, including full buffer or no available memory. - BytesDiscardedOnSend uint64 `json:"bytesDiscardedOnSend"` - - // LocalID is used for looking up the local InboundRTPStreamStats object for the same SSRC. - LocalID string `json:"localId"` - - // RemoteTimestamp represents the remote timestamp at which these statistics were - // sent by the remote endpoint. This differs from timestamp, which represents the - // time at which the statistics were generated or received by the local endpoint. - // The RemoteTimestamp, if present, is derived from the NTP timestamp in an RTCP - // Sender Report (SR) packet, which reflects the remote endpoint's clock. - // That clock may not be synchronized with the local clock. - RemoteTimestamp StatsTimestamp `json:"remoteTimestamp"` -} - -// RTPContributingSourceStats contains statistics for a contributing source (CSRC) that contributed -// to an inbound RTP stream. -type RTPContributingSourceStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // ContributorSSRC is the SSRC identifier of the contributing source represented - // by this stats object. It is a 32-bit unsigned integer that appears in the CSRC - // list of any packets the relevant source contributed to. - ContributorSSRC SSRC `json:"contributorSsrc"` - - // InboundRTPStreamID is the ID of the InboundRTPStreamStats object representing - // the inbound RTP stream that this contributing source is contributing to. - InboundRTPStreamID string `json:"inboundRtpStreamId"` - - // PacketsContributedTo is the total number of RTP packets that this contributing - // source contributed to. This value is incremented each time a packet is counted - // by InboundRTPStreamStats.packetsReceived, and the packet's CSRC list contains - // the SSRC identifier of this contributing source, ContributorSSRC. - PacketsContributedTo uint32 `json:"packetsContributedTo"` - - // AudioLevel is present if the last received RTP packet that this source contributed - // to contained an [RFC6465] mixer-to-client audio level header extension. The value - // of audioLevel is between 0..1 (linear), where 1.0 represents 0 dBov, 0 represents - // silence, and 0.5 represents approximately 6 dBSPL change in the sound pressure level from 0 dBov. - AudioLevel float64 `json:"audioLevel"` -} - -// PeerConnectionStats contains statistics related to the PeerConnection object. -type PeerConnectionStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // DataChannelsOpened represents the number of unique DataChannels that have - // entered the "open" state during their lifetime. - DataChannelsOpened uint32 `json:"dataChannelsOpened"` - - // DataChannelsClosed represents the number of unique DataChannels that have - // left the "open" state during their lifetime (due to being closed by either - // end or the underlying transport being closed). DataChannels that transition - // from "connecting" to "closing" or "closed" without ever being "open" - // are not counted in this number. - DataChannelsClosed uint32 `json:"dataChannelsClosed"` - - // DataChannelsRequested Represents the number of unique DataChannels returned - // from a successful createDataChannel() call on the PeerConnection. If the - // underlying data transport is not established, these may be in the "connecting" state. - DataChannelsRequested uint32 `json:"dataChannelsRequested"` - - // DataChannelsAccepted represents the number of unique DataChannels signaled - // in a "datachannel" event on the PeerConnection. - DataChannelsAccepted uint32 `json:"dataChannelsAccepted"` -} - -// DataChannelStats contains statistics related to each DataChannel ID. -type DataChannelStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // Label is the "label" value of the DataChannel object. - Label string `json:"label"` - - // Protocol is the "protocol" value of the DataChannel object. - Protocol string `json:"protocol"` - - // DataChannelIdentifier is the "id" attribute of the DataChannel object. - DataChannelIdentifier int32 `json:"dataChannelIdentifier"` - - // TransportID the ID of the TransportStats object for transport used to carry this datachannel. - TransportID string `json:"transportId"` - - // State is the "readyState" value of the DataChannel object. - State DataChannelState `json:"state"` - - // MessagesSent represents the total number of API "message" events sent. - MessagesSent uint32 `json:"messagesSent"` - - // BytesSent represents the total number of payload bytes sent on this - // datachannel not including headers or padding. - BytesSent uint64 `json:"bytesSent"` - - // MessagesReceived represents the total number of API "message" events received. - MessagesReceived uint32 `json:"messagesReceived"` - - // BytesReceived represents the total number of bytes received on this - // datachannel not including headers or padding. - BytesReceived uint64 `json:"bytesReceived"` -} - -// MediaStreamStats contains statistics related to a specific MediaStream. -type MediaStreamStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // StreamIdentifier is the "id" property of the MediaStream - StreamIdentifier string `json:"streamIdentifier"` - - // TrackIDs is a list of the identifiers of the stats object representing the - // stream's tracks, either ReceiverAudioTrackAttachmentStats or ReceiverVideoTrackAttachmentStats. - TrackIDs []string `json:"trackIds"` -} - -// AudioSenderStats represents the stats about one audio sender of a PeerConnection -// object for which one calls GetStats. -// -// It appears in the stats as soon as the RTPSender is added by either AddTrack -// or AddTransceiver, or by media negotiation. -type AudioSenderStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // TrackIdentifier represents the id property of the track. - TrackIdentifier string `json:"trackIdentifier"` - - // RemoteSource is true if the source is remote, for instance if it is sourced - // from another host via a PeerConnection. False otherwise. Only applicable for 'track' stats. - RemoteSource bool `json:"remoteSource"` - - // Ended reflects the "ended" state of the track. - Ended bool `json:"ended"` - - // Kind is either "audio" or "video". This reflects the "kind" attribute of the MediaStreamTrack. - Kind string `json:"kind"` - - // AudioLevel represents the output audio level of the track. - // - // The value is a value between 0..1 (linear), where 1.0 represents 0 dBov, - // 0 represents silence, and 0.5 represents approximately 6 dBSPL change in - // the sound pressure level from 0 dBov. - // - // If the track is sourced from an Receiver, does no audio processing, has a - // constant level, and has a volume setting of 1.0, the audio level is expected - // to be the same as the audio level of the source SSRC, while if the volume setting - // is 0.5, the AudioLevel is expected to be half that value. - // - // For outgoing audio tracks, the AudioLevel is the level of the audio being sent. - AudioLevel float64 `json:"audioLevel"` - - // TotalAudioEnergy is the total energy of all the audio samples sent/received - // for this object, calculated by duration * Math.pow(energy/maxEnergy, 2) for - // each audio sample seen. - TotalAudioEnergy float64 `json:"totalAudioEnergy"` - - // VoiceActivityFlag represents whether the last RTP packet sent or played out - // by this track contained voice activity or not based on the presence of the - // V bit in the extension header, as defined in [RFC6464]. - // - // This value indicates the voice activity in the latest RTP packet played out - // from a given SSRC, and is defined in RTPSynchronizationSource.voiceActivityFlag. - VoiceActivityFlag bool `json:"voiceActivityFlag"` - - // TotalSamplesDuration represents the total duration in seconds of all samples - // that have sent or received (and thus counted by TotalSamplesSent or TotalSamplesReceived). - // Can be used with TotalAudioEnergy to compute an average audio level over different intervals. - TotalSamplesDuration float64 `json:"totalSamplesDuration"` - - // EchoReturnLoss is only present while the sender is sending a track sourced from - // a microphone where echo cancellation is applied. Calculated in decibels. - EchoReturnLoss float64 `json:"echoReturnLoss"` - - // EchoReturnLossEnhancement is only present while the sender is sending a track - // sourced from a microphone where echo cancellation is applied. Calculated in decibels. - EchoReturnLossEnhancement float64 `json:"echoReturnLossEnhancement"` - - // TotalSamplesSent is the total number of samples that have been sent by this sender. - TotalSamplesSent uint64 `json:"totalSamplesSent"` -} - -// SenderAudioTrackAttachmentStats object represents the stats about one attachment -// of an audio MediaStreamTrack to the PeerConnection object for which one calls GetStats. -// -// It appears in the stats as soon as it is attached (via AddTrack, via AddTransceiver, -// via ReplaceTrack on an RTPSender object). -// -// If an audio track is attached twice (via AddTransceiver or ReplaceTrack), there -// will be two SenderAudioTrackAttachmentStats objects, one for each attachment. -// They will have the same "TrackIdentifier" attribute, but different "ID" attributes. -// -// If the track is detached from the PeerConnection (via removeTrack or via replaceTrack), -// it continues to appear, but with the "ObjectDeleted" member set to true. -type SenderAudioTrackAttachmentStats AudioSenderStats - -// VideoSenderStats represents the stats about one video sender of a PeerConnection -// object for which one calls GetStats. -// -// It appears in the stats as soon as the sender is added by either AddTrack or -// AddTransceiver, or by media negotiation. -type VideoSenderStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // FramesCaptured represents the total number of frames captured, before encoding, - // for this RTPSender (or for this MediaStreamTrack, if type is "track"). For example, - // if type is "sender" and this sender's track represents a camera, then this is the - // number of frames produced by the camera for this track while being sent by this sender, - // combined with the number of frames produced by all tracks previously attached to this - // sender while being sent by this sender. Framerates can vary due to hardware limitations - // or environmental factors such as lighting conditions. - FramesCaptured uint32 `json:"framesCaptured"` - - // FramesSent represents the total number of frames sent by this RTPSender - // (or for this MediaStreamTrack, if type is "track"). - FramesSent uint32 `json:"framesSent"` - - // HugeFramesSent represents the total number of huge frames sent by this RTPSender - // (or for this MediaStreamTrack, if type is "track"). Huge frames, by definition, - // are frames that have an encoded size at least 2.5 times the average size of the frames. - // The average size of the frames is defined as the target bitrate per second divided - // by the target fps at the time the frame was encoded. These are usually complex - // to encode frames with a lot of changes in the picture. This can be used to estimate, - // e.g slide changes in the streamed presentation. If a huge frame is also a key frame, - // then both counters HugeFramesSent and KeyFramesSent are incremented. - HugeFramesSent uint32 `json:"hugeFramesSent"` - - // KeyFramesSent represents the total number of key frames sent by this RTPSender - // (or for this MediaStreamTrack, if type is "track"), such as Infra-frames in - // VP8 [RFC6386] or I-frames in H.264 [RFC6184]. This is a subset of FramesSent. - // FramesSent - KeyFramesSent gives you the number of delta frames sent. - KeyFramesSent uint32 `json:"keyFramesSent"` -} - -// SenderVideoTrackAttachmentStats represents the stats about one attachment of a -// video MediaStreamTrack to the PeerConnection object for which one calls GetStats. -// -// It appears in the stats as soon as it is attached (via AddTrack, via AddTransceiver, -// via ReplaceTrack on an RTPSender object). -// -// If a video track is attached twice (via AddTransceiver or ReplaceTrack), there -// will be two SenderVideoTrackAttachmentStats objects, one for each attachment. -// They will have the same "TrackIdentifier" attribute, but different "ID" attributes. -// -// If the track is detached from the PeerConnection (via RemoveTrack or via ReplaceTrack), -// it continues to appear, but with the "ObjectDeleted" member set to true. -type SenderVideoTrackAttachmentStats VideoSenderStats - -// AudioReceiverStats contains audio metrics related to a specific receiver. -type AudioReceiverStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // AudioLevel represents the output audio level of the track. - // - // The value is a value between 0..1 (linear), where 1.0 represents 0 dBov, - // 0 represents silence, and 0.5 represents approximately 6 dBSPL change in - // the sound pressure level from 0 dBov. - // - // If the track is sourced from an Receiver, does no audio processing, has a - // constant level, and has a volume setting of 1.0, the audio level is expected - // to be the same as the audio level of the source SSRC, while if the volume setting - // is 0.5, the AudioLevel is expected to be half that value. - // - // For outgoing audio tracks, the AudioLevel is the level of the audio being sent. - AudioLevel float64 `json:"audioLevel"` - - // TotalAudioEnergy is the total energy of all the audio samples sent/received - // for this object, calculated by duration * Math.pow(energy/maxEnergy, 2) for - // each audio sample seen. - TotalAudioEnergy float64 `json:"totalAudioEnergy"` - - // VoiceActivityFlag represents whether the last RTP packet sent or played out - // by this track contained voice activity or not based on the presence of the - // V bit in the extension header, as defined in [RFC6464]. - // - // This value indicates the voice activity in the latest RTP packet played out - // from a given SSRC, and is defined in RTPSynchronizationSource.voiceActivityFlag. - VoiceActivityFlag bool `json:"voiceActivityFlag"` - - // TotalSamplesDuration represents the total duration in seconds of all samples - // that have sent or received (and thus counted by TotalSamplesSent or TotalSamplesReceived). - // Can be used with TotalAudioEnergy to compute an average audio level over different intervals. - TotalSamplesDuration float64 `json:"totalSamplesDuration"` - - // EstimatedPlayoutTimestamp is the estimated playout time of this receiver's - // track. The playout time is the NTP timestamp of the last playable sample that - // has a known timestamp (from an RTCP SR packet mapping RTP timestamps to NTP - // timestamps), extrapolated with the time elapsed since it was ready to be played out. - // This is the "current time" of the track in NTP clock time of the sender and - // can be present even if there is no audio currently playing. - // - // This can be useful for estimating how much audio and video is out of - // sync for two tracks from the same source: - // AudioTrackStats.EstimatedPlayoutTimestamp - VideoTrackStats.EstimatedPlayoutTimestamp - EstimatedPlayoutTimestamp StatsTimestamp `json:"estimatedPlayoutTimestamp"` - - // JitterBufferDelay is the sum of the time, in seconds, each sample takes from - // the time it is received and to the time it exits the jitter buffer. - // This increases upon samples exiting, having completed their time in the buffer - // (incrementing JitterBufferEmittedCount). The average jitter buffer delay can - // be calculated by dividing the JitterBufferDelay with the JitterBufferEmittedCount. - JitterBufferDelay float64 `json:"jitterBufferDelay"` - - // JitterBufferEmittedCount is the total number of samples that have come out - // of the jitter buffer (increasing JitterBufferDelay). - JitterBufferEmittedCount uint64 `json:"jitterBufferEmittedCount"` - - // TotalSamplesReceived is the total number of samples that have been received - // by this receiver. This includes ConcealedSamples. - TotalSamplesReceived uint64 `json:"totalSamplesReceived"` - - // ConcealedSamples is the total number of samples that are concealed samples. - // A concealed sample is a sample that is based on data that was synthesized - // to conceal packet loss and does not represent incoming data. - ConcealedSamples uint64 `json:"concealedSamples"` - - // ConcealmentEvents is the number of concealment events. This counter increases - // every time a concealed sample is synthesized after a non-concealed sample. - // That is, multiple consecutive concealed samples will increase the concealedSamples - // count multiple times but is a single concealment event. - ConcealmentEvents uint64 `json:"concealmentEvents"` -} - -// VideoReceiverStats contains video metrics related to a specific receiver. -type VideoReceiverStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // FrameWidth represents the width of the last processed frame for this track. - // Before the first frame is processed this attribute is missing. - FrameWidth uint32 `json:"frameWidth"` - - // FrameHeight represents the height of the last processed frame for this track. - // Before the first frame is processed this attribute is missing. - FrameHeight uint32 `json:"frameHeight"` - - // FramesPerSecond represents the nominal FPS value before the degradation preference - // is applied. It is the number of complete frames in the last second. For sending - // tracks it is the current captured FPS and for the receiving tracks it is the - // current decoding framerate. - FramesPerSecond float64 `json:"framesPerSecond"` - - // EstimatedPlayoutTimestamp is the estimated playout time of this receiver's - // track. The playout time is the NTP timestamp of the last playable sample that - // has a known timestamp (from an RTCP SR packet mapping RTP timestamps to NTP - // timestamps), extrapolated with the time elapsed since it was ready to be played out. - // This is the "current time" of the track in NTP clock time of the sender and - // can be present even if there is no audio currently playing. - // - // This can be useful for estimating how much audio and video is out of - // sync for two tracks from the same source: - // AudioTrackStats.EstimatedPlayoutTimestamp - VideoTrackStats.EstimatedPlayoutTimestamp - EstimatedPlayoutTimestamp StatsTimestamp `json:"estimatedPlayoutTimestamp"` - - // JitterBufferDelay is the sum of the time, in seconds, each sample takes from - // the time it is received and to the time it exits the jitter buffer. - // This increases upon samples exiting, having completed their time in the buffer - // (incrementing JitterBufferEmittedCount). The average jitter buffer delay can - // be calculated by dividing the JitterBufferDelay with the JitterBufferEmittedCount. - JitterBufferDelay float64 `json:"jitterBufferDelay"` - - // JitterBufferEmittedCount is the total number of samples that have come out - // of the jitter buffer (increasing JitterBufferDelay). - JitterBufferEmittedCount uint64 `json:"jitterBufferEmittedCount"` - - // FramesReceived Represents the total number of complete frames received for - // this receiver. This metric is incremented when the complete frame is received. - FramesReceived uint32 `json:"framesReceived"` - - // KeyFramesReceived represents the total number of complete key frames received - // for this MediaStreamTrack, such as Infra-frames in VP8 [RFC6386] or I-frames - // in H.264 [RFC6184]. This is a subset of framesReceived. `framesReceived - keyFramesReceived` - // gives you the number of delta frames received. This metric is incremented when - // the complete key frame is received. It is not incremented if a partial key - // frames is received and sent for decoding, i.e., the frame could not be recovered - // via retransmission or FEC. - KeyFramesReceived uint32 `json:"keyFramesReceived"` - - // FramesDecoded represents the total number of frames correctly decoded for this - // SSRC, i.e., frames that would be displayed if no frames are dropped. - FramesDecoded uint32 `json:"framesDecoded"` - - // FramesDropped is the total number of frames dropped predecode or dropped - // because the frame missed its display deadline for this receiver's track. - FramesDropped uint32 `json:"framesDropped"` - - // The cumulative number of partial frames lost. This metric is incremented when - // the frame is sent to the decoder. If the partial frame is received and recovered - // via retransmission or FEC before decoding, the FramesReceived counter is incremented. - PartialFramesLost uint32 `json:"partialFramesLost"` - - // FullFramesLost is the cumulative number of full frames lost. - FullFramesLost uint32 `json:"fullFramesLost"` -} - -// TransportStats contains transport statistics related to the PeerConnection object. -type TransportStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // PacketsSent represents the total number of packets sent over this transport. - PacketsSent uint32 `json:"packetsSent"` - - // PacketsReceived represents the total number of packets received on this transport. - PacketsReceived uint32 `json:"packetsReceived"` - - // BytesSent represents the total number of payload bytes sent on this PeerConnection - // not including headers or padding. - BytesSent uint64 `json:"bytesSent"` - - // BytesReceived represents the total number of bytes received on this PeerConnection - // not including headers or padding. - BytesReceived uint64 `json:"bytesReceived"` - - // RTCPTransportStatsID is the ID of the transport that gives stats for the RTCP - // component If RTP and RTCP are not multiplexed and this record has only - // the RTP component stats. - RTCPTransportStatsID string `json:"rtcpTransportStatsId"` - - // ICERole is set to the current value of the "role" attribute of the underlying - // DTLSTransport's "transport". - ICERole ICERole `json:"iceRole"` - - // DTLSState is set to the current value of the "state" attribute of the underlying DTLSTransport. - DTLSState DTLSTransportState `json:"dtlsState"` - - // SelectedCandidatePairID is a unique identifier that is associated to the object - // that was inspected to produce the ICECandidatePairStats associated with this transport. - SelectedCandidatePairID string `json:"selectedCandidatePairId"` - - // LocalCertificateID is the ID of the CertificateStats for the local certificate. - // Present only if DTLS is negotiated. - LocalCertificateID string `json:"localCertificateId"` - - // LocalCertificateID is the ID of the CertificateStats for the remote certificate. - // Present only if DTLS is negotiated. - RemoteCertificateID string `json:"remoteCertificateId"` - - // DTLSCipher is the descriptive name of the cipher suite used for the DTLS transport, - // as defined in the "Description" column of the IANA cipher suite registry. - DTLSCipher string `json:"dtlsCipher"` - - // SRTPCipher is the descriptive name of the protection profile used for the SRTP - // transport, as defined in the "Profile" column of the IANA DTLS-SRTP protection - // profile registry. - SRTPCipher string `json:"srtpCipher"` -} - -// StatsICECandidatePairState is the state of an ICE candidate pair used in the -// ICECandidatePairStats object. -type StatsICECandidatePairState string - -func toStatsICECandidatePairState(state ice.CandidatePairState) (StatsICECandidatePairState, error) { - switch state { - case ice.CandidatePairStateWaiting: - return StatsICECandidatePairStateWaiting, nil - case ice.CandidatePairStateInProgress: - return StatsICECandidatePairStateInProgress, nil - case ice.CandidatePairStateFailed: - return StatsICECandidatePairStateFailed, nil - case ice.CandidatePairStateSucceeded: - return StatsICECandidatePairStateSucceeded, nil - default: - // NOTE: this should never happen[tm] - err := fmt.Errorf("%w: %s", errStatsICECandidateStateInvalid, state.String()) - return StatsICECandidatePairState("Unknown"), err - } -} - -const ( - // StatsICECandidatePairStateFrozen means a check for this pair hasn't been - // performed, and it can't yet be performed until some other check succeeds, - // allowing this pair to unfreeze and move into the Waiting state. - StatsICECandidatePairStateFrozen StatsICECandidatePairState = "frozen" - - // StatsICECandidatePairStateWaiting means a check has not been performed for - // this pair, and can be performed as soon as it is the highest-priority Waiting - // pair on the check list. - StatsICECandidatePairStateWaiting StatsICECandidatePairState = "waiting" - - // StatsICECandidatePairStateInProgress means a check has been sent for this pair, - // but the transaction is in progress. - StatsICECandidatePairStateInProgress StatsICECandidatePairState = "in-progress" - - // StatsICECandidatePairStateFailed means a check for this pair was already done - // and failed, either never producing any response or producing an unrecoverable - // failure response. - StatsICECandidatePairStateFailed StatsICECandidatePairState = "failed" - - // StatsICECandidatePairStateSucceeded means a check for this pair was already - // done and produced a successful result. - StatsICECandidatePairStateSucceeded StatsICECandidatePairState = "succeeded" -) - -// ICECandidatePairStats contains ICE candidate pair statistics related -// to the ICETransport objects. -type ICECandidatePairStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // TransportID is a unique identifier that is associated to the object that - // was inspected to produce the TransportStats associated with this candidate pair. - TransportID string `json:"transportId"` - - // LocalCandidateID is a unique identifier that is associated to the object - // that was inspected to produce the ICECandidateStats for the local candidate - // associated with this candidate pair. - LocalCandidateID string `json:"localCandidateId"` - - // RemoteCandidateID is a unique identifier that is associated to the object - // that was inspected to produce the ICECandidateStats for the remote candidate - // associated with this candidate pair. - RemoteCandidateID string `json:"remoteCandidateId"` - - // State represents the state of the checklist for the local and remote - // candidates in a pair. - State StatsICECandidatePairState `json:"state"` - - // Nominated is true when this valid pair that should be used for media - // if it is the highest-priority one amongst those whose nominated flag is set - Nominated bool `json:"nominated"` - - // PacketsSent represents the total number of packets sent on this candidate pair. - PacketsSent uint32 `json:"packetsSent"` - - // PacketsReceived represents the total number of packets received on this candidate pair. - PacketsReceived uint32 `json:"packetsReceived"` - - // BytesSent represents the total number of payload bytes sent on this candidate pair - // not including headers or padding. - BytesSent uint64 `json:"bytesSent"` - - // BytesReceived represents the total number of payload bytes received on this candidate pair - // not including headers or padding. - BytesReceived uint64 `json:"bytesReceived"` - - // LastPacketSentTimestamp represents the timestamp at which the last packet was - // sent on this particular candidate pair, excluding STUN packets. - LastPacketSentTimestamp StatsTimestamp `json:"lastPacketSentTimestamp"` - - // LastPacketReceivedTimestamp represents the timestamp at which the last packet - // was received on this particular candidate pair, excluding STUN packets. - LastPacketReceivedTimestamp StatsTimestamp `json:"lastPacketReceivedTimestamp"` - - // FirstRequestTimestamp represents the timestamp at which the first STUN request - // was sent on this particular candidate pair. - FirstRequestTimestamp StatsTimestamp `json:"firstRequestTimestamp"` - - // LastRequestTimestamp represents the timestamp at which the last STUN request - // was sent on this particular candidate pair. The average interval between two - // consecutive connectivity checks sent can be calculated with - // (LastRequestTimestamp - FirstRequestTimestamp) / RequestsSent. - LastRequestTimestamp StatsTimestamp `json:"lastRequestTimestamp"` - - // LastResponseTimestamp represents the timestamp at which the last STUN response - // was received on this particular candidate pair. - LastResponseTimestamp StatsTimestamp `json:"lastResponseTimestamp"` - - // TotalRoundTripTime represents the sum of all round trip time measurements - // in seconds since the beginning of the session, based on STUN connectivity - // check responses (ResponsesReceived), including those that reply to requests - // that are sent in order to verify consent. The average round trip time can - // be computed from TotalRoundTripTime by dividing it by ResponsesReceived. - TotalRoundTripTime float64 `json:"totalRoundTripTime"` - - // CurrentRoundTripTime represents the latest round trip time measured in seconds, - // computed from both STUN connectivity checks, including those that are sent - // for consent verification. - CurrentRoundTripTime float64 `json:"currentRoundTripTime"` - - // AvailableOutgoingBitrate is calculated by the underlying congestion control - // by combining the available bitrate for all the outgoing RTP streams using - // this candidate pair. The bitrate measurement does not count the size of the - // IP or other transport layers like TCP or UDP. It is similar to the TIAS defined - // in RFC 3890, i.e., it is measured in bits per second and the bitrate is calculated - // over a 1 second window. - AvailableOutgoingBitrate float64 `json:"availableOutgoingBitrate"` - - // AvailableIncomingBitrate is calculated by the underlying congestion control - // by combining the available bitrate for all the incoming RTP streams using - // this candidate pair. The bitrate measurement does not count the size of the - // IP or other transport layers like TCP or UDP. It is similar to the TIAS defined - // in RFC 3890, i.e., it is measured in bits per second and the bitrate is - // calculated over a 1 second window. - AvailableIncomingBitrate float64 `json:"availableIncomingBitrate"` - - // CircuitBreakerTriggerCount represents the number of times the circuit breaker - // is triggered for this particular 5-tuple, ceasing transmission. - CircuitBreakerTriggerCount uint32 `json:"circuitBreakerTriggerCount"` - - // RequestsReceived represents the total number of connectivity check requests - // received (including retransmissions). It is impossible for the receiver to - // tell whether the request was sent in order to check connectivity or check - // consent, so all connectivity checks requests are counted here. - RequestsReceived uint64 `json:"requestsReceived"` - - // RequestsSent represents the total number of connectivity check requests - // sent (not including retransmissions). - RequestsSent uint64 `json:"requestsSent"` - - // ResponsesReceived represents the total number of connectivity check responses received. - ResponsesReceived uint64 `json:"responsesReceived"` - - // ResponsesSent represents the total number of connectivity check responses sent. - // Since we cannot distinguish connectivity check requests and consent requests, - // all responses are counted. - ResponsesSent uint64 `json:"responsesSent"` - - // RetransmissionsReceived represents the total number of connectivity check - // request retransmissions received. - RetransmissionsReceived uint64 `json:"retransmissionsReceived"` - - // RetransmissionsSent represents the total number of connectivity check - // request retransmissions sent. - RetransmissionsSent uint64 `json:"retransmissionsSent"` - - // ConsentRequestsSent represents the total number of consent requests sent. - ConsentRequestsSent uint64 `json:"consentRequestsSent"` - - // ConsentExpiredTimestamp represents the timestamp at which the latest valid - // STUN binding response expired. - ConsentExpiredTimestamp StatsTimestamp `json:"consentExpiredTimestamp"` -} - -// ICECandidateStats contains ICE candidate statistics related to the ICETransport objects. -type ICECandidateStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // TransportID is a unique identifier that is associated to the object that - // was inspected to produce the TransportStats associated with this candidate. - TransportID string `json:"transportId"` - - // NetworkType represents the type of network interface used by the base of a - // local candidate (the address the ICE agent sends from). Only present for - // local candidates; it's not possible to know what type of network interface - // a remote candidate is using. - // - // Note: - // This stat only tells you about the network interface used by the first "hop"; - // it's possible that a connection will be bottlenecked by another type of network. - // For example, when using Wi-Fi tethering, the networkType of the relevant candidate - // would be "wifi", even when the next hop is over a cellular connection. - NetworkType NetworkType `json:"networkType"` - - // IP is the IP address of the candidate, allowing for IPv4 addresses and - // IPv6 addresses, but fully qualified domain names (FQDNs) are not allowed. - IP string `json:"ip"` - - // Port is the port number of the candidate. - Port int32 `json:"port"` - - // Protocol is one of udp and tcp. - Protocol string `json:"protocol"` - - // CandidateType is the "Type" field of the ICECandidate. - CandidateType ICECandidateType `json:"candidateType"` - - // Priority is the "Priority" field of the ICECandidate. - Priority int32 `json:"priority"` - - // URL is the URL of the TURN or STUN server indicated in the that translated - // this IP address. It is the URL address surfaced in an PeerConnectionICEEvent. - URL string `json:"url"` - - // RelayProtocol is the protocol used by the endpoint to communicate with the - // TURN server. This is only present for local candidates. Valid values for - // the TURN URL protocol is one of udp, tcp, or tls. - RelayProtocol string `json:"relayProtocol"` - - // Deleted is true if the candidate has been deleted/freed. For host candidates, - // this means that any network resources (typically a socket) associated with the - // candidate have been released. For TURN candidates, this means the TURN allocation - // is no longer active. - // - // Only defined for local candidates. For remote candidates, this property is not applicable. - Deleted bool `json:"deleted"` -} - -// CertificateStats contains information about a certificate used by an ICETransport. -type CertificateStats struct { - // Timestamp is the timestamp associated with this object. - Timestamp StatsTimestamp `json:"timestamp"` - - // Type is the object's StatsType - Type StatsType `json:"type"` - - // ID is a unique id that is associated with the component inspected to produce - // this Stats object. Two Stats objects will have the same ID if they were produced - // by inspecting the same underlying object. - ID string `json:"id"` - - // Fingerprint is the fingerprint of the certificate. - Fingerprint string `json:"fingerprint"` - - // FingerprintAlgorithm is the hash function used to compute the certificate fingerprint. For instance, "sha-256". - FingerprintAlgorithm string `json:"fingerprintAlgorithm"` - - // Base64Certificate is the DER-encoded base-64 representation of the certificate. - Base64Certificate string `json:"base64Certificate"` - - // IssuerCertificateID refers to the stats object that contains the next certificate - // in the certificate chain. If the current certificate is at the end of the chain - // (i.e. a self-signed certificate), this will not be set. - IssuerCertificateID string `json:"issuerCertificateId"` -} diff --git a/vendor/github.com/pion/webrtc/v3/stats_go.go b/vendor/github.com/pion/webrtc/v3/stats_go.go deleted file mode 100644 index a9a8e215..00000000 --- a/vendor/github.com/pion/webrtc/v3/stats_go.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -// GetConnectionStats is a helper method to return the associated stats for a given PeerConnection -func (r StatsReport) GetConnectionStats(conn *PeerConnection) (PeerConnectionStats, bool) { - statsID := conn.getStatsID() - stats, ok := r[statsID] - if !ok { - return PeerConnectionStats{}, false - } - - pcStats, ok := stats.(PeerConnectionStats) - if !ok { - return PeerConnectionStats{}, false - } - return pcStats, true -} - -// GetDataChannelStats is a helper method to return the associated stats for a given DataChannel -func (r StatsReport) GetDataChannelStats(dc *DataChannel) (DataChannelStats, bool) { - statsID := dc.getStatsID() - stats, ok := r[statsID] - if !ok { - return DataChannelStats{}, false - } - - dcStats, ok := stats.(DataChannelStats) - if !ok { - return DataChannelStats{}, false - } - return dcStats, true -} - -// GetICECandidateStats is a helper method to return the associated stats for a given ICECandidate -func (r StatsReport) GetICECandidateStats(c *ICECandidate) (ICECandidateStats, bool) { - statsID := c.statsID - stats, ok := r[statsID] - if !ok { - return ICECandidateStats{}, false - } - - candidateStats, ok := stats.(ICECandidateStats) - if !ok { - return ICECandidateStats{}, false - } - return candidateStats, true -} - -// GetICECandidatePairStats is a helper method to return the associated stats for a given ICECandidatePair -func (r StatsReport) GetICECandidatePairStats(c *ICECandidatePair) (ICECandidatePairStats, bool) { - statsID := c.statsID - stats, ok := r[statsID] - if !ok { - return ICECandidatePairStats{}, false - } - - candidateStats, ok := stats.(ICECandidatePairStats) - if !ok { - return ICECandidatePairStats{}, false - } - return candidateStats, true -} - -// GetCertificateStats is a helper method to return the associated stats for a given Certificate -func (r StatsReport) GetCertificateStats(c *Certificate) (CertificateStats, bool) { - statsID := c.statsID - stats, ok := r[statsID] - if !ok { - return CertificateStats{}, false - } - - certificateStats, ok := stats.(CertificateStats) - if !ok { - return CertificateStats{}, false - } - return certificateStats, true -} - -// GetCodecStats is a helper method to return the associated stats for a given Codec -func (r StatsReport) GetCodecStats(c *RTPCodecParameters) (CodecStats, bool) { - statsID := c.statsID - stats, ok := r[statsID] - if !ok { - return CodecStats{}, false - } - - codecStats, ok := stats.(CodecStats) - if !ok { - return CodecStats{}, false - } - return codecStats, true -} diff --git a/vendor/github.com/pion/webrtc/v3/track_local.go b/vendor/github.com/pion/webrtc/v3/track_local.go deleted file mode 100644 index a2e6599a..00000000 --- a/vendor/github.com/pion/webrtc/v3/track_local.go +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package webrtc - -import ( - "github.com/pion/interceptor" - "github.com/pion/rtp" -) - -// TrackLocalWriter is the Writer for outbound RTP Packets -type TrackLocalWriter interface { - // WriteRTP encrypts a RTP packet and writes to the connection - WriteRTP(header *rtp.Header, payload []byte) (int, error) - - // Write encrypts and writes a full RTP packet - Write(b []byte) (int, error) -} - -// TrackLocalContext is the Context passed when a TrackLocal has been Binded/Unbinded from a PeerConnection, and used -// in Interceptors. -type TrackLocalContext struct { - id string - params RTPParameters - ssrc SSRC - writeStream TrackLocalWriter - rtcpInterceptor interceptor.RTCPReader -} - -// CodecParameters returns the negotiated RTPCodecParameters. These are the codecs supported by both -// PeerConnections and the SSRC/PayloadTypes -func (t *TrackLocalContext) CodecParameters() []RTPCodecParameters { - return t.params.Codecs -} - -// HeaderExtensions returns the negotiated RTPHeaderExtensionParameters. These are the header extensions supported by -// both PeerConnections and the SSRC/PayloadTypes -func (t *TrackLocalContext) HeaderExtensions() []RTPHeaderExtensionParameter { - return t.params.HeaderExtensions -} - -// SSRC requires the negotiated SSRC of this track -// This track may have multiple if RTX is enabled -func (t *TrackLocalContext) SSRC() SSRC { - return t.ssrc -} - -// WriteStream returns the WriteStream for this TrackLocal. The implementer writes the outbound -// media packets to it -func (t *TrackLocalContext) WriteStream() TrackLocalWriter { - return t.writeStream -} - -// ID is a unique identifier that is used for both Bind/Unbind -func (t *TrackLocalContext) ID() string { - return t.id -} - -// RTCPReader returns the RTCP interceptor for this TrackLocal. Used to read RTCP of this TrackLocal. -func (t *TrackLocalContext) RTCPReader() interceptor.RTCPReader { - return t.rtcpInterceptor -} - -// TrackLocal is an interface that controls how the user can send media -// The user can provide their own TrackLocal implementations, or use -// the implementations in pkg/media -type TrackLocal interface { - // Bind should implement the way how the media data flows from the Track to the PeerConnection - // This will be called internally after signaling is complete and the list of available - // codecs has been determined - Bind(TrackLocalContext) (RTPCodecParameters, error) - - // Unbind should implement the teardown logic when the track is no longer needed. This happens - // because a track has been stopped. - Unbind(TrackLocalContext) error - - // ID is the unique identifier for this Track. This should be unique for the - // stream, but doesn't have to globally unique. A common example would be 'audio' or 'video' - // and StreamID would be 'desktop' or 'webcam' - ID() string - - // RID is the RTP Stream ID for this track. - RID() string - - // StreamID is the group this track belongs too. This must be unique - StreamID() string - - // Kind controls if this TrackLocal is audio or video - Kind() RTPCodecType -} diff --git a/vendor/github.com/pion/webrtc/v3/track_local_static.go b/vendor/github.com/pion/webrtc/v3/track_local_static.go deleted file mode 100644 index 17ce0587..00000000 --- a/vendor/github.com/pion/webrtc/v3/track_local_static.go +++ /dev/null @@ -1,306 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "strings" - "sync" - - "github.com/pion/rtp" - "github.com/pion/webrtc/v3/internal/util" - "github.com/pion/webrtc/v3/pkg/media" -) - -// trackBinding is a single bind for a Track -// Bind can be called multiple times, this stores the -// result for a single bind call so that it can be used when writing -type trackBinding struct { - id string - ssrc SSRC - payloadType PayloadType - writeStream TrackLocalWriter -} - -// TrackLocalStaticRTP is a TrackLocal that has a pre-set codec and accepts RTP Packets. -// If you wish to send a media.Sample use TrackLocalStaticSample -type TrackLocalStaticRTP struct { - mu sync.RWMutex - bindings []trackBinding - codec RTPCodecCapability - id, rid, streamID string -} - -// NewTrackLocalStaticRTP returns a TrackLocalStaticRTP. -func NewTrackLocalStaticRTP(c RTPCodecCapability, id, streamID string, options ...func(*TrackLocalStaticRTP)) (*TrackLocalStaticRTP, error) { - t := &TrackLocalStaticRTP{ - codec: c, - bindings: []trackBinding{}, - id: id, - streamID: streamID, - } - - for _, option := range options { - option(t) - } - - return t, nil -} - -// WithRTPStreamID sets the RTP stream ID for this TrackLocalStaticRTP. -func WithRTPStreamID(rid string) func(*TrackLocalStaticRTP) { - return func(t *TrackLocalStaticRTP) { - t.rid = rid - } -} - -// Bind is called by the PeerConnection after negotiation is complete -// This asserts that the code requested is supported by the remote peer. -// If so it setups all the state (SSRC and PayloadType) to have a call -func (s *TrackLocalStaticRTP) Bind(t TrackLocalContext) (RTPCodecParameters, error) { - s.mu.Lock() - defer s.mu.Unlock() - - parameters := RTPCodecParameters{RTPCodecCapability: s.codec} - if codec, matchType := codecParametersFuzzySearch(parameters, t.CodecParameters()); matchType != codecMatchNone { - s.bindings = append(s.bindings, trackBinding{ - ssrc: t.SSRC(), - payloadType: codec.PayloadType, - writeStream: t.WriteStream(), - id: t.ID(), - }) - return codec, nil - } - - return RTPCodecParameters{}, ErrUnsupportedCodec -} - -// Unbind implements the teardown logic when the track is no longer needed. This happens -// because a track has been stopped. -func (s *TrackLocalStaticRTP) Unbind(t TrackLocalContext) error { - s.mu.Lock() - defer s.mu.Unlock() - - for i := range s.bindings { - if s.bindings[i].id == t.ID() { - s.bindings[i] = s.bindings[len(s.bindings)-1] - s.bindings = s.bindings[:len(s.bindings)-1] - return nil - } - } - - return ErrUnbindFailed -} - -// ID is the unique identifier for this Track. This should be unique for the -// stream, but doesn't have to globally unique. A common example would be 'audio' or 'video' -// and StreamID would be 'desktop' or 'webcam' -func (s *TrackLocalStaticRTP) ID() string { return s.id } - -// StreamID is the group this track belongs too. This must be unique -func (s *TrackLocalStaticRTP) StreamID() string { return s.streamID } - -// RID is the RTP stream identifier. -func (s *TrackLocalStaticRTP) RID() string { return s.rid } - -// Kind controls if this TrackLocal is audio or video -func (s *TrackLocalStaticRTP) Kind() RTPCodecType { - switch { - case strings.HasPrefix(s.codec.MimeType, "audio/"): - return RTPCodecTypeAudio - case strings.HasPrefix(s.codec.MimeType, "video/"): - return RTPCodecTypeVideo - default: - return RTPCodecType(0) - } -} - -// Codec gets the Codec of the track -func (s *TrackLocalStaticRTP) Codec() RTPCodecCapability { - return s.codec -} - -// packetPool is a pool of packets used by WriteRTP and Write below -// nolint:gochecknoglobals -var rtpPacketPool = sync.Pool{ - New: func() interface{} { - return &rtp.Packet{} - }, -} - -func resetPacketPoolAllocation(localPacket *rtp.Packet) { - *localPacket = rtp.Packet{} - rtpPacketPool.Put(localPacket) -} - -func getPacketAllocationFromPool() *rtp.Packet { - ipacket := rtpPacketPool.Get() - return ipacket.(*rtp.Packet) //nolint:forcetypeassert -} - -// WriteRTP writes a RTP Packet to the TrackLocalStaticRTP -// If one PeerConnection fails the packets will still be sent to -// all PeerConnections. The error message will contain the ID of the failed -// PeerConnections so you can remove them -func (s *TrackLocalStaticRTP) WriteRTP(p *rtp.Packet) error { - packet := getPacketAllocationFromPool() - - defer resetPacketPoolAllocation(packet) - - *packet = *p - - return s.writeRTP(packet) -} - -// writeRTP is like WriteRTP, except that it may modify the packet p -func (s *TrackLocalStaticRTP) writeRTP(p *rtp.Packet) error { - s.mu.RLock() - defer s.mu.RUnlock() - - writeErrs := []error{} - - for _, b := range s.bindings { - p.Header.SSRC = uint32(b.ssrc) - p.Header.PayloadType = uint8(b.payloadType) - if _, err := b.writeStream.WriteRTP(&p.Header, p.Payload); err != nil { - writeErrs = append(writeErrs, err) - } - } - - return util.FlattenErrs(writeErrs) -} - -// Write writes a RTP Packet as a buffer to the TrackLocalStaticRTP -// If one PeerConnection fails the packets will still be sent to -// all PeerConnections. The error message will contain the ID of the failed -// PeerConnections so you can remove them -func (s *TrackLocalStaticRTP) Write(b []byte) (n int, err error) { - packet := getPacketAllocationFromPool() - - defer resetPacketPoolAllocation(packet) - - if err = packet.Unmarshal(b); err != nil { - return 0, err - } - - return len(b), s.writeRTP(packet) -} - -// TrackLocalStaticSample is a TrackLocal that has a pre-set codec and accepts Samples. -// If you wish to send a RTP Packet use TrackLocalStaticRTP -type TrackLocalStaticSample struct { - packetizer rtp.Packetizer - sequencer rtp.Sequencer - rtpTrack *TrackLocalStaticRTP - clockRate float64 -} - -// NewTrackLocalStaticSample returns a TrackLocalStaticSample -func NewTrackLocalStaticSample(c RTPCodecCapability, id, streamID string, options ...func(*TrackLocalStaticRTP)) (*TrackLocalStaticSample, error) { - rtpTrack, err := NewTrackLocalStaticRTP(c, id, streamID, options...) - if err != nil { - return nil, err - } - - return &TrackLocalStaticSample{ - rtpTrack: rtpTrack, - }, nil -} - -// ID is the unique identifier for this Track. This should be unique for the -// stream, but doesn't have to globally unique. A common example would be 'audio' or 'video' -// and StreamID would be 'desktop' or 'webcam' -func (s *TrackLocalStaticSample) ID() string { return s.rtpTrack.ID() } - -// StreamID is the group this track belongs too. This must be unique -func (s *TrackLocalStaticSample) StreamID() string { return s.rtpTrack.StreamID() } - -// RID is the RTP stream identifier. -func (s *TrackLocalStaticSample) RID() string { return s.rtpTrack.RID() } - -// Kind controls if this TrackLocal is audio or video -func (s *TrackLocalStaticSample) Kind() RTPCodecType { return s.rtpTrack.Kind() } - -// Codec gets the Codec of the track -func (s *TrackLocalStaticSample) Codec() RTPCodecCapability { - return s.rtpTrack.Codec() -} - -// Bind is called by the PeerConnection after negotiation is complete -// This asserts that the code requested is supported by the remote peer. -// If so it setups all the state (SSRC and PayloadType) to have a call -func (s *TrackLocalStaticSample) Bind(t TrackLocalContext) (RTPCodecParameters, error) { - codec, err := s.rtpTrack.Bind(t) - if err != nil { - return codec, err - } - - s.rtpTrack.mu.Lock() - defer s.rtpTrack.mu.Unlock() - - // We only need one packetizer - if s.packetizer != nil { - return codec, nil - } - - payloader, err := payloaderForCodec(codec.RTPCodecCapability) - if err != nil { - return codec, err - } - - s.sequencer = rtp.NewRandomSequencer() - s.packetizer = rtp.NewPacketizer( - rtpOutboundMTU, - 0, // Value is handled when writing - 0, // Value is handled when writing - payloader, - s.sequencer, - codec.ClockRate, - ) - s.clockRate = float64(codec.RTPCodecCapability.ClockRate) - return codec, nil -} - -// Unbind implements the teardown logic when the track is no longer needed. This happens -// because a track has been stopped. -func (s *TrackLocalStaticSample) Unbind(t TrackLocalContext) error { - return s.rtpTrack.Unbind(t) -} - -// WriteSample writes a Sample to the TrackLocalStaticSample -// If one PeerConnection fails the packets will still be sent to -// all PeerConnections. The error message will contain the ID of the failed -// PeerConnections so you can remove them -func (s *TrackLocalStaticSample) WriteSample(sample media.Sample) error { - s.rtpTrack.mu.RLock() - p := s.packetizer - clockRate := s.clockRate - s.rtpTrack.mu.RUnlock() - - if p == nil { - return nil - } - - // skip packets by the number of previously dropped packets - for i := uint16(0); i < sample.PrevDroppedPackets; i++ { - s.sequencer.NextSequenceNumber() - } - - samples := uint32(sample.Duration.Seconds() * clockRate) - if sample.PrevDroppedPackets > 0 { - p.SkipSamples(samples * uint32(sample.PrevDroppedPackets)) - } - packets := p.Packetize(sample.Data, samples) - - writeErrs := []error{} - for _, p := range packets { - if err := s.rtpTrack.WriteRTP(p); err != nil { - writeErrs = append(writeErrs, err) - } - } - - return util.FlattenErrs(writeErrs) -} diff --git a/vendor/github.com/pion/webrtc/v3/track_remote.go b/vendor/github.com/pion/webrtc/v3/track_remote.go deleted file mode 100644 index 150b91bc..00000000 --- a/vendor/github.com/pion/webrtc/v3/track_remote.go +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -//go:build !js -// +build !js - -package webrtc - -import ( - "sync" - "time" - - "github.com/pion/interceptor" - "github.com/pion/rtp" -) - -// TrackRemote represents a single inbound source of media -type TrackRemote struct { - mu sync.RWMutex - - id string - streamID string - - payloadType PayloadType - kind RTPCodecType - ssrc SSRC - codec RTPCodecParameters - params RTPParameters - rid string - - receiver *RTPReceiver - peeked []byte - peekedAttributes interceptor.Attributes -} - -func newTrackRemote(kind RTPCodecType, ssrc SSRC, rid string, receiver *RTPReceiver) *TrackRemote { - return &TrackRemote{ - kind: kind, - ssrc: ssrc, - rid: rid, - receiver: receiver, - } -} - -// ID is the unique identifier for this Track. This should be unique for the -// stream, but doesn't have to globally unique. A common example would be 'audio' or 'video' -// and StreamID would be 'desktop' or 'webcam' -func (t *TrackRemote) ID() string { - t.mu.RLock() - defer t.mu.RUnlock() - return t.id -} - -// RID gets the RTP Stream ID of this Track -// With Simulcast you will have multiple tracks with the same ID, but different RID values. -// In many cases a TrackRemote will not have an RID, so it is important to assert it is non-zero -func (t *TrackRemote) RID() string { - t.mu.RLock() - defer t.mu.RUnlock() - - return t.rid -} - -// PayloadType gets the PayloadType of the track -func (t *TrackRemote) PayloadType() PayloadType { - t.mu.RLock() - defer t.mu.RUnlock() - return t.payloadType -} - -// Kind gets the Kind of the track -func (t *TrackRemote) Kind() RTPCodecType { - t.mu.RLock() - defer t.mu.RUnlock() - return t.kind -} - -// StreamID is the group this track belongs too. This must be unique -func (t *TrackRemote) StreamID() string { - t.mu.RLock() - defer t.mu.RUnlock() - return t.streamID -} - -// SSRC gets the SSRC of the track -func (t *TrackRemote) SSRC() SSRC { - t.mu.RLock() - defer t.mu.RUnlock() - return t.ssrc -} - -// Msid gets the Msid of the track -func (t *TrackRemote) Msid() string { - return t.StreamID() + " " + t.ID() -} - -// Codec gets the Codec of the track -func (t *TrackRemote) Codec() RTPCodecParameters { - t.mu.RLock() - defer t.mu.RUnlock() - return t.codec -} - -// Read reads data from the track. -func (t *TrackRemote) Read(b []byte) (n int, attributes interceptor.Attributes, err error) { - t.mu.RLock() - r := t.receiver - peeked := t.peeked != nil - t.mu.RUnlock() - - if peeked { - t.mu.Lock() - data := t.peeked - attributes = t.peekedAttributes - - t.peeked = nil - t.peekedAttributes = nil - t.mu.Unlock() - // someone else may have stolen our packet when we - // released the lock. Deal with it. - if data != nil { - n = copy(b, data) - err = t.checkAndUpdateTrack(b) - return - } - } - - n, attributes, err = r.readRTP(b, t) - if err != nil { - return - } - - err = t.checkAndUpdateTrack(b) - return -} - -// checkAndUpdateTrack checks payloadType for every incoming packet -// once a different payloadType is detected the track will be updated -func (t *TrackRemote) checkAndUpdateTrack(b []byte) error { - if len(b) < 2 { - return errRTPTooShort - } - - if payloadType := PayloadType(b[1] & rtpPayloadTypeBitmask); payloadType != t.PayloadType() { - t.mu.Lock() - defer t.mu.Unlock() - - params, err := t.receiver.api.mediaEngine.getRTPParametersByPayloadType(payloadType) - if err != nil { - return err - } - - t.kind = t.receiver.kind - t.payloadType = payloadType - t.codec = params.Codecs[0] - t.params = params - } - - return nil -} - -// ReadRTP is a convenience method that wraps Read and unmarshals for you. -func (t *TrackRemote) ReadRTP() (*rtp.Packet, interceptor.Attributes, error) { - b := make([]byte, t.receiver.api.settingEngine.getReceiveMTU()) - i, attributes, err := t.Read(b) - if err != nil { - return nil, nil, err - } - - r := &rtp.Packet{} - if err := r.Unmarshal(b[:i]); err != nil { - return nil, nil, err - } - return r, attributes, nil -} - -// peek is like Read, but it doesn't discard the packet read -func (t *TrackRemote) peek(b []byte) (n int, a interceptor.Attributes, err error) { - n, a, err = t.Read(b) - if err != nil { - return - } - - t.mu.Lock() - // this might overwrite data if somebody peeked between the Read - // and us getting the lock. Oh well, we'll just drop a packet in - // that case. - data := make([]byte, n) - n = copy(data, b[:n]) - t.peeked = data - t.peekedAttributes = a - t.mu.Unlock() - return -} - -// SetReadDeadline sets the max amount of time the RTP stream will block before returning. 0 is forever. -func (t *TrackRemote) SetReadDeadline(deadline time.Time) error { - return t.receiver.setRTPReadDeadline(deadline, t) -} diff --git a/vendor/github.com/pion/webrtc/v3/webrtc.go b/vendor/github.com/pion/webrtc/v3/webrtc.go deleted file mode 100644 index 2781c8d1..00000000 --- a/vendor/github.com/pion/webrtc/v3/webrtc.go +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package webrtc implements the WebRTC 1.0 as defined in W3C WebRTC specification document. -package webrtc - -// SSRC represents a synchronization source -// A synchronization source is a randomly chosen -// value meant to be globally unique within a particular -// RTP session. Used to identify a single stream of media. -// -// https://tools.ietf.org/html/rfc3550#section-3 -type SSRC uint32 - -// PayloadType identifies the format of the RTP payload and determines -// its interpretation by the application. Each codec in a RTP Session -// will have a different PayloadType -// -// https://tools.ietf.org/html/rfc3550#section-3 -type PayloadType uint8 diff --git a/vendor/github.com/pion/webrtc/v3/yarn.lock b/vendor/github.com/pion/webrtc/v3/yarn.lock deleted file mode 100644 index 01bf7823..00000000 --- a/vendor/github.com/pion/webrtc/v3/yarn.lock +++ /dev/null @@ -1,797 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - -# SPDX-FileCopyrightText: 2023 The Pion community -# SPDX-License-Identifier: MIT - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -ajv@^6.5.5: - version "6.12.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" - integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" - integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chownr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -debug@^2.1.2: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== - dependencies: - minipass "^2.2.1" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== - dependencies: - minipass "^2.2.1" - -mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== - dependencies: - debug "^2.1.2" - iconv-lite "^0.4.4" - sax "^1.2.4" - -node-pre-gyp@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42" - integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" - integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-tmpdir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== - -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -readable-stream@^2.0.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -request@2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -rimraf@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -safe-buffer@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver@^5.3.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== - -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -wrtc@0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/wrtc/-/wrtc-0.4.7.tgz#c61530cd662713e50bffe64b7a78673ce070426c" - integrity sha512-P6Hn7VT4lfSH49HxLHcHhDq+aFf/jd9dPY7lDHeFhZ22N3858EKuwm2jmnlPzpsRGEPaoF6XwkcxY5SYnt4f/g== - dependencies: - node-pre-gyp "^0.13.0" - optionalDependencies: - domexception "^1.0.1" - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== diff --git a/vendor/github.com/pmezard/go-difflib/LICENSE b/vendor/github.com/pmezard/go-difflib/LICENSE deleted file mode 100644 index c67dad61..00000000 --- a/vendor/github.com/pmezard/go-difflib/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013, Patrick Mezard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - The names of its contributors may not be used to endorse or promote -products derived from this software without specific prior written -permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go deleted file mode 100644 index 003e99fa..00000000 --- a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go +++ /dev/null @@ -1,772 +0,0 @@ -// Package difflib is a partial port of Python difflib module. -// -// It provides tools to compare sequences of strings and generate textual diffs. -// -// The following class and functions have been ported: -// -// - SequenceMatcher -// -// - unified_diff -// -// - context_diff -// -// Getting unified diffs was the main goal of the port. Keep in mind this code -// is mostly suitable to output text differences in a human friendly way, there -// are no guarantees generated diffs are consumable by patch(1). -package difflib - -import ( - "bufio" - "bytes" - "fmt" - "io" - "strings" -) - -func min(a, b int) int { - if a < b { - return a - } - return b -} - -func max(a, b int) int { - if a > b { - return a - } - return b -} - -func calculateRatio(matches, length int) float64 { - if length > 0 { - return 2.0 * float64(matches) / float64(length) - } - return 1.0 -} - -type Match struct { - A int - B int - Size int -} - -type OpCode struct { - Tag byte - I1 int - I2 int - J1 int - J2 int -} - -// SequenceMatcher compares sequence of strings. The basic -// algorithm predates, and is a little fancier than, an algorithm -// published in the late 1980's by Ratcliff and Obershelp under the -// hyperbolic name "gestalt pattern matching". The basic idea is to find -// the longest contiguous matching subsequence that contains no "junk" -// elements (R-O doesn't address junk). The same idea is then applied -// recursively to the pieces of the sequences to the left and to the right -// of the matching subsequence. This does not yield minimal edit -// sequences, but does tend to yield matches that "look right" to people. -// -// SequenceMatcher tries to compute a "human-friendly diff" between two -// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the -// longest *contiguous* & junk-free matching subsequence. That's what -// catches peoples' eyes. The Windows(tm) windiff has another interesting -// notion, pairing up elements that appear uniquely in each sequence. -// That, and the method here, appear to yield more intuitive difference -// reports than does diff. This method appears to be the least vulnerable -// to synching up on blocks of "junk lines", though (like blank lines in -// ordinary text files, or maybe "

" lines in HTML files). That may be -// because this is the only method of the 3 that has a *concept* of -// "junk" . -// -// Timing: Basic R-O is cubic time worst case and quadratic time expected -// case. SequenceMatcher is quadratic time for the worst case and has -// expected-case behavior dependent in a complicated way on how many -// elements the sequences have in common; best case time is linear. -type SequenceMatcher struct { - a []string - b []string - b2j map[string][]int - IsJunk func(string) bool - autoJunk bool - bJunk map[string]struct{} - matchingBlocks []Match - fullBCount map[string]int - bPopular map[string]struct{} - opCodes []OpCode -} - -func NewMatcher(a, b []string) *SequenceMatcher { - m := SequenceMatcher{autoJunk: true} - m.SetSeqs(a, b) - return &m -} - -func NewMatcherWithJunk(a, b []string, autoJunk bool, - isJunk func(string) bool) *SequenceMatcher { - - m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} - m.SetSeqs(a, b) - return &m -} - -// Set two sequences to be compared. -func (m *SequenceMatcher) SetSeqs(a, b []string) { - m.SetSeq1(a) - m.SetSeq2(b) -} - -// Set the first sequence to be compared. The second sequence to be compared is -// not changed. -// -// SequenceMatcher computes and caches detailed information about the second -// sequence, so if you want to compare one sequence S against many sequences, -// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other -// sequences. -// -// See also SetSeqs() and SetSeq2(). -func (m *SequenceMatcher) SetSeq1(a []string) { - if &a == &m.a { - return - } - m.a = a - m.matchingBlocks = nil - m.opCodes = nil -} - -// Set the second sequence to be compared. The first sequence to be compared is -// not changed. -func (m *SequenceMatcher) SetSeq2(b []string) { - if &b == &m.b { - return - } - m.b = b - m.matchingBlocks = nil - m.opCodes = nil - m.fullBCount = nil - m.chainB() -} - -func (m *SequenceMatcher) chainB() { - // Populate line -> index mapping - b2j := map[string][]int{} - for i, s := range m.b { - indices := b2j[s] - indices = append(indices, i) - b2j[s] = indices - } - - // Purge junk elements - m.bJunk = map[string]struct{}{} - if m.IsJunk != nil { - junk := m.bJunk - for s, _ := range b2j { - if m.IsJunk(s) { - junk[s] = struct{}{} - } - } - for s, _ := range junk { - delete(b2j, s) - } - } - - // Purge remaining popular elements - popular := map[string]struct{}{} - n := len(m.b) - if m.autoJunk && n >= 200 { - ntest := n/100 + 1 - for s, indices := range b2j { - if len(indices) > ntest { - popular[s] = struct{}{} - } - } - for s, _ := range popular { - delete(b2j, s) - } - } - m.bPopular = popular - m.b2j = b2j -} - -func (m *SequenceMatcher) isBJunk(s string) bool { - _, ok := m.bJunk[s] - return ok -} - -// Find longest matching block in a[alo:ahi] and b[blo:bhi]. -// -// If IsJunk is not defined: -// -// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where -// alo <= i <= i+k <= ahi -// blo <= j <= j+k <= bhi -// and for all (i',j',k') meeting those conditions, -// k >= k' -// i <= i' -// and if i == i', j <= j' -// -// In other words, of all maximal matching blocks, return one that -// starts earliest in a, and of all those maximal matching blocks that -// start earliest in a, return the one that starts earliest in b. -// -// If IsJunk is defined, first the longest matching block is -// determined as above, but with the additional restriction that no -// junk element appears in the block. Then that block is extended as -// far as possible by matching (only) junk elements on both sides. So -// the resulting block never matches on junk except as identical junk -// happens to be adjacent to an "interesting" match. -// -// If no blocks match, return (alo, blo, 0). -func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { - // CAUTION: stripping common prefix or suffix would be incorrect. - // E.g., - // ab - // acab - // Longest matching block is "ab", but if common prefix is - // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so - // strip, so ends up claiming that ab is changed to acab by - // inserting "ca" in the middle. That's minimal but unintuitive: - // "it's obvious" that someone inserted "ac" at the front. - // Windiff ends up at the same place as diff, but by pairing up - // the unique 'b's and then matching the first two 'a's. - besti, bestj, bestsize := alo, blo, 0 - - // find longest junk-free match - // during an iteration of the loop, j2len[j] = length of longest - // junk-free match ending with a[i-1] and b[j] - j2len := map[int]int{} - for i := alo; i != ahi; i++ { - // look at all instances of a[i] in b; note that because - // b2j has no junk keys, the loop is skipped if a[i] is junk - newj2len := map[int]int{} - for _, j := range m.b2j[m.a[i]] { - // a[i] matches b[j] - if j < blo { - continue - } - if j >= bhi { - break - } - k := j2len[j-1] + 1 - newj2len[j] = k - if k > bestsize { - besti, bestj, bestsize = i-k+1, j-k+1, k - } - } - j2len = newj2len - } - - // Extend the best by non-junk elements on each end. In particular, - // "popular" non-junk elements aren't in b2j, which greatly speeds - // the inner loop above, but also means "the best" match so far - // doesn't contain any junk *or* popular non-junk elements. - for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && - m.a[besti-1] == m.b[bestj-1] { - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - } - for besti+bestsize < ahi && bestj+bestsize < bhi && - !m.isBJunk(m.b[bestj+bestsize]) && - m.a[besti+bestsize] == m.b[bestj+bestsize] { - bestsize += 1 - } - - // Now that we have a wholly interesting match (albeit possibly - // empty!), we may as well suck up the matching junk on each - // side of it too. Can't think of a good reason not to, and it - // saves post-processing the (possibly considerable) expense of - // figuring out what to do with it. In the case of an empty - // interesting match, this is clearly the right thing to do, - // because no other kind of match is possible in the regions. - for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && - m.a[besti-1] == m.b[bestj-1] { - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - } - for besti+bestsize < ahi && bestj+bestsize < bhi && - m.isBJunk(m.b[bestj+bestsize]) && - m.a[besti+bestsize] == m.b[bestj+bestsize] { - bestsize += 1 - } - - return Match{A: besti, B: bestj, Size: bestsize} -} - -// Return list of triples describing matching subsequences. -// -// Each triple is of the form (i, j, n), and means that -// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in -// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are -// adjacent triples in the list, and the second is not the last triple in the -// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe -// adjacent equal blocks. -// -// The last triple is a dummy, (len(a), len(b), 0), and is the only -// triple with n==0. -func (m *SequenceMatcher) GetMatchingBlocks() []Match { - if m.matchingBlocks != nil { - return m.matchingBlocks - } - - var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match - matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { - match := m.findLongestMatch(alo, ahi, blo, bhi) - i, j, k := match.A, match.B, match.Size - if match.Size > 0 { - if alo < i && blo < j { - matched = matchBlocks(alo, i, blo, j, matched) - } - matched = append(matched, match) - if i+k < ahi && j+k < bhi { - matched = matchBlocks(i+k, ahi, j+k, bhi, matched) - } - } - return matched - } - matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) - - // It's possible that we have adjacent equal blocks in the - // matching_blocks list now. - nonAdjacent := []Match{} - i1, j1, k1 := 0, 0, 0 - for _, b := range matched { - // Is this block adjacent to i1, j1, k1? - i2, j2, k2 := b.A, b.B, b.Size - if i1+k1 == i2 && j1+k1 == j2 { - // Yes, so collapse them -- this just increases the length of - // the first block by the length of the second, and the first - // block so lengthened remains the block to compare against. - k1 += k2 - } else { - // Not adjacent. Remember the first block (k1==0 means it's - // the dummy we started with), and make the second block the - // new block to compare against. - if k1 > 0 { - nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) - } - i1, j1, k1 = i2, j2, k2 - } - } - if k1 > 0 { - nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) - } - - nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) - m.matchingBlocks = nonAdjacent - return m.matchingBlocks -} - -// Return list of 5-tuples describing how to turn a into b. -// -// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple -// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the -// tuple preceding it, and likewise for j1 == the previous j2. -// -// The tags are characters, with these meanings: -// -// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] -// -// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. -// -// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. -// -// 'e' (equal): a[i1:i2] == b[j1:j2] -func (m *SequenceMatcher) GetOpCodes() []OpCode { - if m.opCodes != nil { - return m.opCodes - } - i, j := 0, 0 - matching := m.GetMatchingBlocks() - opCodes := make([]OpCode, 0, len(matching)) - for _, m := range matching { - // invariant: we've pumped out correct diffs to change - // a[:i] into b[:j], and the next matching block is - // a[ai:ai+size] == b[bj:bj+size]. So we need to pump - // out a diff to change a[i:ai] into b[j:bj], pump out - // the matching block, and move (i,j) beyond the match - ai, bj, size := m.A, m.B, m.Size - tag := byte(0) - if i < ai && j < bj { - tag = 'r' - } else if i < ai { - tag = 'd' - } else if j < bj { - tag = 'i' - } - if tag > 0 { - opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) - } - i, j = ai+size, bj+size - // the list of matching blocks is terminated by a - // sentinel with size 0 - if size > 0 { - opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) - } - } - m.opCodes = opCodes - return m.opCodes -} - -// Isolate change clusters by eliminating ranges with no changes. -// -// Return a generator of groups with up to n lines of context. -// Each group is in the same format as returned by GetOpCodes(). -func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { - if n < 0 { - n = 3 - } - codes := m.GetOpCodes() - if len(codes) == 0 { - codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} - } - // Fixup leading and trailing groups if they show no changes. - if codes[0].Tag == 'e' { - c := codes[0] - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} - } - if codes[len(codes)-1].Tag == 'e' { - c := codes[len(codes)-1] - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} - } - nn := n + n - groups := [][]OpCode{} - group := []OpCode{} - for _, c := range codes { - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - // End the current group and start a new one whenever - // there is a large range with no changes. - if c.Tag == 'e' && i2-i1 > nn { - group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), - j1, min(j2, j1+n)}) - groups = append(groups, group) - group = []OpCode{} - i1, j1 = max(i1, i2-n), max(j1, j2-n) - } - group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) - } - if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { - groups = append(groups, group) - } - return groups -} - -// Return a measure of the sequences' similarity (float in [0,1]). -// -// Where T is the total number of elements in both sequences, and -// M is the number of matches, this is 2.0*M / T. -// Note that this is 1 if the sequences are identical, and 0 if -// they have nothing in common. -// -// .Ratio() is expensive to compute if you haven't already computed -// .GetMatchingBlocks() or .GetOpCodes(), in which case you may -// want to try .QuickRatio() or .RealQuickRation() first to get an -// upper bound. -func (m *SequenceMatcher) Ratio() float64 { - matches := 0 - for _, m := range m.GetMatchingBlocks() { - matches += m.Size - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() relatively quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute. -func (m *SequenceMatcher) QuickRatio() float64 { - // viewing a and b as multisets, set matches to the cardinality - // of their intersection; this counts the number of matches - // without regard to order, so is clearly an upper bound - if m.fullBCount == nil { - m.fullBCount = map[string]int{} - for _, s := range m.b { - m.fullBCount[s] = m.fullBCount[s] + 1 - } - } - - // avail[x] is the number of times x appears in 'b' less the - // number of times we've seen it in 'a' so far ... kinda - avail := map[string]int{} - matches := 0 - for _, s := range m.a { - n, ok := avail[s] - if !ok { - n = m.fullBCount[s] - } - avail[s] = n - 1 - if n > 0 { - matches += 1 - } - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() very quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute than either .Ratio() or .QuickRatio(). -func (m *SequenceMatcher) RealQuickRatio() float64 { - la, lb := len(m.a), len(m.b) - return calculateRatio(min(la, lb), la+lb) -} - -// Convert range to the "ed" format -func formatRangeUnified(start, stop int) string { - // Per the diff spec at http://www.unix.org/single_unix_specification/ - beginning := start + 1 // lines start numbering with one - length := stop - start - if length == 1 { - return fmt.Sprintf("%d", beginning) - } - if length == 0 { - beginning -= 1 // empty ranges begin at line just before the range - } - return fmt.Sprintf("%d,%d", beginning, length) -} - -// Unified diff parameters -type UnifiedDiff struct { - A []string // First sequence lines - FromFile string // First file name - FromDate string // First file time - B []string // Second sequence lines - ToFile string // Second file name - ToDate string // Second file time - Eol string // Headers end of line, defaults to LF - Context int // Number of context lines -} - -// Compare two sequences of lines; generate the delta as a unified diff. -// -// Unified diffs are a compact way of showing line changes and a few -// lines of context. The number of context lines is set by 'n' which -// defaults to three. -// -// By default, the diff control lines (those with ---, +++, or @@) are -// created with a trailing newline. This is helpful so that inputs -// created from file.readlines() result in diffs that are suitable for -// file.writelines() since both the inputs and outputs have trailing -// newlines. -// -// For inputs that do not have trailing newlines, set the lineterm -// argument to "" so that the output will be uniformly newline free. -// -// The unidiff format normally has a header for filenames and modification -// times. Any or all of these may be specified using strings for -// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. -// The modification times are normally expressed in the ISO 8601 format. -func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { - buf := bufio.NewWriter(writer) - defer buf.Flush() - wf := func(format string, args ...interface{}) error { - _, err := buf.WriteString(fmt.Sprintf(format, args...)) - return err - } - ws := func(s string) error { - _, err := buf.WriteString(s) - return err - } - - if len(diff.Eol) == 0 { - diff.Eol = "\n" - } - - started := false - m := NewMatcher(diff.A, diff.B) - for _, g := range m.GetGroupedOpCodes(diff.Context) { - if !started { - started = true - fromDate := "" - if len(diff.FromDate) > 0 { - fromDate = "\t" + diff.FromDate - } - toDate := "" - if len(diff.ToDate) > 0 { - toDate = "\t" + diff.ToDate - } - if diff.FromFile != "" || diff.ToFile != "" { - err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) - if err != nil { - return err - } - err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) - if err != nil { - return err - } - } - } - first, last := g[0], g[len(g)-1] - range1 := formatRangeUnified(first.I1, last.I2) - range2 := formatRangeUnified(first.J1, last.J2) - if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { - return err - } - for _, c := range g { - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - if c.Tag == 'e' { - for _, line := range diff.A[i1:i2] { - if err := ws(" " + line); err != nil { - return err - } - } - continue - } - if c.Tag == 'r' || c.Tag == 'd' { - for _, line := range diff.A[i1:i2] { - if err := ws("-" + line); err != nil { - return err - } - } - } - if c.Tag == 'r' || c.Tag == 'i' { - for _, line := range diff.B[j1:j2] { - if err := ws("+" + line); err != nil { - return err - } - } - } - } - } - return nil -} - -// Like WriteUnifiedDiff but returns the diff a string. -func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { - w := &bytes.Buffer{} - err := WriteUnifiedDiff(w, diff) - return string(w.Bytes()), err -} - -// Convert range to the "ed" format. -func formatRangeContext(start, stop int) string { - // Per the diff spec at http://www.unix.org/single_unix_specification/ - beginning := start + 1 // lines start numbering with one - length := stop - start - if length == 0 { - beginning -= 1 // empty ranges begin at line just before the range - } - if length <= 1 { - return fmt.Sprintf("%d", beginning) - } - return fmt.Sprintf("%d,%d", beginning, beginning+length-1) -} - -type ContextDiff UnifiedDiff - -// Compare two sequences of lines; generate the delta as a context diff. -// -// Context diffs are a compact way of showing line changes and a few -// lines of context. The number of context lines is set by diff.Context -// which defaults to three. -// -// By default, the diff control lines (those with *** or ---) are -// created with a trailing newline. -// -// For inputs that do not have trailing newlines, set the diff.Eol -// argument to "" so that the output will be uniformly newline free. -// -// The context diff format normally has a header for filenames and -// modification times. Any or all of these may be specified using -// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. -// The modification times are normally expressed in the ISO 8601 format. -// If not specified, the strings default to blanks. -func WriteContextDiff(writer io.Writer, diff ContextDiff) error { - buf := bufio.NewWriter(writer) - defer buf.Flush() - var diffErr error - wf := func(format string, args ...interface{}) { - _, err := buf.WriteString(fmt.Sprintf(format, args...)) - if diffErr == nil && err != nil { - diffErr = err - } - } - ws := func(s string) { - _, err := buf.WriteString(s) - if diffErr == nil && err != nil { - diffErr = err - } - } - - if len(diff.Eol) == 0 { - diff.Eol = "\n" - } - - prefix := map[byte]string{ - 'i': "+ ", - 'd': "- ", - 'r': "! ", - 'e': " ", - } - - started := false - m := NewMatcher(diff.A, diff.B) - for _, g := range m.GetGroupedOpCodes(diff.Context) { - if !started { - started = true - fromDate := "" - if len(diff.FromDate) > 0 { - fromDate = "\t" + diff.FromDate - } - toDate := "" - if len(diff.ToDate) > 0 { - toDate = "\t" + diff.ToDate - } - if diff.FromFile != "" || diff.ToFile != "" { - wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) - wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) - } - } - - first, last := g[0], g[len(g)-1] - ws("***************" + diff.Eol) - - range1 := formatRangeContext(first.I1, last.I2) - wf("*** %s ****%s", range1, diff.Eol) - for _, c := range g { - if c.Tag == 'r' || c.Tag == 'd' { - for _, cc := range g { - if cc.Tag == 'i' { - continue - } - for _, line := range diff.A[cc.I1:cc.I2] { - ws(prefix[cc.Tag] + line) - } - } - break - } - } - - range2 := formatRangeContext(first.J1, last.J2) - wf("--- %s ----%s", range2, diff.Eol) - for _, c := range g { - if c.Tag == 'r' || c.Tag == 'i' { - for _, cc := range g { - if cc.Tag == 'd' { - continue - } - for _, line := range diff.B[cc.J1:cc.J2] { - ws(prefix[cc.Tag] + line) - } - } - break - } - } - } - return diffErr -} - -// Like WriteContextDiff but returns the diff a string. -func GetContextDiffString(diff ContextDiff) (string, error) { - w := &bytes.Buffer{} - err := WriteContextDiff(w, diff) - return string(w.Bytes()), err -} - -// Split a string on "\n" while preserving them. The output can be used -// as input for UnifiedDiff and ContextDiff structures. -func SplitLines(s string) []string { - lines := strings.SplitAfter(s, "\n") - lines[len(lines)-1] += "\n" - return lines -} diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE deleted file mode 100644 index 4b0421cf..00000000 --- a/vendor/github.com/stretchr/testify/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/vendor/github.com/stretchr/testify/assert/assertion_compare.go deleted file mode 100644 index 4d4b4aad..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_compare.go +++ /dev/null @@ -1,480 +0,0 @@ -package assert - -import ( - "bytes" - "fmt" - "reflect" - "time" -) - -type CompareType int - -const ( - compareLess CompareType = iota - 1 - compareEqual - compareGreater -) - -var ( - intType = reflect.TypeOf(int(1)) - int8Type = reflect.TypeOf(int8(1)) - int16Type = reflect.TypeOf(int16(1)) - int32Type = reflect.TypeOf(int32(1)) - int64Type = reflect.TypeOf(int64(1)) - - uintType = reflect.TypeOf(uint(1)) - uint8Type = reflect.TypeOf(uint8(1)) - uint16Type = reflect.TypeOf(uint16(1)) - uint32Type = reflect.TypeOf(uint32(1)) - uint64Type = reflect.TypeOf(uint64(1)) - - uintptrType = reflect.TypeOf(uintptr(1)) - - float32Type = reflect.TypeOf(float32(1)) - float64Type = reflect.TypeOf(float64(1)) - - stringType = reflect.TypeOf("") - - timeType = reflect.TypeOf(time.Time{}) - bytesType = reflect.TypeOf([]byte{}) -) - -func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { - obj1Value := reflect.ValueOf(obj1) - obj2Value := reflect.ValueOf(obj2) - - // throughout this switch we try and avoid calling .Convert() if possible, - // as this has a pretty big performance impact - switch kind { - case reflect.Int: - { - intobj1, ok := obj1.(int) - if !ok { - intobj1 = obj1Value.Convert(intType).Interface().(int) - } - intobj2, ok := obj2.(int) - if !ok { - intobj2 = obj2Value.Convert(intType).Interface().(int) - } - if intobj1 > intobj2 { - return compareGreater, true - } - if intobj1 == intobj2 { - return compareEqual, true - } - if intobj1 < intobj2 { - return compareLess, true - } - } - case reflect.Int8: - { - int8obj1, ok := obj1.(int8) - if !ok { - int8obj1 = obj1Value.Convert(int8Type).Interface().(int8) - } - int8obj2, ok := obj2.(int8) - if !ok { - int8obj2 = obj2Value.Convert(int8Type).Interface().(int8) - } - if int8obj1 > int8obj2 { - return compareGreater, true - } - if int8obj1 == int8obj2 { - return compareEqual, true - } - if int8obj1 < int8obj2 { - return compareLess, true - } - } - case reflect.Int16: - { - int16obj1, ok := obj1.(int16) - if !ok { - int16obj1 = obj1Value.Convert(int16Type).Interface().(int16) - } - int16obj2, ok := obj2.(int16) - if !ok { - int16obj2 = obj2Value.Convert(int16Type).Interface().(int16) - } - if int16obj1 > int16obj2 { - return compareGreater, true - } - if int16obj1 == int16obj2 { - return compareEqual, true - } - if int16obj1 < int16obj2 { - return compareLess, true - } - } - case reflect.Int32: - { - int32obj1, ok := obj1.(int32) - if !ok { - int32obj1 = obj1Value.Convert(int32Type).Interface().(int32) - } - int32obj2, ok := obj2.(int32) - if !ok { - int32obj2 = obj2Value.Convert(int32Type).Interface().(int32) - } - if int32obj1 > int32obj2 { - return compareGreater, true - } - if int32obj1 == int32obj2 { - return compareEqual, true - } - if int32obj1 < int32obj2 { - return compareLess, true - } - } - case reflect.Int64: - { - int64obj1, ok := obj1.(int64) - if !ok { - int64obj1 = obj1Value.Convert(int64Type).Interface().(int64) - } - int64obj2, ok := obj2.(int64) - if !ok { - int64obj2 = obj2Value.Convert(int64Type).Interface().(int64) - } - if int64obj1 > int64obj2 { - return compareGreater, true - } - if int64obj1 == int64obj2 { - return compareEqual, true - } - if int64obj1 < int64obj2 { - return compareLess, true - } - } - case reflect.Uint: - { - uintobj1, ok := obj1.(uint) - if !ok { - uintobj1 = obj1Value.Convert(uintType).Interface().(uint) - } - uintobj2, ok := obj2.(uint) - if !ok { - uintobj2 = obj2Value.Convert(uintType).Interface().(uint) - } - if uintobj1 > uintobj2 { - return compareGreater, true - } - if uintobj1 == uintobj2 { - return compareEqual, true - } - if uintobj1 < uintobj2 { - return compareLess, true - } - } - case reflect.Uint8: - { - uint8obj1, ok := obj1.(uint8) - if !ok { - uint8obj1 = obj1Value.Convert(uint8Type).Interface().(uint8) - } - uint8obj2, ok := obj2.(uint8) - if !ok { - uint8obj2 = obj2Value.Convert(uint8Type).Interface().(uint8) - } - if uint8obj1 > uint8obj2 { - return compareGreater, true - } - if uint8obj1 == uint8obj2 { - return compareEqual, true - } - if uint8obj1 < uint8obj2 { - return compareLess, true - } - } - case reflect.Uint16: - { - uint16obj1, ok := obj1.(uint16) - if !ok { - uint16obj1 = obj1Value.Convert(uint16Type).Interface().(uint16) - } - uint16obj2, ok := obj2.(uint16) - if !ok { - uint16obj2 = obj2Value.Convert(uint16Type).Interface().(uint16) - } - if uint16obj1 > uint16obj2 { - return compareGreater, true - } - if uint16obj1 == uint16obj2 { - return compareEqual, true - } - if uint16obj1 < uint16obj2 { - return compareLess, true - } - } - case reflect.Uint32: - { - uint32obj1, ok := obj1.(uint32) - if !ok { - uint32obj1 = obj1Value.Convert(uint32Type).Interface().(uint32) - } - uint32obj2, ok := obj2.(uint32) - if !ok { - uint32obj2 = obj2Value.Convert(uint32Type).Interface().(uint32) - } - if uint32obj1 > uint32obj2 { - return compareGreater, true - } - if uint32obj1 == uint32obj2 { - return compareEqual, true - } - if uint32obj1 < uint32obj2 { - return compareLess, true - } - } - case reflect.Uint64: - { - uint64obj1, ok := obj1.(uint64) - if !ok { - uint64obj1 = obj1Value.Convert(uint64Type).Interface().(uint64) - } - uint64obj2, ok := obj2.(uint64) - if !ok { - uint64obj2 = obj2Value.Convert(uint64Type).Interface().(uint64) - } - if uint64obj1 > uint64obj2 { - return compareGreater, true - } - if uint64obj1 == uint64obj2 { - return compareEqual, true - } - if uint64obj1 < uint64obj2 { - return compareLess, true - } - } - case reflect.Float32: - { - float32obj1, ok := obj1.(float32) - if !ok { - float32obj1 = obj1Value.Convert(float32Type).Interface().(float32) - } - float32obj2, ok := obj2.(float32) - if !ok { - float32obj2 = obj2Value.Convert(float32Type).Interface().(float32) - } - if float32obj1 > float32obj2 { - return compareGreater, true - } - if float32obj1 == float32obj2 { - return compareEqual, true - } - if float32obj1 < float32obj2 { - return compareLess, true - } - } - case reflect.Float64: - { - float64obj1, ok := obj1.(float64) - if !ok { - float64obj1 = obj1Value.Convert(float64Type).Interface().(float64) - } - float64obj2, ok := obj2.(float64) - if !ok { - float64obj2 = obj2Value.Convert(float64Type).Interface().(float64) - } - if float64obj1 > float64obj2 { - return compareGreater, true - } - if float64obj1 == float64obj2 { - return compareEqual, true - } - if float64obj1 < float64obj2 { - return compareLess, true - } - } - case reflect.String: - { - stringobj1, ok := obj1.(string) - if !ok { - stringobj1 = obj1Value.Convert(stringType).Interface().(string) - } - stringobj2, ok := obj2.(string) - if !ok { - stringobj2 = obj2Value.Convert(stringType).Interface().(string) - } - if stringobj1 > stringobj2 { - return compareGreater, true - } - if stringobj1 == stringobj2 { - return compareEqual, true - } - if stringobj1 < stringobj2 { - return compareLess, true - } - } - // Check for known struct types we can check for compare results. - case reflect.Struct: - { - // All structs enter here. We're not interested in most types. - if !obj1Value.CanConvert(timeType) { - break - } - - // time.Time can be compared! - timeObj1, ok := obj1.(time.Time) - if !ok { - timeObj1 = obj1Value.Convert(timeType).Interface().(time.Time) - } - - timeObj2, ok := obj2.(time.Time) - if !ok { - timeObj2 = obj2Value.Convert(timeType).Interface().(time.Time) - } - - return compare(timeObj1.UnixNano(), timeObj2.UnixNano(), reflect.Int64) - } - case reflect.Slice: - { - // We only care about the []byte type. - if !obj1Value.CanConvert(bytesType) { - break - } - - // []byte can be compared! - bytesObj1, ok := obj1.([]byte) - if !ok { - bytesObj1 = obj1Value.Convert(bytesType).Interface().([]byte) - - } - bytesObj2, ok := obj2.([]byte) - if !ok { - bytesObj2 = obj2Value.Convert(bytesType).Interface().([]byte) - } - - return CompareType(bytes.Compare(bytesObj1, bytesObj2)), true - } - case reflect.Uintptr: - { - uintptrObj1, ok := obj1.(uintptr) - if !ok { - uintptrObj1 = obj1Value.Convert(uintptrType).Interface().(uintptr) - } - uintptrObj2, ok := obj2.(uintptr) - if !ok { - uintptrObj2 = obj2Value.Convert(uintptrType).Interface().(uintptr) - } - if uintptrObj1 > uintptrObj2 { - return compareGreater, true - } - if uintptrObj1 == uintptrObj2 { - return compareEqual, true - } - if uintptrObj1 < uintptrObj2 { - return compareLess, true - } - } - } - - return compareEqual, false -} - -// Greater asserts that the first element is greater than the second -// -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") -func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return compareTwoValues(t, e1, e2, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) -} - -// GreaterOrEqual asserts that the first element is greater than or equal to the second -// -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") -func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return compareTwoValues(t, e1, e2, []CompareType{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) -} - -// Less asserts that the first element is less than the second -// -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") -func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return compareTwoValues(t, e1, e2, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) -} - -// LessOrEqual asserts that the first element is less than or equal to the second -// -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") -func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) -} - -// Positive asserts that the specified element is positive -// -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) -func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - zero := reflect.Zero(reflect.TypeOf(e)) - return compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, "\"%v\" is not positive", msgAndArgs...) -} - -// Negative asserts that the specified element is negative -// -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) -func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - zero := reflect.Zero(reflect.TypeOf(e)) - return compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, "\"%v\" is not negative", msgAndArgs...) -} - -func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - e1Kind := reflect.ValueOf(e1).Kind() - e2Kind := reflect.ValueOf(e2).Kind() - if e1Kind != e2Kind { - return Fail(t, "Elements should be the same type", msgAndArgs...) - } - - compareResult, isComparable := compare(e1, e2, e1Kind) - if !isComparable { - return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...) - } - - if !containsValue(allowedComparesResults, compareResult) { - return Fail(t, fmt.Sprintf(failMessage, e1, e2), msgAndArgs...) - } - - return true -} - -func containsValue(values []CompareType, value CompareType) bool { - for _, v := range values { - if v == value { - return true - } - } - - return false -} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go b/vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go deleted file mode 100644 index da867903..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_compare_can_convert.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build go1.17 -// +build go1.17 - -// TODO: once support for Go 1.16 is dropped, this file can be -// merged/removed with assertion_compare_go1.17_test.go and -// assertion_compare_legacy.go - -package assert - -import "reflect" - -// Wrapper around reflect.Value.CanConvert, for compatibility -// reasons. -func canConvert(value reflect.Value, to reflect.Type) bool { - return value.CanConvert(to) -} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare_legacy.go b/vendor/github.com/stretchr/testify/assert/assertion_compare_legacy.go deleted file mode 100644 index 1701af2a..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_compare_legacy.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !go1.17 -// +build !go1.17 - -// TODO: once support for Go 1.16 is dropped, this file can be -// merged/removed with assertion_compare_go1.17_test.go and -// assertion_compare_can_convert.go - -package assert - -import "reflect" - -// Older versions of Go does not have the reflect.Value.CanConvert -// method. -func canConvert(value reflect.Value, to reflect.Type) bool { - return false -} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go deleted file mode 100644 index 3ddab109..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_format.go +++ /dev/null @@ -1,815 +0,0 @@ -// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT. - -package assert - -import ( - http "net/http" - url "net/url" - time "time" -) - -// Conditionf uses a Comparison to assert a complex condition. -func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Condition(t, comp, append([]interface{}{msg}, args...)...) -} - -// Containsf asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") -func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Contains(t, s, contains, append([]interface{}{msg}, args...)...) -} - -// DirExistsf checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return DirExists(t, path, append([]interface{}{msg}, args...)...) -} - -// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") -func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) -} - -// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// assert.Emptyf(t, obj, "error message %s", "formatted") -func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Empty(t, object, append([]interface{}{msg}, args...)...) -} - -// Equalf asserts that two objects are equal. -// -// assert.Equalf(t, 123, 123, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") -func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...) -} - -// EqualExportedValuesf asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true -// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false -func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. -// -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") -func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// Errorf asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } -func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Error(t, err, append([]interface{}{msg}, args...)...) -} - -// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return ErrorAs(t, err, target, append([]interface{}{msg}, args...)...) -} - -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") -func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return ErrorContains(t, theError, contains, append([]interface{}{msg}, args...)...) -} - -// ErrorIsf asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return ErrorIs(t, err, target, append([]interface{}{msg}, args...)...) -} - -// Eventuallyf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) -} - -// EventuallyWithTf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return EventuallyWithT(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) -} - -// Exactlyf asserts that two objects are equal in value and type. -// -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") -func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// Failf reports a failure through -func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Fail(t, failureMessage, append([]interface{}{msg}, args...)...) -} - -// FailNowf fails test -func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...) -} - -// Falsef asserts that the specified value is false. -// -// assert.Falsef(t, myBool, "error message %s", "formatted") -func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return False(t, value, append([]interface{}{msg}, args...)...) -} - -// FileExistsf checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return FileExists(t, path, append([]interface{}{msg}, args...)...) -} - -// Greaterf asserts that the first element is greater than the second -// -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") -func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Greater(t, e1, e2, append([]interface{}{msg}, args...)...) -} - -// GreaterOrEqualf asserts that the first element is greater than or equal to the second -// -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") -func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return GreaterOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...) -} - -// HTTPBodyContainsf asserts that a specified handler returns a -// body that contains a string. -// -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) -} - -// HTTPBodyNotContainsf asserts that a specified handler returns a -// body that does not contain a string. -// -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) -} - -// HTTPErrorf asserts that a specified handler returns an error status code. -// -// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...) -} - -// HTTPRedirectf asserts that a specified handler returns a redirect status code. -// -// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...) -} - -// HTTPStatusCodef asserts that a specified handler returns a specified status code. -// -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return HTTPStatusCode(t, handler, method, url, values, statuscode, append([]interface{}{msg}, args...)...) -} - -// HTTPSuccessf asserts that a specified handler returns a success status code. -// -// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...) -} - -// Implementsf asserts that an object is implemented by the specified interface. -// -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...) -} - -// InDeltaf asserts that the two numerals are within delta of each other. -// -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") -func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...) -} - -// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...) -} - -// InDeltaSlicef is the same as InDelta, except it compares two slices. -func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...) -} - -// InEpsilonf asserts that expected and actual have a relative error less than epsilon -func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) -} - -// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. -func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) -} - -// IsDecreasingf asserts that the collection is decreasing -// -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return IsDecreasing(t, object, append([]interface{}{msg}, args...)...) -} - -// IsIncreasingf asserts that the collection is increasing -// -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return IsIncreasing(t, object, append([]interface{}{msg}, args...)...) -} - -// IsNonDecreasingf asserts that the collection is not decreasing -// -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return IsNonDecreasing(t, object, append([]interface{}{msg}, args...)...) -} - -// IsNonIncreasingf asserts that the collection is not increasing -// -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...) -} - -// IsTypef asserts that the specified objects are of the same type. -func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...) -} - -// JSONEqf asserts that two JSON strings are equivalent. -// -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") -func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// Lenf asserts that the specified object has specific length. -// Lenf also fails if the object has a type that len() not accept. -// -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") -func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Len(t, object, length, append([]interface{}{msg}, args...)...) -} - -// Lessf asserts that the first element is less than the second -// -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") -func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Less(t, e1, e2, append([]interface{}{msg}, args...)...) -} - -// LessOrEqualf asserts that the first element is less than or equal to the second -// -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") -func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...) -} - -// Negativef asserts that the specified element is negative -// -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") -func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Negative(t, e, append([]interface{}{msg}, args...)...) -} - -// Neverf asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Never(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) -} - -// Nilf asserts that the specified object is nil. -// -// assert.Nilf(t, err, "error message %s", "formatted") -func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Nil(t, object, append([]interface{}{msg}, args...)...) -} - -// NoDirExistsf checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NoDirExists(t, path, append([]interface{}{msg}, args...)...) -} - -// NoErrorf asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } -func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NoError(t, err, append([]interface{}{msg}, args...)...) -} - -// NoFileExistsf checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NoFileExists(t, path, append([]interface{}{msg}, args...)...) -} - -// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") -func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) -} - -// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } -func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotEmpty(t, object, append([]interface{}{msg}, args...)...) -} - -// NotEqualf asserts that the specified values are NOT equal. -// -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// NotEqualValuesf asserts that two objects are not equal even when converted to the same type -// -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") -func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// NotErrorIsf asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotErrorIs(t, err, target, append([]interface{}{msg}, args...)...) -} - -// NotImplementsf asserts that an object does not implement the specified interface. -// -// assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotImplements(t, interfaceObject, object, append([]interface{}{msg}, args...)...) -} - -// NotNilf asserts that the specified object is not nil. -// -// assert.NotNilf(t, err, "error message %s", "formatted") -func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotNil(t, object, append([]interface{}{msg}, args...)...) -} - -// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") -func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotPanics(t, f, append([]interface{}{msg}, args...)...) -} - -// NotRegexpf asserts that a specified regexp does not match a string. -// -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") -func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...) -} - -// NotSamef asserts that two pointers do not reference the same object. -// -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// NotSubsetf asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") -// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") -func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...) -} - -// NotZerof asserts that i is not the zero value for its type. -func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return NotZero(t, i, append([]interface{}{msg}, args...)...) -} - -// Panicsf asserts that the code inside the specified PanicTestFunc panics. -// -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") -func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Panics(t, f, append([]interface{}{msg}, args...)...) -} - -// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return PanicsWithError(t, errString, f, append([]interface{}{msg}, args...)...) -} - -// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...) -} - -// Positivef asserts that the specified element is positive -// -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") -func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Positive(t, e, append([]interface{}{msg}, args...)...) -} - -// Regexpf asserts that a specified regexp matches a string. -// -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") -func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Regexp(t, rx, str, append([]interface{}{msg}, args...)...) -} - -// Samef asserts that two pointers reference the same object. -// -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Same(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// Subsetf asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") -// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") -func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Subset(t, list, subset, append([]interface{}{msg}, args...)...) -} - -// Truef asserts that the specified value is true. -// -// assert.Truef(t, myBool, "error message %s", "formatted") -func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return True(t, value, append([]interface{}{msg}, args...)...) -} - -// WithinDurationf asserts that the two times are within duration delta of each other. -// -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") -func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...) -} - -// WithinRangef asserts that a time is within a time range (inclusive). -// -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") -func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...) -} - -// YAMLEqf asserts that two YAML strings are equivalent. -func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return YAMLEq(t, expected, actual, append([]interface{}{msg}, args...)...) -} - -// Zerof asserts that i is the zero value for its type. -func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Zero(t, i, append([]interface{}{msg}, args...)...) -} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl deleted file mode 100644 index d2bb0b81..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl +++ /dev/null @@ -1,5 +0,0 @@ -{{.CommentFormat}} -func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool { - if h, ok := t.(tHelper); ok { h.Helper() } - return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}}) -} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go deleted file mode 100644 index a84e09bd..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ /dev/null @@ -1,1621 +0,0 @@ -// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT. - -package assert - -import ( - http "net/http" - url "net/url" - time "time" -) - -// Condition uses a Comparison to assert a complex condition. -func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Condition(a.t, comp, msgAndArgs...) -} - -// Conditionf uses a Comparison to assert a complex condition. -func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Conditionf(a.t, comp, msg, args...) -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// a.Contains("Hello World", "World") -// a.Contains(["Hello", "World"], "World") -// a.Contains({"Hello": "World"}, "Hello") -func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Contains(a.t, s, contains, msgAndArgs...) -} - -// Containsf asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// a.Containsf("Hello World", "World", "error message %s", "formatted") -// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") -// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") -func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Containsf(a.t, s, contains, msg, args...) -} - -// DirExists checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return DirExists(a.t, path, msgAndArgs...) -} - -// DirExistsf checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return DirExistsf(a.t, path, msg, args...) -} - -// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]) -func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ElementsMatch(a.t, listA, listB, msgAndArgs...) -} - -// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") -func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ElementsMatchf(a.t, listA, listB, msg, args...) -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// a.Empty(obj) -func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Empty(a.t, object, msgAndArgs...) -} - -// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// a.Emptyf(obj, "error message %s", "formatted") -func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Emptyf(a.t, object, msg, args...) -} - -// Equal asserts that two objects are equal. -// -// a.Equal(123, 123) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Equal(a.t, expected, actual, msgAndArgs...) -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString) -func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EqualError(a.t, theError, errString, msgAndArgs...) -} - -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") -func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EqualErrorf(a.t, theError, errString, msg, args...) -} - -// EqualExportedValues asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// a.EqualExportedValues(S{1, 2}, S{1, 3}) => true -// a.EqualExportedValues(S{1, 2}, S{2, 3}) => false -func (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EqualExportedValues(a.t, expected, actual, msgAndArgs...) -} - -// EqualExportedValuesf asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// a.EqualExportedValuesf(S{1, 2}, S{1, 3}, "error message %s", "formatted") => true -// a.EqualExportedValuesf(S{1, 2}, S{2, 3}, "error message %s", "formatted") => false -func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EqualExportedValuesf(a.t, expected, actual, msg, args...) -} - -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. -// -// a.EqualValues(uint32(123), int32(123)) -func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EqualValues(a.t, expected, actual, msgAndArgs...) -} - -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. -// -// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") -func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EqualValuesf(a.t, expected, actual, msg, args...) -} - -// Equalf asserts that two objects are equal. -// -// a.Equalf(123, 123, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Equalf(a.t, expected, actual, msg, args...) -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if a.Error(err) { -// assert.Equal(t, expectedError, err) -// } -func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Error(a.t, err, msgAndArgs...) -} - -// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ErrorAs(a.t, err, target, msgAndArgs...) -} - -// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ErrorAsf(a.t, err, target, msg, args...) -} - -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// a.ErrorContains(err, expectedErrorSubString) -func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ErrorContains(a.t, theError, contains, msgAndArgs...) -} - -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") -func (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ErrorContainsf(a.t, theError, contains, msg, args...) -} - -// ErrorIs asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ErrorIs(a.t, err, target, msgAndArgs...) -} - -// ErrorIsf asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return ErrorIsf(a.t, err, target, msg, args...) -} - -// Errorf asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if a.Errorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } -func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Errorf(a.t, err, msg, args...) -} - -// Eventually asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) -func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Eventually(a.t, condition, waitFor, tick, msgAndArgs...) -} - -// EventuallyWithT asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// a.EventuallyWithT(func(c *assert.CollectT) { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...) -} - -// EventuallyWithTf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...) -} - -// Eventuallyf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Eventuallyf(a.t, condition, waitFor, tick, msg, args...) -} - -// Exactly asserts that two objects are equal in value and type. -// -// a.Exactly(int32(123), int64(123)) -func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Exactly(a.t, expected, actual, msgAndArgs...) -} - -// Exactlyf asserts that two objects are equal in value and type. -// -// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") -func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Exactlyf(a.t, expected, actual, msg, args...) -} - -// Fail reports a failure through -func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Fail(a.t, failureMessage, msgAndArgs...) -} - -// FailNow fails test -func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return FailNow(a.t, failureMessage, msgAndArgs...) -} - -// FailNowf fails test -func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return FailNowf(a.t, failureMessage, msg, args...) -} - -// Failf reports a failure through -func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Failf(a.t, failureMessage, msg, args...) -} - -// False asserts that the specified value is false. -// -// a.False(myBool) -func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return False(a.t, value, msgAndArgs...) -} - -// Falsef asserts that the specified value is false. -// -// a.Falsef(myBool, "error message %s", "formatted") -func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Falsef(a.t, value, msg, args...) -} - -// FileExists checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return FileExists(a.t, path, msgAndArgs...) -} - -// FileExistsf checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return FileExistsf(a.t, path, msg, args...) -} - -// Greater asserts that the first element is greater than the second -// -// a.Greater(2, 1) -// a.Greater(float64(2), float64(1)) -// a.Greater("b", "a") -func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Greater(a.t, e1, e2, msgAndArgs...) -} - -// GreaterOrEqual asserts that the first element is greater than or equal to the second -// -// a.GreaterOrEqual(2, 1) -// a.GreaterOrEqual(2, 2) -// a.GreaterOrEqual("b", "a") -// a.GreaterOrEqual("b", "b") -func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return GreaterOrEqual(a.t, e1, e2, msgAndArgs...) -} - -// GreaterOrEqualf asserts that the first element is greater than or equal to the second -// -// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") -// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") -// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") -// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") -func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return GreaterOrEqualf(a.t, e1, e2, msg, args...) -} - -// Greaterf asserts that the first element is greater than the second -// -// a.Greaterf(2, 1, "error message %s", "formatted") -// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") -// a.Greaterf("b", "a", "error message %s", "formatted") -func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Greaterf(a.t, e1, e2, msg, args...) -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...) -} - -// HTTPBodyContainsf asserts that a specified handler returns a -// body that contains a string. -// -// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...) -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...) -} - -// HTTPBodyNotContainsf asserts that a specified handler returns a -// body that does not contain a string. -// -// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...) -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPError(a.t, handler, method, url, values, msgAndArgs...) -} - -// HTTPErrorf asserts that a specified handler returns an error status code. -// -// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPErrorf(a.t, handler, method, url, values, msg, args...) -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...) -} - -// HTTPRedirectf asserts that a specified handler returns a redirect status code. -// -// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPRedirectf(a.t, handler, method, url, values, msg, args...) -} - -// HTTPStatusCode asserts that a specified handler returns a specified status code. -// -// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPStatusCode(a.t, handler, method, url, values, statuscode, msgAndArgs...) -} - -// HTTPStatusCodef asserts that a specified handler returns a specified status code. -// -// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPStatusCodef(a.t, handler, method, url, values, statuscode, msg, args...) -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...) -} - -// HTTPSuccessf asserts that a specified handler returns a success status code. -// -// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return HTTPSuccessf(a.t, handler, method, url, values, msg, args...) -} - -// Implements asserts that an object is implemented by the specified interface. -// -// a.Implements((*MyInterface)(nil), new(MyObject)) -func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Implements(a.t, interfaceObject, object, msgAndArgs...) -} - -// Implementsf asserts that an object is implemented by the specified interface. -// -// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Implementsf(a.t, interfaceObject, object, msg, args...) -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// a.InDelta(math.Pi, 22/7.0, 0.01) -func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InDelta(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...) -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaSlicef is the same as InDelta, except it compares two slices. -func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InDeltaSlicef(a.t, expected, actual, delta, msg, args...) -} - -// InDeltaf asserts that the two numerals are within delta of each other. -// -// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") -func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InDeltaf(a.t, expected, actual, delta, msg, args...) -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. -func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...) -} - -// InEpsilonf asserts that expected and actual have a relative error less than epsilon -func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return InEpsilonf(a.t, expected, actual, epsilon, msg, args...) -} - -// IsDecreasing asserts that the collection is decreasing -// -// a.IsDecreasing([]int{2, 1, 0}) -// a.IsDecreasing([]float{2, 1}) -// a.IsDecreasing([]string{"b", "a"}) -func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsDecreasing(a.t, object, msgAndArgs...) -} - -// IsDecreasingf asserts that the collection is decreasing -// -// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") -// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") -func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsDecreasingf(a.t, object, msg, args...) -} - -// IsIncreasing asserts that the collection is increasing -// -// a.IsIncreasing([]int{1, 2, 3}) -// a.IsIncreasing([]float{1, 2}) -// a.IsIncreasing([]string{"a", "b"}) -func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsIncreasing(a.t, object, msgAndArgs...) -} - -// IsIncreasingf asserts that the collection is increasing -// -// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") -// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") -func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsIncreasingf(a.t, object, msg, args...) -} - -// IsNonDecreasing asserts that the collection is not decreasing -// -// a.IsNonDecreasing([]int{1, 1, 2}) -// a.IsNonDecreasing([]float{1, 2}) -// a.IsNonDecreasing([]string{"a", "b"}) -func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsNonDecreasing(a.t, object, msgAndArgs...) -} - -// IsNonDecreasingf asserts that the collection is not decreasing -// -// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") -func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsNonDecreasingf(a.t, object, msg, args...) -} - -// IsNonIncreasing asserts that the collection is not increasing -// -// a.IsNonIncreasing([]int{2, 1, 1}) -// a.IsNonIncreasing([]float{2, 1}) -// a.IsNonIncreasing([]string{"b", "a"}) -func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsNonIncreasing(a.t, object, msgAndArgs...) -} - -// IsNonIncreasingf asserts that the collection is not increasing -// -// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") -func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsNonIncreasingf(a.t, object, msg, args...) -} - -// IsType asserts that the specified objects are of the same type. -func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsType(a.t, expectedType, object, msgAndArgs...) -} - -// IsTypef asserts that the specified objects are of the same type. -func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return IsTypef(a.t, expectedType, object, msg, args...) -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return JSONEq(a.t, expected, actual, msgAndArgs...) -} - -// JSONEqf asserts that two JSON strings are equivalent. -// -// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") -func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return JSONEqf(a.t, expected, actual, msg, args...) -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// a.Len(mySlice, 3) -func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Len(a.t, object, length, msgAndArgs...) -} - -// Lenf asserts that the specified object has specific length. -// Lenf also fails if the object has a type that len() not accept. -// -// a.Lenf(mySlice, 3, "error message %s", "formatted") -func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Lenf(a.t, object, length, msg, args...) -} - -// Less asserts that the first element is less than the second -// -// a.Less(1, 2) -// a.Less(float64(1), float64(2)) -// a.Less("a", "b") -func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Less(a.t, e1, e2, msgAndArgs...) -} - -// LessOrEqual asserts that the first element is less than or equal to the second -// -// a.LessOrEqual(1, 2) -// a.LessOrEqual(2, 2) -// a.LessOrEqual("a", "b") -// a.LessOrEqual("b", "b") -func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return LessOrEqual(a.t, e1, e2, msgAndArgs...) -} - -// LessOrEqualf asserts that the first element is less than or equal to the second -// -// a.LessOrEqualf(1, 2, "error message %s", "formatted") -// a.LessOrEqualf(2, 2, "error message %s", "formatted") -// a.LessOrEqualf("a", "b", "error message %s", "formatted") -// a.LessOrEqualf("b", "b", "error message %s", "formatted") -func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return LessOrEqualf(a.t, e1, e2, msg, args...) -} - -// Lessf asserts that the first element is less than the second -// -// a.Lessf(1, 2, "error message %s", "formatted") -// a.Lessf(float64(1), float64(2), "error message %s", "formatted") -// a.Lessf("a", "b", "error message %s", "formatted") -func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Lessf(a.t, e1, e2, msg, args...) -} - -// Negative asserts that the specified element is negative -// -// a.Negative(-1) -// a.Negative(-1.23) -func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Negative(a.t, e, msgAndArgs...) -} - -// Negativef asserts that the specified element is negative -// -// a.Negativef(-1, "error message %s", "formatted") -// a.Negativef(-1.23, "error message %s", "formatted") -func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Negativef(a.t, e, msg, args...) -} - -// Never asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) -func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Never(a.t, condition, waitFor, tick, msgAndArgs...) -} - -// Neverf asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Neverf(a.t, condition, waitFor, tick, msg, args...) -} - -// Nil asserts that the specified object is nil. -// -// a.Nil(err) -func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Nil(a.t, object, msgAndArgs...) -} - -// Nilf asserts that the specified object is nil. -// -// a.Nilf(err, "error message %s", "formatted") -func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Nilf(a.t, object, msg, args...) -} - -// NoDirExists checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NoDirExists(a.t, path, msgAndArgs...) -} - -// NoDirExistsf checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NoDirExistsf(a.t, path, msg, args...) -} - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } -func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NoError(a.t, err, msgAndArgs...) -} - -// NoErrorf asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } -func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NoErrorf(a.t, err, msg, args...) -} - -// NoFileExists checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NoFileExists(a.t, path, msgAndArgs...) -} - -// NoFileExistsf checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NoFileExistsf(a.t, path, msg, args...) -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// a.NotContains("Hello World", "Earth") -// a.NotContains(["Hello", "World"], "Earth") -// a.NotContains({"Hello": "World"}, "Earth") -func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotContains(a.t, s, contains, msgAndArgs...) -} - -// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") -// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") -// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") -func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotContainsf(a.t, s, contains, msg, args...) -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } -func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotEmpty(a.t, object, msgAndArgs...) -} - -// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } -func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotEmptyf(a.t, object, msg, args...) -} - -// NotEqual asserts that the specified values are NOT equal. -// -// a.NotEqual(obj1, obj2) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotEqual(a.t, expected, actual, msgAndArgs...) -} - -// NotEqualValues asserts that two objects are not equal even when converted to the same type -// -// a.NotEqualValues(obj1, obj2) -func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotEqualValues(a.t, expected, actual, msgAndArgs...) -} - -// NotEqualValuesf asserts that two objects are not equal even when converted to the same type -// -// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") -func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotEqualValuesf(a.t, expected, actual, msg, args...) -} - -// NotEqualf asserts that the specified values are NOT equal. -// -// a.NotEqualf(obj1, obj2, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotEqualf(a.t, expected, actual, msg, args...) -} - -// NotErrorIs asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotErrorIs(a.t, err, target, msgAndArgs...) -} - -// NotErrorIsf asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotErrorIsf(a.t, err, target, msg, args...) -} - -// NotImplements asserts that an object does not implement the specified interface. -// -// a.NotImplements((*MyInterface)(nil), new(MyObject)) -func (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotImplements(a.t, interfaceObject, object, msgAndArgs...) -} - -// NotImplementsf asserts that an object does not implement the specified interface. -// -// a.NotImplementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotImplementsf(a.t, interfaceObject, object, msg, args...) -} - -// NotNil asserts that the specified object is not nil. -// -// a.NotNil(err) -func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotNil(a.t, object, msgAndArgs...) -} - -// NotNilf asserts that the specified object is not nil. -// -// a.NotNilf(err, "error message %s", "formatted") -func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotNilf(a.t, object, msg, args...) -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// a.NotPanics(func(){ RemainCalm() }) -func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotPanics(a.t, f, msgAndArgs...) -} - -// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") -func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotPanicsf(a.t, f, msg, args...) -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") -func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotRegexp(a.t, rx, str, msgAndArgs...) -} - -// NotRegexpf asserts that a specified regexp does not match a string. -// -// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") -func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotRegexpf(a.t, rx, str, msg, args...) -} - -// NotSame asserts that two pointers do not reference the same object. -// -// a.NotSame(ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotSame(a.t, expected, actual, msgAndArgs...) -} - -// NotSamef asserts that two pointers do not reference the same object. -// -// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotSamef(a.t, expected, actual, msg, args...) -} - -// NotSubset asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// a.NotSubset([1, 3, 4], [1, 2]) -// a.NotSubset({"x": 1, "y": 2}, {"z": 3}) -func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotSubset(a.t, list, subset, msgAndArgs...) -} - -// NotSubsetf asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted") -// a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") -func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotSubsetf(a.t, list, subset, msg, args...) -} - -// NotZero asserts that i is not the zero value for its type. -func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotZero(a.t, i, msgAndArgs...) -} - -// NotZerof asserts that i is not the zero value for its type. -func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return NotZerof(a.t, i, msg, args...) -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// a.Panics(func(){ GoCrazy() }) -func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Panics(a.t, f, msgAndArgs...) -} - -// PanicsWithError asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// a.PanicsWithError("crazy error", func(){ GoCrazy() }) -func (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return PanicsWithError(a.t, errString, f, msgAndArgs...) -} - -// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return PanicsWithErrorf(a.t, errString, f, msg, args...) -} - -// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) -func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return PanicsWithValue(a.t, expected, f, msgAndArgs...) -} - -// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return PanicsWithValuef(a.t, expected, f, msg, args...) -} - -// Panicsf asserts that the code inside the specified PanicTestFunc panics. -// -// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") -func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Panicsf(a.t, f, msg, args...) -} - -// Positive asserts that the specified element is positive -// -// a.Positive(1) -// a.Positive(1.23) -func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Positive(a.t, e, msgAndArgs...) -} - -// Positivef asserts that the specified element is positive -// -// a.Positivef(1, "error message %s", "formatted") -// a.Positivef(1.23, "error message %s", "formatted") -func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Positivef(a.t, e, msg, args...) -} - -// Regexp asserts that a specified regexp matches a string. -// -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") -func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Regexp(a.t, rx, str, msgAndArgs...) -} - -// Regexpf asserts that a specified regexp matches a string. -// -// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") -func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Regexpf(a.t, rx, str, msg, args...) -} - -// Same asserts that two pointers reference the same object. -// -// a.Same(ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Same(a.t, expected, actual, msgAndArgs...) -} - -// Samef asserts that two pointers reference the same object. -// -// a.Samef(ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Samef(a.t, expected, actual, msg, args...) -} - -// Subset asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// a.Subset([1, 2, 3], [1, 2]) -// a.Subset({"x": 1, "y": 2}, {"x": 1}) -func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Subset(a.t, list, subset, msgAndArgs...) -} - -// Subsetf asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted") -// a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") -func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Subsetf(a.t, list, subset, msg, args...) -} - -// True asserts that the specified value is true. -// -// a.True(myBool) -func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return True(a.t, value, msgAndArgs...) -} - -// Truef asserts that the specified value is true. -// -// a.Truef(myBool, "error message %s", "formatted") -func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Truef(a.t, value, msg, args...) -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) -func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) -} - -// WithinDurationf asserts that the two times are within duration delta of each other. -// -// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") -func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return WithinDurationf(a.t, expected, actual, delta, msg, args...) -} - -// WithinRange asserts that a time is within a time range (inclusive). -// -// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) -func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return WithinRange(a.t, actual, start, end, msgAndArgs...) -} - -// WithinRangef asserts that a time is within a time range (inclusive). -// -// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") -func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return WithinRangef(a.t, actual, start, end, msg, args...) -} - -// YAMLEq asserts that two YAML strings are equivalent. -func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return YAMLEq(a.t, expected, actual, msgAndArgs...) -} - -// YAMLEqf asserts that two YAML strings are equivalent. -func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return YAMLEqf(a.t, expected, actual, msg, args...) -} - -// Zero asserts that i is the zero value for its type. -func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Zero(a.t, i, msgAndArgs...) -} - -// Zerof asserts that i is the zero value for its type. -func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - return Zerof(a.t, i, msg, args...) -} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl deleted file mode 100644 index 188bb9e1..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl +++ /dev/null @@ -1,5 +0,0 @@ -{{.CommentWithoutT "a"}} -func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { - if h, ok := a.t.(tHelper); ok { h.Helper() } - return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) -} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go deleted file mode 100644 index 00df62a0..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertion_order.go +++ /dev/null @@ -1,81 +0,0 @@ -package assert - -import ( - "fmt" - "reflect" -) - -// isOrdered checks that collection contains orderable elements. -func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { - objKind := reflect.TypeOf(object).Kind() - if objKind != reflect.Slice && objKind != reflect.Array { - return false - } - - objValue := reflect.ValueOf(object) - objLen := objValue.Len() - - if objLen <= 1 { - return true - } - - value := objValue.Index(0) - valueInterface := value.Interface() - firstValueKind := value.Kind() - - for i := 1; i < objLen; i++ { - prevValue := value - prevValueInterface := valueInterface - - value = objValue.Index(i) - valueInterface = value.Interface() - - compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind) - - if !isComparable { - return Fail(t, fmt.Sprintf("Can not compare type \"%s\" and \"%s\"", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...) - } - - if !containsValue(allowedComparesResults, compareResult) { - return Fail(t, fmt.Sprintf(failMessage, prevValue, value), msgAndArgs...) - } - } - - return true -} - -// IsIncreasing asserts that the collection is increasing -// -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) -func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) -} - -// IsNonIncreasing asserts that the collection is not increasing -// -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) -func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) -} - -// IsDecreasing asserts that the collection is decreasing -// -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) -func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) -} - -// IsNonDecreasing asserts that the collection is not decreasing -// -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) -func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) -} diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go deleted file mode 100644 index 0b7570f2..00000000 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ /dev/null @@ -1,2105 +0,0 @@ -package assert - -import ( - "bufio" - "bytes" - "encoding/json" - "errors" - "fmt" - "math" - "os" - "reflect" - "regexp" - "runtime" - "runtime/debug" - "strings" - "time" - "unicode" - "unicode/utf8" - - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" - "gopkg.in/yaml.v3" -) - -//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" - -// TestingT is an interface wrapper around *testing.T -type TestingT interface { - Errorf(format string, args ...interface{}) -} - -// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful -// for table driven tests. -type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool - -// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful -// for table driven tests. -type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool - -// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful -// for table driven tests. -type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool - -// ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful -// for table driven tests. -type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool - -// Comparison is a custom function that returns true on success and false on failure -type Comparison func() (success bool) - -/* - Helper functions -*/ - -// ObjectsAreEqual determines if two objects are considered equal. -// -// This function does no assertion of any kind. -func ObjectsAreEqual(expected, actual interface{}) bool { - if expected == nil || actual == nil { - return expected == actual - } - - exp, ok := expected.([]byte) - if !ok { - return reflect.DeepEqual(expected, actual) - } - - act, ok := actual.([]byte) - if !ok { - return false - } - if exp == nil || act == nil { - return exp == nil && act == nil - } - return bytes.Equal(exp, act) -} - -// copyExportedFields iterates downward through nested data structures and creates a copy -// that only contains the exported struct fields. -func copyExportedFields(expected interface{}) interface{} { - if isNil(expected) { - return expected - } - - expectedType := reflect.TypeOf(expected) - expectedKind := expectedType.Kind() - expectedValue := reflect.ValueOf(expected) - - switch expectedKind { - case reflect.Struct: - result := reflect.New(expectedType).Elem() - for i := 0; i < expectedType.NumField(); i++ { - field := expectedType.Field(i) - isExported := field.IsExported() - if isExported { - fieldValue := expectedValue.Field(i) - if isNil(fieldValue) || isNil(fieldValue.Interface()) { - continue - } - newValue := copyExportedFields(fieldValue.Interface()) - result.Field(i).Set(reflect.ValueOf(newValue)) - } - } - return result.Interface() - - case reflect.Ptr: - result := reflect.New(expectedType.Elem()) - unexportedRemoved := copyExportedFields(expectedValue.Elem().Interface()) - result.Elem().Set(reflect.ValueOf(unexportedRemoved)) - return result.Interface() - - case reflect.Array, reflect.Slice: - var result reflect.Value - if expectedKind == reflect.Array { - result = reflect.New(reflect.ArrayOf(expectedValue.Len(), expectedType.Elem())).Elem() - } else { - result = reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len()) - } - for i := 0; i < expectedValue.Len(); i++ { - index := expectedValue.Index(i) - if isNil(index) { - continue - } - unexportedRemoved := copyExportedFields(index.Interface()) - result.Index(i).Set(reflect.ValueOf(unexportedRemoved)) - } - return result.Interface() - - case reflect.Map: - result := reflect.MakeMap(expectedType) - for _, k := range expectedValue.MapKeys() { - index := expectedValue.MapIndex(k) - unexportedRemoved := copyExportedFields(index.Interface()) - result.SetMapIndex(k, reflect.ValueOf(unexportedRemoved)) - } - return result.Interface() - - default: - return expected - } -} - -// ObjectsExportedFieldsAreEqual determines if the exported (public) fields of two objects are -// considered equal. This comparison of only exported fields is applied recursively to nested data -// structures. -// -// This function does no assertion of any kind. -// -// Deprecated: Use [EqualExportedValues] instead. -func ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool { - expectedCleaned := copyExportedFields(expected) - actualCleaned := copyExportedFields(actual) - return ObjectsAreEqualValues(expectedCleaned, actualCleaned) -} - -// ObjectsAreEqualValues gets whether two objects are equal, or if their -// values are equal. -func ObjectsAreEqualValues(expected, actual interface{}) bool { - if ObjectsAreEqual(expected, actual) { - return true - } - - expectedValue := reflect.ValueOf(expected) - actualValue := reflect.ValueOf(actual) - if !expectedValue.IsValid() || !actualValue.IsValid() { - return false - } - - expectedType := expectedValue.Type() - actualType := actualValue.Type() - if !expectedType.ConvertibleTo(actualType) { - return false - } - - if !isNumericType(expectedType) || !isNumericType(actualType) { - // Attempt comparison after type conversion - return reflect.DeepEqual( - expectedValue.Convert(actualType).Interface(), actual, - ) - } - - // If BOTH values are numeric, there are chances of false positives due - // to overflow or underflow. So, we need to make sure to always convert - // the smaller type to a larger type before comparing. - if expectedType.Size() >= actualType.Size() { - return actualValue.Convert(expectedType).Interface() == expected - } - - return expectedValue.Convert(actualType).Interface() == actual -} - -// isNumericType returns true if the type is one of: -// int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, -// float32, float64, complex64, complex128 -func isNumericType(t reflect.Type) bool { - return t.Kind() >= reflect.Int && t.Kind() <= reflect.Complex128 -} - -/* CallerInfo is necessary because the assert functions use the testing object -internally, causing it to print the file:line of the assert method, rather than where -the problem actually occurred in calling code.*/ - -// CallerInfo returns an array of strings containing the file and line number -// of each stack frame leading from the current test to the assert call that -// failed. -func CallerInfo() []string { - - var pc uintptr - var ok bool - var file string - var line int - var name string - - callers := []string{} - for i := 0; ; i++ { - pc, file, line, ok = runtime.Caller(i) - if !ok { - // The breaks below failed to terminate the loop, and we ran off the - // end of the call stack. - break - } - - // This is a huge edge case, but it will panic if this is the case, see #180 - if file == "" { - break - } - - f := runtime.FuncForPC(pc) - if f == nil { - break - } - name = f.Name() - - // testing.tRunner is the standard library function that calls - // tests. Subtests are called directly by tRunner, without going through - // the Test/Benchmark/Example function that contains the t.Run calls, so - // with subtests we should break when we hit tRunner, without adding it - // to the list of callers. - if name == "testing.tRunner" { - break - } - - parts := strings.Split(file, "/") - if len(parts) > 1 { - filename := parts[len(parts)-1] - dir := parts[len(parts)-2] - if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" { - callers = append(callers, fmt.Sprintf("%s:%d", file, line)) - } - } - - // Drop the package - segments := strings.Split(name, ".") - name = segments[len(segments)-1] - if isTest(name, "Test") || - isTest(name, "Benchmark") || - isTest(name, "Example") { - break - } - } - - return callers -} - -// Stolen from the `go test` tool. -// isTest tells whether name looks like a test (or benchmark, according to prefix). -// It is a Test (say) if there is a character after Test that is not a lower-case letter. -// We don't want TesticularCancer. -func isTest(name, prefix string) bool { - if !strings.HasPrefix(name, prefix) { - return false - } - if len(name) == len(prefix) { // "Test" is ok - return true - } - r, _ := utf8.DecodeRuneInString(name[len(prefix):]) - return !unicode.IsLower(r) -} - -func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { - if len(msgAndArgs) == 0 || msgAndArgs == nil { - return "" - } - if len(msgAndArgs) == 1 { - msg := msgAndArgs[0] - if msgAsStr, ok := msg.(string); ok { - return msgAsStr - } - return fmt.Sprintf("%+v", msg) - } - if len(msgAndArgs) > 1 { - return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) - } - return "" -} - -// Aligns the provided message so that all lines after the first line start at the same location as the first line. -// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). -// The longestLabelLen parameter specifies the length of the longest label in the output (required because this is the -// basis on which the alignment occurs). -func indentMessageLines(message string, longestLabelLen int) string { - outBuf := new(bytes.Buffer) - - for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { - // no need to align first line because it starts at the correct location (after the label) - if i != 0 { - // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab - outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") - } - outBuf.WriteString(scanner.Text()) - } - - return outBuf.String() -} - -type failNower interface { - FailNow() -} - -// FailNow fails test -func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - Fail(t, failureMessage, msgAndArgs...) - - // We cannot extend TestingT with FailNow() and - // maintain backwards compatibility, so we fallback - // to panicking when FailNow is not available in - // TestingT. - // See issue #263 - - if t, ok := t.(failNower); ok { - t.FailNow() - } else { - panic("test failed and t is missing `FailNow()`") - } - return false -} - -// Fail reports a failure through -func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - content := []labeledContent{ - {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")}, - {"Error", failureMessage}, - } - - // Add test name if the Go version supports it - if n, ok := t.(interface { - Name() string - }); ok { - content = append(content, labeledContent{"Test", n.Name()}) - } - - message := messageFromMsgAndArgs(msgAndArgs...) - if len(message) > 0 { - content = append(content, labeledContent{"Messages", message}) - } - - t.Errorf("\n%s", ""+labeledOutput(content...)) - - return false -} - -type labeledContent struct { - label string - content string -} - -// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: -// -// \t{{label}}:{{align_spaces}}\t{{content}}\n -// -// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. -// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this -// alignment is achieved, "\t{{content}}\n" is added for the output. -// -// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line. -func labeledOutput(content ...labeledContent) string { - longestLabel := 0 - for _, v := range content { - if len(v.label) > longestLabel { - longestLabel = len(v.label) - } - } - var output string - for _, v := range content { - output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" - } - return output -} - -// Implements asserts that an object is implemented by the specified interface. -// -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) -func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - interfaceType := reflect.TypeOf(interfaceObject).Elem() - - if object == nil { - return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...) - } - if !reflect.TypeOf(object).Implements(interfaceType) { - return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) - } - - return true -} - -// NotImplements asserts that an object does not implement the specified interface. -// -// assert.NotImplements(t, (*MyInterface)(nil), new(MyObject)) -func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - interfaceType := reflect.TypeOf(interfaceObject).Elem() - - if object == nil { - return Fail(t, fmt.Sprintf("Cannot check if nil does not implement %v", interfaceType), msgAndArgs...) - } - if reflect.TypeOf(object).Implements(interfaceType) { - return Fail(t, fmt.Sprintf("%T implements %v", object, interfaceType), msgAndArgs...) - } - - return true -} - -// IsType asserts that the specified objects are of the same type. -func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { - return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) - } - - return true -} - -// Equal asserts that two objects are equal. -// -// assert.Equal(t, 123, 123) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if err := validateEqualArgs(expected, actual); err != nil { - return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", - expected, actual, err), msgAndArgs...) - } - - if !ObjectsAreEqual(expected, actual) { - diff := diff(expected, actual) - expected, actual = formatUnequalValues(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: \n"+ - "expected: %s\n"+ - "actual : %s%s", expected, actual, diff), msgAndArgs...) - } - - return true - -} - -// validateEqualArgs checks whether provided arguments can be safely used in the -// Equal/NotEqual functions. -func validateEqualArgs(expected, actual interface{}) error { - if expected == nil && actual == nil { - return nil - } - - if isFunction(expected) || isFunction(actual) { - return errors.New("cannot take func type as argument") - } - return nil -} - -// Same asserts that two pointers reference the same object. -// -// assert.Same(t, ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if !samePointers(expected, actual) { - return Fail(t, fmt.Sprintf("Not same: \n"+ - "expected: %p %#v\n"+ - "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) - } - - return true -} - -// NotSame asserts that two pointers do not reference the same object. -// -// assert.NotSame(t, ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if samePointers(expected, actual) { - return Fail(t, fmt.Sprintf( - "Expected and actual point to the same object: %p %#v", - expected, expected), msgAndArgs...) - } - return true -} - -// samePointers compares two generic interface objects and returns whether -// they point to the same object -func samePointers(first, second interface{}) bool { - firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) - if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { - return false - } - - firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) - if firstType != secondType { - return false - } - - // compare pointer addresses - return first == second -} - -// formatUnequalValues takes two values of arbitrary types and returns string -// representations appropriate to be presented to the user. -// -// If the values are not of like type, the returned strings will be prefixed -// with the type name, and the value will be enclosed in parentheses similar -// to a type conversion in the Go grammar. -func formatUnequalValues(expected, actual interface{}) (e string, a string) { - if reflect.TypeOf(expected) != reflect.TypeOf(actual) { - return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)), - fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual)) - } - switch expected.(type) { - case time.Duration: - return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) - } - return truncatingFormat(expected), truncatingFormat(actual) -} - -// truncatingFormat formats the data and truncates it if it's too long. -// -// This helps keep formatted error messages lines from exceeding the -// bufio.MaxScanTokenSize max line length that the go testing framework imposes. -func truncatingFormat(data interface{}) string { - value := fmt.Sprintf("%#v", data) - max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed. - if len(value) > max { - value = value[0:max] + "<... truncated>" - } - return value -} - -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. -// -// assert.EqualValues(t, uint32(123), int32(123)) -func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if !ObjectsAreEqualValues(expected, actual) { - diff := diff(expected, actual) - expected, actual = formatUnequalValues(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: \n"+ - "expected: %s\n"+ - "actual : %s%s", expected, actual, diff), msgAndArgs...) - } - - return true - -} - -// EqualExportedValues asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true -// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false -func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - aType := reflect.TypeOf(expected) - bType := reflect.TypeOf(actual) - - if aType != bType { - return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) - } - - if aType.Kind() == reflect.Ptr { - aType = aType.Elem() - } - if bType.Kind() == reflect.Ptr { - bType = bType.Elem() - } - - if aType.Kind() != reflect.Struct { - return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) - } - - if bType.Kind() != reflect.Struct { - return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) - } - - expected = copyExportedFields(expected) - actual = copyExportedFields(actual) - - if !ObjectsAreEqualValues(expected, actual) { - diff := diff(expected, actual) - expected, actual = formatUnequalValues(expected, actual) - return Fail(t, fmt.Sprintf("Not equal (comparing only exported fields): \n"+ - "expected: %s\n"+ - "actual : %s%s", expected, actual, diff), msgAndArgs...) - } - - return true -} - -// Exactly asserts that two objects are equal in value and type. -// -// assert.Exactly(t, int32(123), int64(123)) -func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - aType := reflect.TypeOf(expected) - bType := reflect.TypeOf(actual) - - if aType != bType { - return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) - } - - return Equal(t, expected, actual, msgAndArgs...) - -} - -// NotNil asserts that the specified object is not nil. -// -// assert.NotNil(t, err) -func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - if !isNil(object) { - return true - } - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Fail(t, "Expected value not to be nil.", msgAndArgs...) -} - -// isNil checks if a specified object is nil or not, without Failing. -func isNil(object interface{}) bool { - if object == nil { - return true - } - - value := reflect.ValueOf(object) - switch value.Kind() { - case - reflect.Chan, reflect.Func, - reflect.Interface, reflect.Map, - reflect.Ptr, reflect.Slice, reflect.UnsafePointer: - - return value.IsNil() - } - - return false -} - -// Nil asserts that the specified object is nil. -// -// assert.Nil(t, err) -func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - if isNil(object) { - return true - } - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) -} - -// isEmpty gets whether the specified object is considered empty or not. -func isEmpty(object interface{}) bool { - - // get nil case out of the way - if object == nil { - return true - } - - objValue := reflect.ValueOf(object) - - switch objValue.Kind() { - // collection types are empty when they have no element - case reflect.Chan, reflect.Map, reflect.Slice: - return objValue.Len() == 0 - // pointers are empty if nil or if the value they point to is empty - case reflect.Ptr: - if objValue.IsNil() { - return true - } - deref := objValue.Elem().Interface() - return isEmpty(deref) - // for all other types, compare against the zero value - // array types are empty when they match their zero-initialized state - default: - zero := reflect.Zero(objValue.Type()) - return reflect.DeepEqual(object, zero.Interface()) - } -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// assert.Empty(t, obj) -func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - pass := isEmpty(object) - if !pass { - if h, ok := t.(tHelper); ok { - h.Helper() - } - Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) - } - - return pass - -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } -func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - pass := !isEmpty(object) - if !pass { - if h, ok := t.(tHelper); ok { - h.Helper() - } - Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) - } - - return pass - -} - -// getLen tries to get the length of an object. -// It returns (0, false) if impossible. -func getLen(x interface{}) (length int, ok bool) { - v := reflect.ValueOf(x) - defer func() { - ok = recover() == nil - }() - return v.Len(), true -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// assert.Len(t, mySlice, 3) -func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - l, ok := getLen(object) - if !ok { - return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...) - } - - if l != length { - return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) - } - return true -} - -// True asserts that the specified value is true. -// -// assert.True(t, myBool) -func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { - if !value { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Fail(t, "Should be true", msgAndArgs...) - } - - return true - -} - -// False asserts that the specified value is false. -// -// assert.False(t, myBool) -func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { - if value { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Fail(t, "Should be false", msgAndArgs...) - } - - return true - -} - -// NotEqual asserts that the specified values are NOT equal. -// -// assert.NotEqual(t, obj1, obj2) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if err := validateEqualArgs(expected, actual); err != nil { - return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", - expected, actual, err), msgAndArgs...) - } - - if ObjectsAreEqual(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) - } - - return true - -} - -// NotEqualValues asserts that two objects are not equal even when converted to the same type -// -// assert.NotEqualValues(t, obj1, obj2) -func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if ObjectsAreEqualValues(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) - } - - return true -} - -// containsElement try loop over the list check if the list includes the element. -// return (false, false) if impossible. -// return (true, false) if element was not found. -// return (true, true) if element was found. -func containsElement(list interface{}, element interface{}) (ok, found bool) { - - listValue := reflect.ValueOf(list) - listType := reflect.TypeOf(list) - if listType == nil { - return false, false - } - listKind := listType.Kind() - defer func() { - if e := recover(); e != nil { - ok = false - found = false - } - }() - - if listKind == reflect.String { - elementValue := reflect.ValueOf(element) - return true, strings.Contains(listValue.String(), elementValue.String()) - } - - if listKind == reflect.Map { - mapKeys := listValue.MapKeys() - for i := 0; i < len(mapKeys); i++ { - if ObjectsAreEqual(mapKeys[i].Interface(), element) { - return true, true - } - } - return true, false - } - - for i := 0; i < listValue.Len(); i++ { - if ObjectsAreEqual(listValue.Index(i).Interface(), element) { - return true, true - } - } - return true, false - -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") -func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - ok, found := containsElement(s, contains) - if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) - } - if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...) - } - - return true - -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") -func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - ok, found := containsElement(s, contains) - if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) - } - if found { - return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) - } - - return true - -} - -// Subset asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// assert.Subset(t, [1, 2, 3], [1, 2]) -// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1}) -func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if subset == nil { - return true // we consider nil to be equal to the nil set - } - - listKind := reflect.TypeOf(list).Kind() - if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) - } - - subsetKind := reflect.TypeOf(subset).Kind() - if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) - } - - if subsetKind == reflect.Map && listKind == reflect.Map { - subsetMap := reflect.ValueOf(subset) - actualMap := reflect.ValueOf(list) - - for _, k := range subsetMap.MapKeys() { - ev := subsetMap.MapIndex(k) - av := actualMap.MapIndex(k) - - if !av.IsValid() { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) - } - if !ObjectsAreEqual(ev.Interface(), av.Interface()) { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) - } - } - - return true - } - - subsetList := reflect.ValueOf(subset) - for i := 0; i < subsetList.Len(); i++ { - element := subsetList.Index(i).Interface() - ok, found := containsElement(list, element) - if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) - } - if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) - } - } - - return true -} - -// NotSubset asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// assert.NotSubset(t, [1, 3, 4], [1, 2]) -// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) -func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if subset == nil { - return Fail(t, "nil is the empty set which is a subset of every set", msgAndArgs...) - } - - listKind := reflect.TypeOf(list).Kind() - if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) - } - - subsetKind := reflect.TypeOf(subset).Kind() - if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) - } - - if subsetKind == reflect.Map && listKind == reflect.Map { - subsetMap := reflect.ValueOf(subset) - actualMap := reflect.ValueOf(list) - - for _, k := range subsetMap.MapKeys() { - ev := subsetMap.MapIndex(k) - av := actualMap.MapIndex(k) - - if !av.IsValid() { - return true - } - if !ObjectsAreEqual(ev.Interface(), av.Interface()) { - return true - } - } - - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) - } - - subsetList := reflect.ValueOf(subset) - for i := 0; i < subsetList.Len(); i++ { - element := subsetList.Index(i).Interface() - ok, found := containsElement(list, element) - if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) - } - if !found { - return true - } - } - - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) -} - -// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) -func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if isEmpty(listA) && isEmpty(listB) { - return true - } - - if !isList(t, listA, msgAndArgs...) || !isList(t, listB, msgAndArgs...) { - return false - } - - extraA, extraB := diffLists(listA, listB) - - if len(extraA) == 0 && len(extraB) == 0 { - return true - } - - return Fail(t, formatListDiff(listA, listB, extraA, extraB), msgAndArgs...) -} - -// isList checks that the provided value is array or slice. -func isList(t TestingT, list interface{}, msgAndArgs ...interface{}) (ok bool) { - kind := reflect.TypeOf(list).Kind() - if kind != reflect.Array && kind != reflect.Slice { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s, expecting array or slice", list, kind), - msgAndArgs...) - } - return true -} - -// diffLists diffs two arrays/slices and returns slices of elements that are only in A and only in B. -// If some element is present multiple times, each instance is counted separately (e.g. if something is 2x in A and -// 5x in B, it will be 0x in extraA and 3x in extraB). The order of items in both lists is ignored. -func diffLists(listA, listB interface{}) (extraA, extraB []interface{}) { - aValue := reflect.ValueOf(listA) - bValue := reflect.ValueOf(listB) - - aLen := aValue.Len() - bLen := bValue.Len() - - // Mark indexes in bValue that we already used - visited := make([]bool, bLen) - for i := 0; i < aLen; i++ { - element := aValue.Index(i).Interface() - found := false - for j := 0; j < bLen; j++ { - if visited[j] { - continue - } - if ObjectsAreEqual(bValue.Index(j).Interface(), element) { - visited[j] = true - found = true - break - } - } - if !found { - extraA = append(extraA, element) - } - } - - for j := 0; j < bLen; j++ { - if visited[j] { - continue - } - extraB = append(extraB, bValue.Index(j).Interface()) - } - - return -} - -func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) string { - var msg bytes.Buffer - - msg.WriteString("elements differ") - if len(extraA) > 0 { - msg.WriteString("\n\nextra elements in list A:\n") - msg.WriteString(spewConfig.Sdump(extraA)) - } - if len(extraB) > 0 { - msg.WriteString("\n\nextra elements in list B:\n") - msg.WriteString(spewConfig.Sdump(extraB)) - } - msg.WriteString("\n\nlistA:\n") - msg.WriteString(spewConfig.Sdump(listA)) - msg.WriteString("\n\nlistB:\n") - msg.WriteString(spewConfig.Sdump(listB)) - - return msg.String() -} - -// Condition uses a Comparison to assert a complex condition. -func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - result := comp() - if !result { - Fail(t, "Condition failed!", msgAndArgs...) - } - return result -} - -// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics -// methods, and represents a simple func that takes no arguments, and returns nothing. -type PanicTestFunc func() - -// didPanic returns true if the function passed to it panics. Otherwise, it returns false. -func didPanic(f PanicTestFunc) (didPanic bool, message interface{}, stack string) { - didPanic = true - - defer func() { - message = recover() - if didPanic { - stack = string(debug.Stack()) - } - }() - - // call the target function - f() - didPanic = false - - return -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// assert.Panics(t, func(){ GoCrazy() }) -func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic { - return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) - } - - return true -} - -// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) -func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - funcDidPanic, panicValue, panickedStack := didPanic(f) - if !funcDidPanic { - return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) - } - if panicValue != expected { - return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, expected, panicValue, panickedStack), msgAndArgs...) - } - - return true -} - -// PanicsWithError asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) -func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - funcDidPanic, panicValue, panickedStack := didPanic(f) - if !funcDidPanic { - return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) - } - panicErr, ok := panicValue.(error) - if !ok || panicErr.Error() != errString { - return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...) - } - - return true -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// assert.NotPanics(t, func(){ RemainCalm() }) -func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic { - return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v\n\tPanic stack:\t%s", f, panicValue, panickedStack), msgAndArgs...) - } - - return true -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) -func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - dt := expected.Sub(actual) - if dt < -delta || dt > delta { - return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) - } - - return true -} - -// WithinRange asserts that a time is within a time range (inclusive). -// -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) -func WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if end.Before(start) { - return Fail(t, "Start should be before end", msgAndArgs...) - } - - if actual.Before(start) { - return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is before the range", actual, start, end), msgAndArgs...) - } else if actual.After(end) { - return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is after the range", actual, start, end), msgAndArgs...) - } - - return true -} - -func toFloat(x interface{}) (float64, bool) { - var xf float64 - xok := true - - switch xn := x.(type) { - case uint: - xf = float64(xn) - case uint8: - xf = float64(xn) - case uint16: - xf = float64(xn) - case uint32: - xf = float64(xn) - case uint64: - xf = float64(xn) - case int: - xf = float64(xn) - case int8: - xf = float64(xn) - case int16: - xf = float64(xn) - case int32: - xf = float64(xn) - case int64: - xf = float64(xn) - case float32: - xf = float64(xn) - case float64: - xf = xn - case time.Duration: - xf = float64(xn) - default: - xok = false - } - - return xf, xok -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) -func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - af, aok := toFloat(expected) - bf, bok := toFloat(actual) - - if !aok || !bok { - return Fail(t, "Parameters must be numerical", msgAndArgs...) - } - - if math.IsNaN(af) && math.IsNaN(bf) { - return true - } - - if math.IsNaN(af) { - return Fail(t, "Expected must not be NaN", msgAndArgs...) - } - - if math.IsNaN(bf) { - return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) - } - - dt := af - bf - if dt < -delta || dt > delta { - return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) - } - - return true -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if expected == nil || actual == nil || - reflect.TypeOf(actual).Kind() != reflect.Slice || - reflect.TypeOf(expected).Kind() != reflect.Slice { - return Fail(t, "Parameters must be slice", msgAndArgs...) - } - - actualSlice := reflect.ValueOf(actual) - expectedSlice := reflect.ValueOf(expected) - - for i := 0; i < actualSlice.Len(); i++ { - result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...) - if !result { - return result - } - } - - return true -} - -// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if expected == nil || actual == nil || - reflect.TypeOf(actual).Kind() != reflect.Map || - reflect.TypeOf(expected).Kind() != reflect.Map { - return Fail(t, "Arguments must be maps", msgAndArgs...) - } - - expectedMap := reflect.ValueOf(expected) - actualMap := reflect.ValueOf(actual) - - if expectedMap.Len() != actualMap.Len() { - return Fail(t, "Arguments must have the same number of keys", msgAndArgs...) - } - - for _, k := range expectedMap.MapKeys() { - ev := expectedMap.MapIndex(k) - av := actualMap.MapIndex(k) - - if !ev.IsValid() { - return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...) - } - - if !av.IsValid() { - return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...) - } - - if !InDelta( - t, - ev.Interface(), - av.Interface(), - delta, - msgAndArgs..., - ) { - return false - } - } - - return true -} - -func calcRelativeError(expected, actual interface{}) (float64, error) { - af, aok := toFloat(expected) - bf, bok := toFloat(actual) - if !aok || !bok { - return 0, fmt.Errorf("Parameters must be numerical") - } - if math.IsNaN(af) && math.IsNaN(bf) { - return 0, nil - } - if math.IsNaN(af) { - return 0, errors.New("expected value must not be NaN") - } - if af == 0 { - return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") - } - if math.IsNaN(bf) { - return 0, errors.New("actual value must not be NaN") - } - - return math.Abs(af-bf) / math.Abs(af), nil -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if math.IsNaN(epsilon) { - return Fail(t, "epsilon must not be NaN", msgAndArgs...) - } - actualEpsilon, err := calcRelativeError(expected, actual) - if err != nil { - return Fail(t, err.Error(), msgAndArgs...) - } - if actualEpsilon > epsilon { - return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ - " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) - } - - return true -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - if expected == nil || actual == nil { - return Fail(t, "Parameters must be slice", msgAndArgs...) - } - - expectedSlice := reflect.ValueOf(expected) - actualSlice := reflect.ValueOf(actual) - - if expectedSlice.Type().Kind() != reflect.Slice { - return Fail(t, "Expected value must be slice", msgAndArgs...) - } - - expectedLen := expectedSlice.Len() - if !IsType(t, expected, actual) || !Len(t, actual, expectedLen) { - return false - } - - for i := 0; i < expectedLen; i++ { - if !InEpsilon(t, expectedSlice.Index(i).Interface(), actualSlice.Index(i).Interface(), epsilon, "at index %d", i) { - return false - } - } - - return true -} - -/* - Errors -*/ - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) -// } -func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { - if err != nil { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) - } - - return true -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if assert.Error(t, err) { -// assert.Equal(t, expectedError, err) -// } -func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { - if err == nil { - if h, ok := t.(tHelper); ok { - h.Helper() - } - return Fail(t, "An error is expected but got nil.", msgAndArgs...) - } - - return true -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) -func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if !Error(t, theError, msgAndArgs...) { - return false - } - expected := errString - actual := theError.Error() - // don't need to use deep equals here, we know they are both strings - if expected != actual { - return Fail(t, fmt.Sprintf("Error message not equal:\n"+ - "expected: %q\n"+ - "actual : %q", expected, actual), msgAndArgs...) - } - return true -} - -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) -func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if !Error(t, theError, msgAndArgs...) { - return false - } - - actual := theError.Error() - if !strings.Contains(actual, contains) { - return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...) - } - - return true -} - -// matchRegexp return true if a specified regexp matches a string. -func matchRegexp(rx interface{}, str interface{}) bool { - - var r *regexp.Regexp - if rr, ok := rx.(*regexp.Regexp); ok { - r = rr - } else { - r = regexp.MustCompile(fmt.Sprint(rx)) - } - - return (r.FindStringIndex(fmt.Sprint(str)) != nil) - -} - -// Regexp asserts that a specified regexp matches a string. -// -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") -func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - match := matchRegexp(rx, str) - - if !match { - Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) - } - - return match -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") -func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - match := matchRegexp(rx, str) - - if match { - Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) - } - - return !match - -} - -// Zero asserts that i is the zero value for its type. -func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) - } - return true -} - -// NotZero asserts that i is not the zero value for its type. -func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) - } - return true -} - -// FileExists checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - info, err := os.Lstat(path) - if err != nil { - if os.IsNotExist(err) { - return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) - } - return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) - } - if info.IsDir() { - return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...) - } - return true -} - -// NoFileExists checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - info, err := os.Lstat(path) - if err != nil { - return true - } - if info.IsDir() { - return true - } - return Fail(t, fmt.Sprintf("file %q exists", path), msgAndArgs...) -} - -// DirExists checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - info, err := os.Lstat(path) - if err != nil { - if os.IsNotExist(err) { - return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) - } - return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) - } - if !info.IsDir() { - return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...) - } - return true -} - -// NoDirExists checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - info, err := os.Lstat(path) - if err != nil { - if os.IsNotExist(err) { - return true - } - return true - } - if !info.IsDir() { - return true - } - return Fail(t, fmt.Sprintf("directory %q exists", path), msgAndArgs...) -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - var expectedJSONAsInterface, actualJSONAsInterface interface{} - - if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { - return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) - } - - if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { - return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) - } - - return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) -} - -// YAMLEq asserts that two YAML strings are equivalent. -func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - var expectedYAMLAsInterface, actualYAMLAsInterface interface{} - - if err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil { - return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...) - } - - if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil { - return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...) - } - - return Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...) -} - -func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { - t := reflect.TypeOf(v) - k := t.Kind() - - if k == reflect.Ptr { - t = t.Elem() - k = t.Kind() - } - return t, k -} - -// diff returns a diff of both values as long as both are of the same type and -// are a struct, map, slice, array or string. Otherwise it returns an empty string. -func diff(expected interface{}, actual interface{}) string { - if expected == nil || actual == nil { - return "" - } - - et, ek := typeAndKind(expected) - at, _ := typeAndKind(actual) - - if et != at { - return "" - } - - if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { - return "" - } - - var e, a string - - switch et { - case reflect.TypeOf(""): - e = reflect.ValueOf(expected).String() - a = reflect.ValueOf(actual).String() - case reflect.TypeOf(time.Time{}): - e = spewConfigStringerEnabled.Sdump(expected) - a = spewConfigStringerEnabled.Sdump(actual) - default: - e = spewConfig.Sdump(expected) - a = spewConfig.Sdump(actual) - } - - diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ - A: difflib.SplitLines(e), - B: difflib.SplitLines(a), - FromFile: "Expected", - FromDate: "", - ToFile: "Actual", - ToDate: "", - Context: 1, - }) - - return "\n\nDiff:\n" + diff -} - -func isFunction(arg interface{}) bool { - if arg == nil { - return false - } - return reflect.TypeOf(arg).Kind() == reflect.Func -} - -var spewConfig = spew.ConfigState{ - Indent: " ", - DisablePointerAddresses: true, - DisableCapacities: true, - SortKeys: true, - DisableMethods: true, - MaxDepth: 10, -} - -var spewConfigStringerEnabled = spew.ConfigState{ - Indent: " ", - DisablePointerAddresses: true, - DisableCapacities: true, - SortKeys: true, - MaxDepth: 10, -} - -type tHelper interface { - Helper() -} - -// Eventually asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) -func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - ch := make(chan bool, 1) - - timer := time.NewTimer(waitFor) - defer timer.Stop() - - ticker := time.NewTicker(tick) - defer ticker.Stop() - - for tick := ticker.C; ; { - select { - case <-timer.C: - return Fail(t, "Condition never satisfied", msgAndArgs...) - case <-tick: - tick = nil - go func() { ch <- condition() }() - case v := <-ch: - if v { - return true - } - tick = ticker.C - } - } -} - -// CollectT implements the TestingT interface and collects all errors. -type CollectT struct { - errors []error -} - -// Errorf collects the error. -func (c *CollectT) Errorf(format string, args ...interface{}) { - c.errors = append(c.errors, fmt.Errorf(format, args...)) -} - -// FailNow panics. -func (*CollectT) FailNow() { - panic("Assertion failed") -} - -// Deprecated: That was a method for internal usage that should not have been published. Now just panics. -func (*CollectT) Reset() { - panic("Reset() is deprecated") -} - -// Deprecated: That was a method for internal usage that should not have been published. Now just panics. -func (*CollectT) Copy(TestingT) { - panic("Copy() is deprecated") -} - -// EventuallyWithT asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// assert.EventuallyWithT(t, func(c *assert.CollectT) { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - var lastFinishedTickErrs []error - ch := make(chan []error, 1) - - timer := time.NewTimer(waitFor) - defer timer.Stop() - - ticker := time.NewTicker(tick) - defer ticker.Stop() - - for tick := ticker.C; ; { - select { - case <-timer.C: - for _, err := range lastFinishedTickErrs { - t.Errorf("%v", err) - } - return Fail(t, "Condition never satisfied", msgAndArgs...) - case <-tick: - tick = nil - go func() { - collect := new(CollectT) - defer func() { - ch <- collect.errors - }() - condition(collect) - }() - case errs := <-ch: - if len(errs) == 0 { - return true - } - // Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached. - lastFinishedTickErrs = errs - tick = ticker.C - } - } -} - -// Never asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) -func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - - ch := make(chan bool, 1) - - timer := time.NewTimer(waitFor) - defer timer.Stop() - - ticker := time.NewTicker(tick) - defer ticker.Stop() - - for tick := ticker.C; ; { - select { - case <-timer.C: - return true - case <-tick: - tick = nil - go func() { ch <- condition() }() - case v := <-ch: - if v { - return Fail(t, "Condition satisfied", msgAndArgs...) - } - tick = ticker.C - } - } -} - -// ErrorIs asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if errors.Is(err, target) { - return true - } - - var expectedText string - if target != nil { - expectedText = target.Error() - } - - chain := buildErrorChainString(err) - - return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+ - "expected: %q\n"+ - "in chain: %s", expectedText, chain, - ), msgAndArgs...) -} - -// NotErrorIs asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if !errors.Is(err, target) { - return true - } - - var expectedText string - if target != nil { - expectedText = target.Error() - } - - chain := buildErrorChainString(err) - - return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ - "found: %q\n"+ - "in chain: %s", expectedText, chain, - ), msgAndArgs...) -} - -// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if errors.As(err, target) { - return true - } - - chain := buildErrorChainString(err) - - return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ - "expected: %q\n"+ - "in chain: %s", target, chain, - ), msgAndArgs...) -} - -func buildErrorChainString(err error) string { - if err == nil { - return "" - } - - e := errors.Unwrap(err) - chain := fmt.Sprintf("%q", err.Error()) - for e != nil { - chain += fmt.Sprintf("\n\t%q", e.Error()) - e = errors.Unwrap(e) - } - return chain -} diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go deleted file mode 100644 index 4953981d..00000000 --- a/vendor/github.com/stretchr/testify/assert/doc.go +++ /dev/null @@ -1,46 +0,0 @@ -// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. -// -// # Example Usage -// -// The following is a complete example using assert in a standard test function: -// -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) -// -// func TestSomething(t *testing.T) { -// -// var a string = "Hello" -// var b string = "Hello" -// -// assert.Equal(t, a, b, "The two words should be the same.") -// -// } -// -// if you assert many times, use the format below: -// -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) -// -// func TestSomething(t *testing.T) { -// assert := assert.New(t) -// -// var a string = "Hello" -// var b string = "Hello" -// -// assert.Equal(a, b, "The two words should be the same.") -// } -// -// # Assertions -// -// Assertions allow you to easily write test code, and are global funcs in the `assert` package. -// All assertion functions take, as the first argument, the `*testing.T` object provided by the -// testing framework. This allows the assertion funcs to write the failings and other details to -// the correct place. -// -// Every assertion function also takes an optional string message as the final argument, -// allowing custom error messages to be appended to the message the assertion method outputs. -package assert diff --git a/vendor/github.com/stretchr/testify/assert/errors.go b/vendor/github.com/stretchr/testify/assert/errors.go deleted file mode 100644 index ac9dc9d1..00000000 --- a/vendor/github.com/stretchr/testify/assert/errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package assert - -import ( - "errors" -) - -// AnError is an error instance useful for testing. If the code does not care -// about error specifics, and only needs to return the error for example, this -// error should be used to make the test code more readable. -var AnError = errors.New("assert.AnError general error for testing") diff --git a/vendor/github.com/stretchr/testify/assert/forward_assertions.go b/vendor/github.com/stretchr/testify/assert/forward_assertions.go deleted file mode 100644 index df189d23..00000000 --- a/vendor/github.com/stretchr/testify/assert/forward_assertions.go +++ /dev/null @@ -1,16 +0,0 @@ -package assert - -// Assertions provides assertion methods around the -// TestingT interface. -type Assertions struct { - t TestingT -} - -// New makes a new Assertions object for the specified TestingT. -func New(t TestingT) *Assertions { - return &Assertions{ - t: t, - } -} - -//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs" diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go deleted file mode 100644 index 861ed4b7..00000000 --- a/vendor/github.com/stretchr/testify/assert/http_assertions.go +++ /dev/null @@ -1,165 +0,0 @@ -package assert - -import ( - "fmt" - "net/http" - "net/http/httptest" - "net/url" - "strings" -) - -// httpCode is a helper that returns HTTP code of the response. It returns -1 and -// an error if building a new request fails. -func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) { - w := httptest.NewRecorder() - req, err := http.NewRequest(method, url, http.NoBody) - if err != nil { - return -1, err - } - req.URL.RawQuery = values.Encode() - handler(w, req) - return w.Code, nil -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - code, err := httpCode(handler, method, url, values) - if err != nil { - Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...) - } - - isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent - if !isSuccessCode { - Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...) - } - - return isSuccessCode -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - code, err := httpCode(handler, method, url, values) - if err != nil { - Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...) - } - - isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect - if !isRedirectCode { - Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...) - } - - return isRedirectCode -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - code, err := httpCode(handler, method, url, values) - if err != nil { - Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...) - } - - isErrorCode := code >= http.StatusBadRequest - if !isErrorCode { - Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...) - } - - return isErrorCode -} - -// HTTPStatusCode asserts that a specified handler returns a specified status code. -// -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - code, err := httpCode(handler, method, url, values) - if err != nil { - Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...) - } - - successful := code == statuscode - if !successful { - Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code), msgAndArgs...) - } - - return successful -} - -// HTTPBody is a helper that returns HTTP body of the response. It returns -// empty string if building a new request fails. -func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { - w := httptest.NewRecorder() - if len(values) > 0 { - url += "?" + values.Encode() - } - req, err := http.NewRequest(method, url, http.NoBody) - if err != nil { - return "" - } - handler(w, req) - return w.Body.String() -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - body := HTTPBody(handler, method, url, values) - - contains := strings.Contains(body, fmt.Sprint(str)) - if !contains { - Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...) - } - - return contains -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { - if h, ok := t.(tHelper); ok { - h.Helper() - } - body := HTTPBody(handler, method, url, values) - - contains := strings.Contains(body, fmt.Sprint(str)) - if contains { - Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body), msgAndArgs...) - } - - return !contains -} diff --git a/vendor/github.com/stretchr/testify/require/doc.go b/vendor/github.com/stretchr/testify/require/doc.go deleted file mode 100644 index 96843472..00000000 --- a/vendor/github.com/stretchr/testify/require/doc.go +++ /dev/null @@ -1,29 +0,0 @@ -// Package require implements the same assertions as the `assert` package but -// stops test execution when a test fails. -// -// # Example Usage -// -// The following is a complete example using require in a standard test function: -// -// import ( -// "testing" -// "github.com/stretchr/testify/require" -// ) -// -// func TestSomething(t *testing.T) { -// -// var a string = "Hello" -// var b string = "Hello" -// -// require.Equal(t, a, b, "The two words should be the same.") -// -// } -// -// # Assertions -// -// The `require` package have same global functions as in the `assert` package, -// but instead of returning a boolean result they call `t.FailNow()`. -// -// Every assertion function also takes an optional string message as the final argument, -// allowing custom error messages to be appended to the message the assertion method outputs. -package require diff --git a/vendor/github.com/stretchr/testify/require/forward_requirements.go b/vendor/github.com/stretchr/testify/require/forward_requirements.go deleted file mode 100644 index 1dcb2338..00000000 --- a/vendor/github.com/stretchr/testify/require/forward_requirements.go +++ /dev/null @@ -1,16 +0,0 @@ -package require - -// Assertions provides assertion methods around the -// TestingT interface. -type Assertions struct { - t TestingT -} - -// New makes a new Assertions object for the specified TestingT. -func New(t TestingT) *Assertions { - return &Assertions{ - t: t, - } -} - -//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require_forward.go.tmpl -include-format-funcs" diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go deleted file mode 100644 index 506a82f8..00000000 --- a/vendor/github.com/stretchr/testify/require/require.go +++ /dev/null @@ -1,2060 +0,0 @@ -// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT. - -package require - -import ( - assert "github.com/stretchr/testify/assert" - http "net/http" - url "net/url" - time "time" -) - -// Condition uses a Comparison to assert a complex condition. -func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Condition(t, comp, msgAndArgs...) { - return - } - t.FailNow() -} - -// Conditionf uses a Comparison to assert a complex condition. -func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Conditionf(t, comp, msg, args...) { - return - } - t.FailNow() -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") -func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Contains(t, s, contains, msgAndArgs...) { - return - } - t.FailNow() -} - -// Containsf asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") -func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Containsf(t, s, contains, msg, args...) { - return - } - t.FailNow() -} - -// DirExists checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func DirExists(t TestingT, path string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.DirExists(t, path, msgAndArgs...) { - return - } - t.FailNow() -} - -// DirExistsf checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.DirExistsf(t, path, msg, args...) { - return - } - t.FailNow() -} - -// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) -func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ElementsMatch(t, listA, listB, msgAndArgs...) { - return - } - t.FailNow() -} - -// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") -func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ElementsMatchf(t, listA, listB, msg, args...) { - return - } - t.FailNow() -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// assert.Empty(t, obj) -func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Empty(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// assert.Emptyf(t, obj, "error message %s", "formatted") -func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Emptyf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// Equal asserts that two objects are equal. -// -// assert.Equal(t, 123, 123) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Equal(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) -func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EqualError(t, theError, errString, msgAndArgs...) { - return - } - t.FailNow() -} - -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") -func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EqualErrorf(t, theError, errString, msg, args...) { - return - } - t.FailNow() -} - -// EqualExportedValues asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true -// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false -func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EqualExportedValues(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// EqualExportedValuesf asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true -// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false -func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EqualExportedValuesf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. -// -// assert.EqualValues(t, uint32(123), int32(123)) -func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EqualValues(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. -// -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") -func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EqualValuesf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// Equalf asserts that two objects are equal. -// -// assert.Equalf(t, 123, 123, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Equalf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if assert.Error(t, err) { -// assert.Equal(t, expectedError, err) -// } -func Error(t TestingT, err error, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Error(t, err, msgAndArgs...) { - return - } - t.FailNow() -} - -// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ErrorAs(t, err, target, msgAndArgs...) { - return - } - t.FailNow() -} - -// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ErrorAsf(t, err, target, msg, args...) { - return - } - t.FailNow() -} - -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) -func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ErrorContains(t, theError, contains, msgAndArgs...) { - return - } - t.FailNow() -} - -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") -func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ErrorContainsf(t, theError, contains, msg, args...) { - return - } - t.FailNow() -} - -// ErrorIs asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ErrorIs(t, err, target, msgAndArgs...) { - return - } - t.FailNow() -} - -// ErrorIsf asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.ErrorIsf(t, err, target, msg, args...) { - return - } - t.FailNow() -} - -// Errorf asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } -func Errorf(t TestingT, err error, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Errorf(t, err, msg, args...) { - return - } - t.FailNow() -} - -// Eventually asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) -func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Eventually(t, condition, waitFor, tick, msgAndArgs...) { - return - } - t.FailNow() -} - -// EventuallyWithT asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// assert.EventuallyWithT(t, func(c *assert.CollectT) { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EventuallyWithT(t, condition, waitFor, tick, msgAndArgs...) { - return - } - t.FailNow() -} - -// EventuallyWithTf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.EventuallyWithTf(t, condition, waitFor, tick, msg, args...) { - return - } - t.FailNow() -} - -// Eventuallyf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Eventuallyf(t, condition, waitFor, tick, msg, args...) { - return - } - t.FailNow() -} - -// Exactly asserts that two objects are equal in value and type. -// -// assert.Exactly(t, int32(123), int64(123)) -func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Exactly(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// Exactlyf asserts that two objects are equal in value and type. -// -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") -func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Exactlyf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// Fail reports a failure through -func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Fail(t, failureMessage, msgAndArgs...) { - return - } - t.FailNow() -} - -// FailNow fails test -func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.FailNow(t, failureMessage, msgAndArgs...) { - return - } - t.FailNow() -} - -// FailNowf fails test -func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.FailNowf(t, failureMessage, msg, args...) { - return - } - t.FailNow() -} - -// Failf reports a failure through -func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Failf(t, failureMessage, msg, args...) { - return - } - t.FailNow() -} - -// False asserts that the specified value is false. -// -// assert.False(t, myBool) -func False(t TestingT, value bool, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.False(t, value, msgAndArgs...) { - return - } - t.FailNow() -} - -// Falsef asserts that the specified value is false. -// -// assert.Falsef(t, myBool, "error message %s", "formatted") -func Falsef(t TestingT, value bool, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Falsef(t, value, msg, args...) { - return - } - t.FailNow() -} - -// FileExists checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func FileExists(t TestingT, path string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.FileExists(t, path, msgAndArgs...) { - return - } - t.FailNow() -} - -// FileExistsf checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.FileExistsf(t, path, msg, args...) { - return - } - t.FailNow() -} - -// Greater asserts that the first element is greater than the second -// -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") -func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Greater(t, e1, e2, msgAndArgs...) { - return - } - t.FailNow() -} - -// GreaterOrEqual asserts that the first element is greater than or equal to the second -// -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") -func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.GreaterOrEqual(t, e1, e2, msgAndArgs...) { - return - } - t.FailNow() -} - -// GreaterOrEqualf asserts that the first element is greater than or equal to the second -// -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") -func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.GreaterOrEqualf(t, e1, e2, msg, args...) { - return - } - t.FailNow() -} - -// Greaterf asserts that the first element is greater than the second -// -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") -func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Greaterf(t, e1, e2, msg, args...) { - return - } - t.FailNow() -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPBodyContains(t, handler, method, url, values, str, msgAndArgs...) { - return - } - t.FailNow() -} - -// HTTPBodyContainsf asserts that a specified handler returns a -// body that contains a string. -// -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPBodyContainsf(t, handler, method, url, values, str, msg, args...) { - return - } - t.FailNow() -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPBodyNotContains(t, handler, method, url, values, str, msgAndArgs...) { - return - } - t.FailNow() -} - -// HTTPBodyNotContainsf asserts that a specified handler returns a -// body that does not contain a string. -// -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPBodyNotContainsf(t, handler, method, url, values, str, msg, args...) { - return - } - t.FailNow() -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPError(t, handler, method, url, values, msgAndArgs...) { - return - } - t.FailNow() -} - -// HTTPErrorf asserts that a specified handler returns an error status code. -// -// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPErrorf(t, handler, method, url, values, msg, args...) { - return - } - t.FailNow() -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPRedirect(t, handler, method, url, values, msgAndArgs...) { - return - } - t.FailNow() -} - -// HTTPRedirectf asserts that a specified handler returns a redirect status code. -// -// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPRedirectf(t, handler, method, url, values, msg, args...) { - return - } - t.FailNow() -} - -// HTTPStatusCode asserts that a specified handler returns a specified status code. -// -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPStatusCode(t, handler, method, url, values, statuscode, msgAndArgs...) { - return - } - t.FailNow() -} - -// HTTPStatusCodef asserts that a specified handler returns a specified status code. -// -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPStatusCodef(t, handler, method, url, values, statuscode, msg, args...) { - return - } - t.FailNow() -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPSuccess(t, handler, method, url, values, msgAndArgs...) { - return - } - t.FailNow() -} - -// HTTPSuccessf asserts that a specified handler returns a success status code. -// -// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.HTTPSuccessf(t, handler, method, url, values, msg, args...) { - return - } - t.FailNow() -} - -// Implements asserts that an object is implemented by the specified interface. -// -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) -func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Implements(t, interfaceObject, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// Implementsf asserts that an object is implemented by the specified interface. -// -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Implementsf(t, interfaceObject, object, msg, args...) { - return - } - t.FailNow() -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) -func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InDelta(t, expected, actual, delta, msgAndArgs...) { - return - } - t.FailNow() -} - -// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) { - return - } - t.FailNow() -} - -// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) { - return - } - t.FailNow() -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) { - return - } - t.FailNow() -} - -// InDeltaSlicef is the same as InDelta, except it compares two slices. -func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) { - return - } - t.FailNow() -} - -// InDeltaf asserts that the two numerals are within delta of each other. -// -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") -func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InDeltaf(t, expected, actual, delta, msg, args...) { - return - } - t.FailNow() -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) { - return - } - t.FailNow() -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) { - return - } - t.FailNow() -} - -// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. -func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) { - return - } - t.FailNow() -} - -// InEpsilonf asserts that expected and actual have a relative error less than epsilon -func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) { - return - } - t.FailNow() -} - -// IsDecreasing asserts that the collection is decreasing -// -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) -func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsDecreasing(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// IsDecreasingf asserts that the collection is decreasing -// -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsDecreasingf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// IsIncreasing asserts that the collection is increasing -// -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) -func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsIncreasing(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// IsIncreasingf asserts that the collection is increasing -// -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsIncreasingf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// IsNonDecreasing asserts that the collection is not decreasing -// -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) -func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsNonDecreasing(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// IsNonDecreasingf asserts that the collection is not decreasing -// -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") -func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsNonDecreasingf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// IsNonIncreasing asserts that the collection is not increasing -// -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) -func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsNonIncreasing(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// IsNonIncreasingf asserts that the collection is not increasing -// -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") -func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsNonIncreasingf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// IsType asserts that the specified objects are of the same type. -func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsType(t, expectedType, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// IsTypef asserts that the specified objects are of the same type. -func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.IsTypef(t, expectedType, object, msg, args...) { - return - } - t.FailNow() -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.JSONEq(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// JSONEqf asserts that two JSON strings are equivalent. -// -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") -func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.JSONEqf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// assert.Len(t, mySlice, 3) -func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Len(t, object, length, msgAndArgs...) { - return - } - t.FailNow() -} - -// Lenf asserts that the specified object has specific length. -// Lenf also fails if the object has a type that len() not accept. -// -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") -func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Lenf(t, object, length, msg, args...) { - return - } - t.FailNow() -} - -// Less asserts that the first element is less than the second -// -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") -func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Less(t, e1, e2, msgAndArgs...) { - return - } - t.FailNow() -} - -// LessOrEqual asserts that the first element is less than or equal to the second -// -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") -func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.LessOrEqual(t, e1, e2, msgAndArgs...) { - return - } - t.FailNow() -} - -// LessOrEqualf asserts that the first element is less than or equal to the second -// -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") -func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.LessOrEqualf(t, e1, e2, msg, args...) { - return - } - t.FailNow() -} - -// Lessf asserts that the first element is less than the second -// -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") -func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Lessf(t, e1, e2, msg, args...) { - return - } - t.FailNow() -} - -// Negative asserts that the specified element is negative -// -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) -func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Negative(t, e, msgAndArgs...) { - return - } - t.FailNow() -} - -// Negativef asserts that the specified element is negative -// -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") -func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Negativef(t, e, msg, args...) { - return - } - t.FailNow() -} - -// Never asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) -func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Never(t, condition, waitFor, tick, msgAndArgs...) { - return - } - t.FailNow() -} - -// Neverf asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Neverf(t, condition, waitFor, tick, msg, args...) { - return - } - t.FailNow() -} - -// Nil asserts that the specified object is nil. -// -// assert.Nil(t, err) -func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Nil(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// Nilf asserts that the specified object is nil. -// -// assert.Nilf(t, err, "error message %s", "formatted") -func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Nilf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// NoDirExists checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NoDirExists(t, path, msgAndArgs...) { - return - } - t.FailNow() -} - -// NoDirExistsf checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NoDirExistsf(t, path, msg, args...) { - return - } - t.FailNow() -} - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) -// } -func NoError(t TestingT, err error, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NoError(t, err, msgAndArgs...) { - return - } - t.FailNow() -} - -// NoErrorf asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } -func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NoErrorf(t, err, msg, args...) { - return - } - t.FailNow() -} - -// NoFileExists checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NoFileExists(t, path, msgAndArgs...) { - return - } - t.FailNow() -} - -// NoFileExistsf checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NoFileExistsf(t, path, msg, args...) { - return - } - t.FailNow() -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") -func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotContains(t, s, contains, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") -func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotContainsf(t, s, contains, msg, args...) { - return - } - t.FailNow() -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } -func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotEmpty(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } -func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotEmptyf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// NotEqual asserts that the specified values are NOT equal. -// -// assert.NotEqual(t, obj1, obj2) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotEqual(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotEqualValues asserts that two objects are not equal even when converted to the same type -// -// assert.NotEqualValues(t, obj1, obj2) -func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotEqualValues(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotEqualValuesf asserts that two objects are not equal even when converted to the same type -// -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") -func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotEqualValuesf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// NotEqualf asserts that the specified values are NOT equal. -// -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotEqualf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// NotErrorIs asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotErrorIs(t, err, target, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotErrorIsf asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotErrorIsf(t, err, target, msg, args...) { - return - } - t.FailNow() -} - -// NotImplements asserts that an object does not implement the specified interface. -// -// assert.NotImplements(t, (*MyInterface)(nil), new(MyObject)) -func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotImplements(t, interfaceObject, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotImplementsf asserts that an object does not implement the specified interface. -// -// assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotImplementsf(t, interfaceObject, object, msg, args...) { - return - } - t.FailNow() -} - -// NotNil asserts that the specified object is not nil. -// -// assert.NotNil(t, err) -func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotNil(t, object, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotNilf asserts that the specified object is not nil. -// -// assert.NotNilf(t, err, "error message %s", "formatted") -func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotNilf(t, object, msg, args...) { - return - } - t.FailNow() -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// assert.NotPanics(t, func(){ RemainCalm() }) -func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotPanics(t, f, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") -func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotPanicsf(t, f, msg, args...) { - return - } - t.FailNow() -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") -func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotRegexp(t, rx, str, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotRegexpf asserts that a specified regexp does not match a string. -// -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") -func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotRegexpf(t, rx, str, msg, args...) { - return - } - t.FailNow() -} - -// NotSame asserts that two pointers do not reference the same object. -// -// assert.NotSame(t, ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotSame(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotSamef asserts that two pointers do not reference the same object. -// -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotSamef(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// NotSubset asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// assert.NotSubset(t, [1, 3, 4], [1, 2]) -// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) -func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotSubset(t, list, subset, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotSubsetf asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") -// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") -func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotSubsetf(t, list, subset, msg, args...) { - return - } - t.FailNow() -} - -// NotZero asserts that i is not the zero value for its type. -func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotZero(t, i, msgAndArgs...) { - return - } - t.FailNow() -} - -// NotZerof asserts that i is not the zero value for its type. -func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.NotZerof(t, i, msg, args...) { - return - } - t.FailNow() -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// assert.Panics(t, func(){ GoCrazy() }) -func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Panics(t, f, msgAndArgs...) { - return - } - t.FailNow() -} - -// PanicsWithError asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) -func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.PanicsWithError(t, errString, f, msgAndArgs...) { - return - } - t.FailNow() -} - -// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.PanicsWithErrorf(t, errString, f, msg, args...) { - return - } - t.FailNow() -} - -// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) -func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.PanicsWithValue(t, expected, f, msgAndArgs...) { - return - } - t.FailNow() -} - -// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.PanicsWithValuef(t, expected, f, msg, args...) { - return - } - t.FailNow() -} - -// Panicsf asserts that the code inside the specified PanicTestFunc panics. -// -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") -func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Panicsf(t, f, msg, args...) { - return - } - t.FailNow() -} - -// Positive asserts that the specified element is positive -// -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) -func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Positive(t, e, msgAndArgs...) { - return - } - t.FailNow() -} - -// Positivef asserts that the specified element is positive -// -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") -func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Positivef(t, e, msg, args...) { - return - } - t.FailNow() -} - -// Regexp asserts that a specified regexp matches a string. -// -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") -func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Regexp(t, rx, str, msgAndArgs...) { - return - } - t.FailNow() -} - -// Regexpf asserts that a specified regexp matches a string. -// -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") -func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Regexpf(t, rx, str, msg, args...) { - return - } - t.FailNow() -} - -// Same asserts that two pointers reference the same object. -// -// assert.Same(t, ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Same(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// Samef asserts that two pointers reference the same object. -// -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Samef(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// Subset asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// assert.Subset(t, [1, 2, 3], [1, 2]) -// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1}) -func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Subset(t, list, subset, msgAndArgs...) { - return - } - t.FailNow() -} - -// Subsetf asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") -// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") -func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Subsetf(t, list, subset, msg, args...) { - return - } - t.FailNow() -} - -// True asserts that the specified value is true. -// -// assert.True(t, myBool) -func True(t TestingT, value bool, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.True(t, value, msgAndArgs...) { - return - } - t.FailNow() -} - -// Truef asserts that the specified value is true. -// -// assert.Truef(t, myBool, "error message %s", "formatted") -func Truef(t TestingT, value bool, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Truef(t, value, msg, args...) { - return - } - t.FailNow() -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) -func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) { - return - } - t.FailNow() -} - -// WithinDurationf asserts that the two times are within duration delta of each other. -// -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") -func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.WithinDurationf(t, expected, actual, delta, msg, args...) { - return - } - t.FailNow() -} - -// WithinRange asserts that a time is within a time range (inclusive). -// -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) -func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.WithinRange(t, actual, start, end, msgAndArgs...) { - return - } - t.FailNow() -} - -// WithinRangef asserts that a time is within a time range (inclusive). -// -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") -func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.WithinRangef(t, actual, start, end, msg, args...) { - return - } - t.FailNow() -} - -// YAMLEq asserts that two YAML strings are equivalent. -func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.YAMLEq(t, expected, actual, msgAndArgs...) { - return - } - t.FailNow() -} - -// YAMLEqf asserts that two YAML strings are equivalent. -func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.YAMLEqf(t, expected, actual, msg, args...) { - return - } - t.FailNow() -} - -// Zero asserts that i is the zero value for its type. -func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Zero(t, i, msgAndArgs...) { - return - } - t.FailNow() -} - -// Zerof asserts that i is the zero value for its type. -func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) { - if h, ok := t.(tHelper); ok { - h.Helper() - } - if assert.Zerof(t, i, msg, args...) { - return - } - t.FailNow() -} diff --git a/vendor/github.com/stretchr/testify/require/require.go.tmpl b/vendor/github.com/stretchr/testify/require/require.go.tmpl deleted file mode 100644 index 55e42dde..00000000 --- a/vendor/github.com/stretchr/testify/require/require.go.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -{{.Comment}} -func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { - if h, ok := t.(tHelper); ok { h.Helper() } - if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } - t.FailNow() -} diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go deleted file mode 100644 index eee8310a..00000000 --- a/vendor/github.com/stretchr/testify/require/require_forward.go +++ /dev/null @@ -1,1622 +0,0 @@ -// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT. - -package require - -import ( - assert "github.com/stretchr/testify/assert" - http "net/http" - url "net/url" - time "time" -) - -// Condition uses a Comparison to assert a complex condition. -func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Condition(a.t, comp, msgAndArgs...) -} - -// Conditionf uses a Comparison to assert a complex condition. -func (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Conditionf(a.t, comp, msg, args...) -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// a.Contains("Hello World", "World") -// a.Contains(["Hello", "World"], "World") -// a.Contains({"Hello": "World"}, "Hello") -func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Contains(a.t, s, contains, msgAndArgs...) -} - -// Containsf asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// a.Containsf("Hello World", "World", "error message %s", "formatted") -// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") -// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") -func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Containsf(a.t, s, contains, msg, args...) -} - -// DirExists checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - DirExists(a.t, path, msgAndArgs...) -} - -// DirExistsf checks whether a directory exists in the given path. It also fails -// if the path is a file rather a directory or there is an error checking whether it exists. -func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - DirExistsf(a.t, path, msg, args...) -} - -// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]) -func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ElementsMatch(a.t, listA, listB, msgAndArgs...) -} - -// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified -// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, -// the number of appearances of each of them in both lists should match. -// -// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") -func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ElementsMatchf(a.t, listA, listB, msg, args...) -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// a.Empty(obj) -func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Empty(a.t, object, msgAndArgs...) -} - -// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// a.Emptyf(obj, "error message %s", "formatted") -func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Emptyf(a.t, object, msg, args...) -} - -// Equal asserts that two objects are equal. -// -// a.Equal(123, 123) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Equal(a.t, expected, actual, msgAndArgs...) -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString) -func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EqualError(a.t, theError, errString, msgAndArgs...) -} - -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") -func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EqualErrorf(a.t, theError, errString, msg, args...) -} - -// EqualExportedValues asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// a.EqualExportedValues(S{1, 2}, S{1, 3}) => true -// a.EqualExportedValues(S{1, 2}, S{2, 3}) => false -func (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EqualExportedValues(a.t, expected, actual, msgAndArgs...) -} - -// EqualExportedValuesf asserts that the types of two objects are equal and their public -// fields are also equal. This is useful for comparing structs that have private fields -// that could potentially differ. -// -// type S struct { -// Exported int -// notExported int -// } -// a.EqualExportedValuesf(S{1, 2}, S{1, 3}, "error message %s", "formatted") => true -// a.EqualExportedValuesf(S{1, 2}, S{2, 3}, "error message %s", "formatted") => false -func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EqualExportedValuesf(a.t, expected, actual, msg, args...) -} - -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. -// -// a.EqualValues(uint32(123), int32(123)) -func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EqualValues(a.t, expected, actual, msgAndArgs...) -} - -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. -// -// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") -func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EqualValuesf(a.t, expected, actual, msg, args...) -} - -// Equalf asserts that two objects are equal. -// -// a.Equalf(123, 123, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). Function equality -// cannot be determined and will always fail. -func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Equalf(a.t, expected, actual, msg, args...) -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if a.Error(err) { -// assert.Equal(t, expectedError, err) -// } -func (a *Assertions) Error(err error, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Error(a.t, err, msgAndArgs...) -} - -// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ErrorAs(a.t, err, target, msgAndArgs...) -} - -// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. -// This is a wrapper for errors.As. -func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ErrorAsf(a.t, err, target, msg, args...) -} - -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// a.ErrorContains(err, expectedErrorSubString) -func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ErrorContains(a.t, theError, contains, msgAndArgs...) -} - -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. -// -// actualObj, err := SomeFunction() -// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") -func (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ErrorContainsf(a.t, theError, contains, msg, args...) -} - -// ErrorIs asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ErrorIs(a.t, err, target, msgAndArgs...) -} - -// ErrorIsf asserts that at least one of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - ErrorIsf(a.t, err, target, msg, args...) -} - -// Errorf asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if a.Errorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } -func (a *Assertions) Errorf(err error, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Errorf(a.t, err, msg, args...) -} - -// Eventually asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) -func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Eventually(a.t, condition, waitFor, tick, msgAndArgs...) -} - -// EventuallyWithT asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// a.EventuallyWithT(func(c *assert.CollectT) { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...) -} - -// EventuallyWithTf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. In contrast to Eventually, -// it supplies a CollectT to the condition function, so that the condition -// function can use the CollectT to call other assertions. -// The condition is considered "met" if no errors are raised in a tick. -// The supplied CollectT collects all errors from one tick (if there are any). -// If the condition is not met before waitFor, the collected errors of -// the last tick are copied to t. -// -// externalValue := false -// go func() { -// time.Sleep(8*time.Second) -// externalValue = true -// }() -// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { -// // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") -func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...) -} - -// Eventuallyf asserts that given condition will be met in waitFor time, -// periodically checking target function each tick. -// -// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Eventuallyf(a.t, condition, waitFor, tick, msg, args...) -} - -// Exactly asserts that two objects are equal in value and type. -// -// a.Exactly(int32(123), int64(123)) -func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Exactly(a.t, expected, actual, msgAndArgs...) -} - -// Exactlyf asserts that two objects are equal in value and type. -// -// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") -func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Exactlyf(a.t, expected, actual, msg, args...) -} - -// Fail reports a failure through -func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Fail(a.t, failureMessage, msgAndArgs...) -} - -// FailNow fails test -func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - FailNow(a.t, failureMessage, msgAndArgs...) -} - -// FailNowf fails test -func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - FailNowf(a.t, failureMessage, msg, args...) -} - -// Failf reports a failure through -func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Failf(a.t, failureMessage, msg, args...) -} - -// False asserts that the specified value is false. -// -// a.False(myBool) -func (a *Assertions) False(value bool, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - False(a.t, value, msgAndArgs...) -} - -// Falsef asserts that the specified value is false. -// -// a.Falsef(myBool, "error message %s", "formatted") -func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Falsef(a.t, value, msg, args...) -} - -// FileExists checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - FileExists(a.t, path, msgAndArgs...) -} - -// FileExistsf checks whether a file exists in the given path. It also fails if -// the path points to a directory or there is an error when trying to check the file. -func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - FileExistsf(a.t, path, msg, args...) -} - -// Greater asserts that the first element is greater than the second -// -// a.Greater(2, 1) -// a.Greater(float64(2), float64(1)) -// a.Greater("b", "a") -func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Greater(a.t, e1, e2, msgAndArgs...) -} - -// GreaterOrEqual asserts that the first element is greater than or equal to the second -// -// a.GreaterOrEqual(2, 1) -// a.GreaterOrEqual(2, 2) -// a.GreaterOrEqual("b", "a") -// a.GreaterOrEqual("b", "b") -func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - GreaterOrEqual(a.t, e1, e2, msgAndArgs...) -} - -// GreaterOrEqualf asserts that the first element is greater than or equal to the second -// -// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") -// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") -// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") -// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") -func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - GreaterOrEqualf(a.t, e1, e2, msg, args...) -} - -// Greaterf asserts that the first element is greater than the second -// -// a.Greaterf(2, 1, "error message %s", "formatted") -// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") -// a.Greaterf("b", "a", "error message %s", "formatted") -func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Greaterf(a.t, e1, e2, msg, args...) -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...) -} - -// HTTPBodyContainsf asserts that a specified handler returns a -// body that contains a string. -// -// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...) -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...) -} - -// HTTPBodyNotContainsf asserts that a specified handler returns a -// body that does not contain a string. -// -// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...) -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPError(a.t, handler, method, url, values, msgAndArgs...) -} - -// HTTPErrorf asserts that a specified handler returns an error status code. -// -// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPErrorf(a.t, handler, method, url, values, msg, args...) -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...) -} - -// HTTPRedirectf asserts that a specified handler returns a redirect status code. -// -// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPRedirectf(a.t, handler, method, url, values, msg, args...) -} - -// HTTPStatusCode asserts that a specified handler returns a specified status code. -// -// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPStatusCode(a.t, handler, method, url, values, statuscode, msgAndArgs...) -} - -// HTTPStatusCodef asserts that a specified handler returns a specified status code. -// -// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPStatusCodef(a.t, handler, method, url, values, statuscode, msg, args...) -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...) -} - -// HTTPSuccessf asserts that a specified handler returns a success status code. -// -// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - HTTPSuccessf(a.t, handler, method, url, values, msg, args...) -} - -// Implements asserts that an object is implemented by the specified interface. -// -// a.Implements((*MyInterface)(nil), new(MyObject)) -func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Implements(a.t, interfaceObject, object, msgAndArgs...) -} - -// Implementsf asserts that an object is implemented by the specified interface. -// -// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Implementsf(a.t, interfaceObject, object, msg, args...) -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// a.InDelta(math.Pi, 22/7.0, 0.01) -func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InDelta(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. -func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...) -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaSlicef is the same as InDelta, except it compares two slices. -func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InDeltaSlicef(a.t, expected, actual, delta, msg, args...) -} - -// InDeltaf asserts that the two numerals are within delta of each other. -// -// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") -func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InDeltaf(a.t, expected, actual, delta, msg, args...) -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. -func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...) -} - -// InEpsilonf asserts that expected and actual have a relative error less than epsilon -func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - InEpsilonf(a.t, expected, actual, epsilon, msg, args...) -} - -// IsDecreasing asserts that the collection is decreasing -// -// a.IsDecreasing([]int{2, 1, 0}) -// a.IsDecreasing([]float{2, 1}) -// a.IsDecreasing([]string{"b", "a"}) -func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsDecreasing(a.t, object, msgAndArgs...) -} - -// IsDecreasingf asserts that the collection is decreasing -// -// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") -// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") -func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsDecreasingf(a.t, object, msg, args...) -} - -// IsIncreasing asserts that the collection is increasing -// -// a.IsIncreasing([]int{1, 2, 3}) -// a.IsIncreasing([]float{1, 2}) -// a.IsIncreasing([]string{"a", "b"}) -func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsIncreasing(a.t, object, msgAndArgs...) -} - -// IsIncreasingf asserts that the collection is increasing -// -// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") -// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") -func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsIncreasingf(a.t, object, msg, args...) -} - -// IsNonDecreasing asserts that the collection is not decreasing -// -// a.IsNonDecreasing([]int{1, 1, 2}) -// a.IsNonDecreasing([]float{1, 2}) -// a.IsNonDecreasing([]string{"a", "b"}) -func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsNonDecreasing(a.t, object, msgAndArgs...) -} - -// IsNonDecreasingf asserts that the collection is not decreasing -// -// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") -func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsNonDecreasingf(a.t, object, msg, args...) -} - -// IsNonIncreasing asserts that the collection is not increasing -// -// a.IsNonIncreasing([]int{2, 1, 1}) -// a.IsNonIncreasing([]float{2, 1}) -// a.IsNonIncreasing([]string{"b", "a"}) -func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsNonIncreasing(a.t, object, msgAndArgs...) -} - -// IsNonIncreasingf asserts that the collection is not increasing -// -// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") -func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsNonIncreasingf(a.t, object, msg, args...) -} - -// IsType asserts that the specified objects are of the same type. -func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsType(a.t, expectedType, object, msgAndArgs...) -} - -// IsTypef asserts that the specified objects are of the same type. -func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - IsTypef(a.t, expectedType, object, msg, args...) -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - JSONEq(a.t, expected, actual, msgAndArgs...) -} - -// JSONEqf asserts that two JSON strings are equivalent. -// -// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") -func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - JSONEqf(a.t, expected, actual, msg, args...) -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// a.Len(mySlice, 3) -func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Len(a.t, object, length, msgAndArgs...) -} - -// Lenf asserts that the specified object has specific length. -// Lenf also fails if the object has a type that len() not accept. -// -// a.Lenf(mySlice, 3, "error message %s", "formatted") -func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Lenf(a.t, object, length, msg, args...) -} - -// Less asserts that the first element is less than the second -// -// a.Less(1, 2) -// a.Less(float64(1), float64(2)) -// a.Less("a", "b") -func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Less(a.t, e1, e2, msgAndArgs...) -} - -// LessOrEqual asserts that the first element is less than or equal to the second -// -// a.LessOrEqual(1, 2) -// a.LessOrEqual(2, 2) -// a.LessOrEqual("a", "b") -// a.LessOrEqual("b", "b") -func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - LessOrEqual(a.t, e1, e2, msgAndArgs...) -} - -// LessOrEqualf asserts that the first element is less than or equal to the second -// -// a.LessOrEqualf(1, 2, "error message %s", "formatted") -// a.LessOrEqualf(2, 2, "error message %s", "formatted") -// a.LessOrEqualf("a", "b", "error message %s", "formatted") -// a.LessOrEqualf("b", "b", "error message %s", "formatted") -func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - LessOrEqualf(a.t, e1, e2, msg, args...) -} - -// Lessf asserts that the first element is less than the second -// -// a.Lessf(1, 2, "error message %s", "formatted") -// a.Lessf(float64(1), float64(2), "error message %s", "formatted") -// a.Lessf("a", "b", "error message %s", "formatted") -func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Lessf(a.t, e1, e2, msg, args...) -} - -// Negative asserts that the specified element is negative -// -// a.Negative(-1) -// a.Negative(-1.23) -func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Negative(a.t, e, msgAndArgs...) -} - -// Negativef asserts that the specified element is negative -// -// a.Negativef(-1, "error message %s", "formatted") -// a.Negativef(-1.23, "error message %s", "formatted") -func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Negativef(a.t, e, msg, args...) -} - -// Never asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) -func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Never(a.t, condition, waitFor, tick, msgAndArgs...) -} - -// Neverf asserts that the given condition doesn't satisfy in waitFor time, -// periodically checking the target function each tick. -// -// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") -func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Neverf(a.t, condition, waitFor, tick, msg, args...) -} - -// Nil asserts that the specified object is nil. -// -// a.Nil(err) -func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Nil(a.t, object, msgAndArgs...) -} - -// Nilf asserts that the specified object is nil. -// -// a.Nilf(err, "error message %s", "formatted") -func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Nilf(a.t, object, msg, args...) -} - -// NoDirExists checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NoDirExists(a.t, path, msgAndArgs...) -} - -// NoDirExistsf checks whether a directory does not exist in the given path. -// It fails if the path points to an existing _directory_ only. -func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NoDirExistsf(a.t, path, msg, args...) -} - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } -func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NoError(a.t, err, msgAndArgs...) -} - -// NoErrorf asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } -func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NoErrorf(a.t, err, msg, args...) -} - -// NoFileExists checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NoFileExists(a.t, path, msgAndArgs...) -} - -// NoFileExistsf checks whether a file does not exist in a given path. It fails -// if the path points to an existing _file_ only. -func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NoFileExistsf(a.t, path, msg, args...) -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// a.NotContains("Hello World", "Earth") -// a.NotContains(["Hello", "World"], "Earth") -// a.NotContains({"Hello": "World"}, "Earth") -func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotContains(a.t, s, contains, msgAndArgs...) -} - -// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") -// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") -// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") -func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotContainsf(a.t, s, contains, msg, args...) -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } -func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotEmpty(a.t, object, msgAndArgs...) -} - -// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } -func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotEmptyf(a.t, object, msg, args...) -} - -// NotEqual asserts that the specified values are NOT equal. -// -// a.NotEqual(obj1, obj2) -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotEqual(a.t, expected, actual, msgAndArgs...) -} - -// NotEqualValues asserts that two objects are not equal even when converted to the same type -// -// a.NotEqualValues(obj1, obj2) -func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotEqualValues(a.t, expected, actual, msgAndArgs...) -} - -// NotEqualValuesf asserts that two objects are not equal even when converted to the same type -// -// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") -func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotEqualValuesf(a.t, expected, actual, msg, args...) -} - -// NotEqualf asserts that the specified values are NOT equal. -// -// a.NotEqualf(obj1, obj2, "error message %s", "formatted") -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotEqualf(a.t, expected, actual, msg, args...) -} - -// NotErrorIs asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotErrorIs(a.t, err, target, msgAndArgs...) -} - -// NotErrorIsf asserts that at none of the errors in err's chain matches target. -// This is a wrapper for errors.Is. -func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotErrorIsf(a.t, err, target, msg, args...) -} - -// NotImplements asserts that an object does not implement the specified interface. -// -// a.NotImplements((*MyInterface)(nil), new(MyObject)) -func (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotImplements(a.t, interfaceObject, object, msgAndArgs...) -} - -// NotImplementsf asserts that an object does not implement the specified interface. -// -// a.NotImplementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") -func (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotImplementsf(a.t, interfaceObject, object, msg, args...) -} - -// NotNil asserts that the specified object is not nil. -// -// a.NotNil(err) -func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotNil(a.t, object, msgAndArgs...) -} - -// NotNilf asserts that the specified object is not nil. -// -// a.NotNilf(err, "error message %s", "formatted") -func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotNilf(a.t, object, msg, args...) -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// a.NotPanics(func(){ RemainCalm() }) -func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotPanics(a.t, f, msgAndArgs...) -} - -// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") -func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotPanicsf(a.t, f, msg, args...) -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") -func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotRegexp(a.t, rx, str, msgAndArgs...) -} - -// NotRegexpf asserts that a specified regexp does not match a string. -// -// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") -func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotRegexpf(a.t, rx, str, msg, args...) -} - -// NotSame asserts that two pointers do not reference the same object. -// -// a.NotSame(ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotSame(a.t, expected, actual, msgAndArgs...) -} - -// NotSamef asserts that two pointers do not reference the same object. -// -// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotSamef(a.t, expected, actual, msg, args...) -} - -// NotSubset asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// a.NotSubset([1, 3, 4], [1, 2]) -// a.NotSubset({"x": 1, "y": 2}, {"z": 3}) -func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotSubset(a.t, list, subset, msgAndArgs...) -} - -// NotSubsetf asserts that the specified list(array, slice...) or map does NOT -// contain all elements given in the specified subset list(array, slice...) or -// map. -// -// a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted") -// a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") -func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotSubsetf(a.t, list, subset, msg, args...) -} - -// NotZero asserts that i is not the zero value for its type. -func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotZero(a.t, i, msgAndArgs...) -} - -// NotZerof asserts that i is not the zero value for its type. -func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - NotZerof(a.t, i, msg, args...) -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// a.Panics(func(){ GoCrazy() }) -func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Panics(a.t, f, msgAndArgs...) -} - -// PanicsWithError asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// a.PanicsWithError("crazy error", func(){ GoCrazy() }) -func (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - PanicsWithError(a.t, errString, f, msgAndArgs...) -} - -// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc -// panics, and that the recovered panic value is an error that satisfies the -// EqualError comparison. -// -// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - PanicsWithErrorf(a.t, errString, f, msg, args...) -} - -// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) -func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - PanicsWithValue(a.t, expected, f, msgAndArgs...) -} - -// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that -// the recovered panic value equals the expected panic value. -// -// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") -func (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - PanicsWithValuef(a.t, expected, f, msg, args...) -} - -// Panicsf asserts that the code inside the specified PanicTestFunc panics. -// -// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") -func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Panicsf(a.t, f, msg, args...) -} - -// Positive asserts that the specified element is positive -// -// a.Positive(1) -// a.Positive(1.23) -func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Positive(a.t, e, msgAndArgs...) -} - -// Positivef asserts that the specified element is positive -// -// a.Positivef(1, "error message %s", "formatted") -// a.Positivef(1.23, "error message %s", "formatted") -func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Positivef(a.t, e, msg, args...) -} - -// Regexp asserts that a specified regexp matches a string. -// -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") -func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Regexp(a.t, rx, str, msgAndArgs...) -} - -// Regexpf asserts that a specified regexp matches a string. -// -// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") -func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Regexpf(a.t, rx, str, msg, args...) -} - -// Same asserts that two pointers reference the same object. -// -// a.Same(ptr1, ptr2) -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Same(a.t, expected, actual, msgAndArgs...) -} - -// Samef asserts that two pointers reference the same object. -// -// a.Samef(ptr1, ptr2, "error message %s", "formatted") -// -// Both arguments must be pointer variables. Pointer variable sameness is -// determined based on the equality of both type and value. -func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Samef(a.t, expected, actual, msg, args...) -} - -// Subset asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// a.Subset([1, 2, 3], [1, 2]) -// a.Subset({"x": 1, "y": 2}, {"x": 1}) -func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Subset(a.t, list, subset, msgAndArgs...) -} - -// Subsetf asserts that the specified list(array, slice...) or map contains all -// elements given in the specified subset list(array, slice...) or map. -// -// a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted") -// a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") -func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Subsetf(a.t, list, subset, msg, args...) -} - -// True asserts that the specified value is true. -// -// a.True(myBool) -func (a *Assertions) True(value bool, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - True(a.t, value, msgAndArgs...) -} - -// Truef asserts that the specified value is true. -// -// a.Truef(myBool, "error message %s", "formatted") -func (a *Assertions) Truef(value bool, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Truef(a.t, value, msg, args...) -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) -func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - WithinDuration(a.t, expected, actual, delta, msgAndArgs...) -} - -// WithinDurationf asserts that the two times are within duration delta of each other. -// -// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") -func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - WithinDurationf(a.t, expected, actual, delta, msg, args...) -} - -// WithinRange asserts that a time is within a time range (inclusive). -// -// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) -func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - WithinRange(a.t, actual, start, end, msgAndArgs...) -} - -// WithinRangef asserts that a time is within a time range (inclusive). -// -// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") -func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - WithinRangef(a.t, actual, start, end, msg, args...) -} - -// YAMLEq asserts that two YAML strings are equivalent. -func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - YAMLEq(a.t, expected, actual, msgAndArgs...) -} - -// YAMLEqf asserts that two YAML strings are equivalent. -func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - YAMLEqf(a.t, expected, actual, msg, args...) -} - -// Zero asserts that i is the zero value for its type. -func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Zero(a.t, i, msgAndArgs...) -} - -// Zerof asserts that i is the zero value for its type. -func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) { - if h, ok := a.t.(tHelper); ok { - h.Helper() - } - Zerof(a.t, i, msg, args...) -} diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl b/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl deleted file mode 100644 index 54124df1..00000000 --- a/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl +++ /dev/null @@ -1,5 +0,0 @@ -{{.CommentWithoutT "a"}} -func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) { - if h, ok := a.t.(tHelper); ok { h.Helper() } - {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) -} diff --git a/vendor/github.com/stretchr/testify/require/requirements.go b/vendor/github.com/stretchr/testify/require/requirements.go deleted file mode 100644 index 91772dfe..00000000 --- a/vendor/github.com/stretchr/testify/require/requirements.go +++ /dev/null @@ -1,29 +0,0 @@ -package require - -// TestingT is an interface wrapper around *testing.T -type TestingT interface { - Errorf(format string, args ...interface{}) - FailNow() -} - -type tHelper interface { - Helper() -} - -// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful -// for table driven tests. -type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) - -// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful -// for table driven tests. -type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) - -// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful -// for table driven tests. -type BoolAssertionFunc func(TestingT, bool, ...interface{}) - -// ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful -// for table driven tests. -type ErrorAssertionFunc func(TestingT, error, ...interface{}) - -//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs" diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go index 21ca3b2e..048faef3 100644 --- a/vendor/golang.org/x/crypto/curve25519/curve25519.go +++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go @@ -3,11 +3,14 @@ // license that can be found in the LICENSE file. // Package curve25519 provides an implementation of the X25519 function, which -// performs scalar multiplication on the elliptic curve known as Curve25519. -// See RFC 7748. +// performs scalar multiplication on the elliptic curve known as Curve25519 +// according to [RFC 7748]. // -// This package is a wrapper for the X25519 implementation -// in the crypto/ecdh package. +// The curve25519 package is a wrapper for the X25519 implementation in the +// crypto/ecdh package. It is [frozen] and is not accepting new features. +// +// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748 +// [frozen]: https://go.dev/wiki/Frozen package curve25519 import "crypto/ecdh" @@ -36,7 +39,7 @@ func ScalarBaseMult(dst, scalar *[32]byte) { curve := ecdh.X25519() priv, err := curve.NewPrivateKey(scalar[:]) if err != nil { - panic("curve25519: internal error: scalarBaseMult was not 32 bytes") + panic("curve25519: " + err.Error()) } copy(dst[:], priv.PublicKey().Bytes()) } diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go b/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go deleted file mode 100644 index ba647e8d..00000000 --- a/vendor/golang.org/x/crypto/curve25519/curve25519_compat.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.20 - -package curve25519 - -import ( - "crypto/subtle" - "errors" - "strconv" - - "golang.org/x/crypto/curve25519/internal/field" -) - -func scalarMult(dst, scalar, point *[32]byte) { - var e [32]byte - - copy(e[:], scalar[:]) - e[0] &= 248 - e[31] &= 127 - e[31] |= 64 - - var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element - x1.SetBytes(point[:]) - x2.One() - x3.Set(&x1) - z3.One() - - swap := 0 - for pos := 254; pos >= 0; pos-- { - b := e[pos/8] >> uint(pos&7) - b &= 1 - swap ^= int(b) - x2.Swap(&x3, swap) - z2.Swap(&z3, swap) - swap = int(b) - - tmp0.Subtract(&x3, &z3) - tmp1.Subtract(&x2, &z2) - x2.Add(&x2, &z2) - z2.Add(&x3, &z3) - z3.Multiply(&tmp0, &x2) - z2.Multiply(&z2, &tmp1) - tmp0.Square(&tmp1) - tmp1.Square(&x2) - x3.Add(&z3, &z2) - z2.Subtract(&z3, &z2) - x2.Multiply(&tmp1, &tmp0) - tmp1.Subtract(&tmp1, &tmp0) - z2.Square(&z2) - - z3.Mult32(&tmp1, 121666) - x3.Square(&x3) - tmp0.Add(&tmp0, &z3) - z3.Multiply(&x1, &z2) - z2.Multiply(&tmp1, &tmp0) - } - - x2.Swap(&x3, swap) - z2.Swap(&z3, swap) - - z2.Invert(&z2) - x2.Multiply(&x2, &z2) - copy(dst[:], x2.Bytes()) -} - -func scalarBaseMult(dst, scalar *[32]byte) { - checkBasepoint() - scalarMult(dst, scalar, &basePoint) -} - -func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { - var in [32]byte - if l := len(scalar); l != 32 { - return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32") - } - if l := len(point); l != 32 { - return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32") - } - copy(in[:], scalar) - if &point[0] == &Basepoint[0] { - scalarBaseMult(dst, &in) - } else { - var base, zero [32]byte - copy(base[:], point) - scalarMult(dst, &in, &base) - if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 { - return nil, errors.New("bad input point: low order point") - } - } - return dst[:], nil -} - -func checkBasepoint() { - if subtle.ConstantTimeCompare(Basepoint, []byte{ - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }) != 1 { - panic("curve25519: global Basepoint value was modified") - } -} diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go b/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go deleted file mode 100644 index 627df497..00000000 --- a/vendor/golang.org/x/crypto/curve25519/curve25519_go120.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.20 - -package curve25519 - -import "crypto/ecdh" - -func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { - curve := ecdh.X25519() - pub, err := curve.NewPublicKey(point) - if err != nil { - return nil, err - } - priv, err := curve.NewPrivateKey(scalar) - if err != nil { - return nil, err - } - out, err := priv.ECDH(pub) - if err != nil { - return nil, err - } - copy(dst[:], out) - return dst[:], nil -} - -func scalarMult(dst, scalar, point *[32]byte) { - if _, err := x25519(dst, scalar[:], point[:]); err != nil { - // The only error condition for x25519 when the inputs are 32 bytes long - // is if the output would have been the all-zero value. - for i := range dst { - dst[i] = 0 - } - } -} - -func scalarBaseMult(dst, scalar *[32]byte) { - curve := ecdh.X25519() - priv, err := curve.NewPrivateKey(scalar[:]) - if err != nil { - panic("curve25519: internal error: scalarBaseMult was not 32 bytes") - } - copy(dst[:], priv.PublicKey().Bytes()) -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/README b/vendor/golang.org/x/crypto/curve25519/internal/field/README deleted file mode 100644 index e25bca7d..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/README +++ /dev/null @@ -1,7 +0,0 @@ -This package is kept in sync with crypto/ed25519/internal/edwards25519/field in -the standard library. - -If there are any changes in the standard library that need to be synced to this -package, run sync.sh. It will not overwrite any local changes made since the -previous sync, so it's ok to land changes in this package first, and then sync -to the standard library later. diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go deleted file mode 100644 index ca841ad9..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go +++ /dev/null @@ -1,416 +0,0 @@ -// Copyright (c) 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package field implements fast arithmetic modulo 2^255-19. -package field - -import ( - "crypto/subtle" - "encoding/binary" - "math/bits" -) - -// Element represents an element of the field GF(2^255-19). Note that this -// is not a cryptographically secure group, and should only be used to interact -// with edwards25519.Point coordinates. -// -// This type works similarly to math/big.Int, and all arguments and receivers -// are allowed to alias. -// -// The zero value is a valid zero element. -type Element struct { - // An element t represents the integer - // t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204 - // - // Between operations, all limbs are expected to be lower than 2^52. - l0 uint64 - l1 uint64 - l2 uint64 - l3 uint64 - l4 uint64 -} - -const maskLow51Bits uint64 = (1 << 51) - 1 - -var feZero = &Element{0, 0, 0, 0, 0} - -// Zero sets v = 0, and returns v. -func (v *Element) Zero() *Element { - *v = *feZero - return v -} - -var feOne = &Element{1, 0, 0, 0, 0} - -// One sets v = 1, and returns v. -func (v *Element) One() *Element { - *v = *feOne - return v -} - -// reduce reduces v modulo 2^255 - 19 and returns it. -func (v *Element) reduce() *Element { - v.carryPropagate() - - // After the light reduction we now have a field element representation - // v < 2^255 + 2^13 * 19, but need v < 2^255 - 19. - - // If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1, - // generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise. - c := (v.l0 + 19) >> 51 - c = (v.l1 + c) >> 51 - c = (v.l2 + c) >> 51 - c = (v.l3 + c) >> 51 - c = (v.l4 + c) >> 51 - - // If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's - // effectively applying the reduction identity to the carry. - v.l0 += 19 * c - - v.l1 += v.l0 >> 51 - v.l0 = v.l0 & maskLow51Bits - v.l2 += v.l1 >> 51 - v.l1 = v.l1 & maskLow51Bits - v.l3 += v.l2 >> 51 - v.l2 = v.l2 & maskLow51Bits - v.l4 += v.l3 >> 51 - v.l3 = v.l3 & maskLow51Bits - // no additional carry - v.l4 = v.l4 & maskLow51Bits - - return v -} - -// Add sets v = a + b, and returns v. -func (v *Element) Add(a, b *Element) *Element { - v.l0 = a.l0 + b.l0 - v.l1 = a.l1 + b.l1 - v.l2 = a.l2 + b.l2 - v.l3 = a.l3 + b.l3 - v.l4 = a.l4 + b.l4 - // Using the generic implementation here is actually faster than the - // assembly. Probably because the body of this function is so simple that - // the compiler can figure out better optimizations by inlining the carry - // propagation. TODO - return v.carryPropagateGeneric() -} - -// Subtract sets v = a - b, and returns v. -func (v *Element) Subtract(a, b *Element) *Element { - // We first add 2 * p, to guarantee the subtraction won't underflow, and - // then subtract b (which can be up to 2^255 + 2^13 * 19). - v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0 - v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1 - v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2 - v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3 - v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4 - return v.carryPropagate() -} - -// Negate sets v = -a, and returns v. -func (v *Element) Negate(a *Element) *Element { - return v.Subtract(feZero, a) -} - -// Invert sets v = 1/z mod p, and returns v. -// -// If z == 0, Invert returns v = 0. -func (v *Element) Invert(z *Element) *Element { - // Inversion is implemented as exponentiation with exponent p − 2. It uses the - // same sequence of 255 squarings and 11 multiplications as [Curve25519]. - var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element - - z2.Square(z) // 2 - t.Square(&z2) // 4 - t.Square(&t) // 8 - z9.Multiply(&t, z) // 9 - z11.Multiply(&z9, &z2) // 11 - t.Square(&z11) // 22 - z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0 - - t.Square(&z2_5_0) // 2^6 - 2^1 - for i := 0; i < 4; i++ { - t.Square(&t) // 2^10 - 2^5 - } - z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0 - - t.Square(&z2_10_0) // 2^11 - 2^1 - for i := 0; i < 9; i++ { - t.Square(&t) // 2^20 - 2^10 - } - z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0 - - t.Square(&z2_20_0) // 2^21 - 2^1 - for i := 0; i < 19; i++ { - t.Square(&t) // 2^40 - 2^20 - } - t.Multiply(&t, &z2_20_0) // 2^40 - 2^0 - - t.Square(&t) // 2^41 - 2^1 - for i := 0; i < 9; i++ { - t.Square(&t) // 2^50 - 2^10 - } - z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0 - - t.Square(&z2_50_0) // 2^51 - 2^1 - for i := 0; i < 49; i++ { - t.Square(&t) // 2^100 - 2^50 - } - z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0 - - t.Square(&z2_100_0) // 2^101 - 2^1 - for i := 0; i < 99; i++ { - t.Square(&t) // 2^200 - 2^100 - } - t.Multiply(&t, &z2_100_0) // 2^200 - 2^0 - - t.Square(&t) // 2^201 - 2^1 - for i := 0; i < 49; i++ { - t.Square(&t) // 2^250 - 2^50 - } - t.Multiply(&t, &z2_50_0) // 2^250 - 2^0 - - t.Square(&t) // 2^251 - 2^1 - t.Square(&t) // 2^252 - 2^2 - t.Square(&t) // 2^253 - 2^3 - t.Square(&t) // 2^254 - 2^4 - t.Square(&t) // 2^255 - 2^5 - - return v.Multiply(&t, &z11) // 2^255 - 21 -} - -// Set sets v = a, and returns v. -func (v *Element) Set(a *Element) *Element { - *v = *a - return v -} - -// SetBytes sets v to x, which must be a 32-byte little-endian encoding. -// -// Consistent with RFC 7748, the most significant bit (the high bit of the -// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1) -// are accepted. Note that this is laxer than specified by RFC 8032. -func (v *Element) SetBytes(x []byte) *Element { - if len(x) != 32 { - panic("edwards25519: invalid field element input size") - } - - // Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51). - v.l0 = binary.LittleEndian.Uint64(x[0:8]) - v.l0 &= maskLow51Bits - // Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51). - v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3 - v.l1 &= maskLow51Bits - // Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51). - v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6 - v.l2 &= maskLow51Bits - // Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51). - v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1 - v.l3 &= maskLow51Bits - // Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51). - // Note: not bytes 25:33, shift 4, to avoid overread. - v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12 - v.l4 &= maskLow51Bits - - return v -} - -// Bytes returns the canonical 32-byte little-endian encoding of v. -func (v *Element) Bytes() []byte { - // This function is outlined to make the allocations inline in the caller - // rather than happen on the heap. - var out [32]byte - return v.bytes(&out) -} - -func (v *Element) bytes(out *[32]byte) []byte { - t := *v - t.reduce() - - var buf [8]byte - for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} { - bitsOffset := i * 51 - binary.LittleEndian.PutUint64(buf[:], l<= len(out) { - break - } - out[off] |= bb - } - } - - return out[:] -} - -// Equal returns 1 if v and u are equal, and 0 otherwise. -func (v *Element) Equal(u *Element) int { - sa, sv := u.Bytes(), v.Bytes() - return subtle.ConstantTimeCompare(sa, sv) -} - -// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise. -func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) } - -// Select sets v to a if cond == 1, and to b if cond == 0. -func (v *Element) Select(a, b *Element, cond int) *Element { - m := mask64Bits(cond) - v.l0 = (m & a.l0) | (^m & b.l0) - v.l1 = (m & a.l1) | (^m & b.l1) - v.l2 = (m & a.l2) | (^m & b.l2) - v.l3 = (m & a.l3) | (^m & b.l3) - v.l4 = (m & a.l4) | (^m & b.l4) - return v -} - -// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v. -func (v *Element) Swap(u *Element, cond int) { - m := mask64Bits(cond) - t := m & (v.l0 ^ u.l0) - v.l0 ^= t - u.l0 ^= t - t = m & (v.l1 ^ u.l1) - v.l1 ^= t - u.l1 ^= t - t = m & (v.l2 ^ u.l2) - v.l2 ^= t - u.l2 ^= t - t = m & (v.l3 ^ u.l3) - v.l3 ^= t - u.l3 ^= t - t = m & (v.l4 ^ u.l4) - v.l4 ^= t - u.l4 ^= t -} - -// IsNegative returns 1 if v is negative, and 0 otherwise. -func (v *Element) IsNegative() int { - return int(v.Bytes()[0] & 1) -} - -// Absolute sets v to |u|, and returns v. -func (v *Element) Absolute(u *Element) *Element { - return v.Select(new(Element).Negate(u), u, u.IsNegative()) -} - -// Multiply sets v = x * y, and returns v. -func (v *Element) Multiply(x, y *Element) *Element { - feMul(v, x, y) - return v -} - -// Square sets v = x * x, and returns v. -func (v *Element) Square(x *Element) *Element { - feSquare(v, x) - return v -} - -// Mult32 sets v = x * y, and returns v. -func (v *Element) Mult32(x *Element, y uint32) *Element { - x0lo, x0hi := mul51(x.l0, y) - x1lo, x1hi := mul51(x.l1, y) - x2lo, x2hi := mul51(x.l2, y) - x3lo, x3hi := mul51(x.l3, y) - x4lo, x4hi := mul51(x.l4, y) - v.l0 = x0lo + 19*x4hi // carried over per the reduction identity - v.l1 = x1lo + x0hi - v.l2 = x2lo + x1hi - v.l3 = x3lo + x2hi - v.l4 = x4lo + x3hi - // The hi portions are going to be only 32 bits, plus any previous excess, - // so we can skip the carry propagation. - return v -} - -// mul51 returns lo + hi * 2⁵¹ = a * b. -func mul51(a uint64, b uint32) (lo uint64, hi uint64) { - mh, ml := bits.Mul64(a, uint64(b)) - lo = ml & maskLow51Bits - hi = (mh << 13) | (ml >> 51) - return -} - -// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3. -func (v *Element) Pow22523(x *Element) *Element { - var t0, t1, t2 Element - - t0.Square(x) // x^2 - t1.Square(&t0) // x^4 - t1.Square(&t1) // x^8 - t1.Multiply(x, &t1) // x^9 - t0.Multiply(&t0, &t1) // x^11 - t0.Square(&t0) // x^22 - t0.Multiply(&t1, &t0) // x^31 - t1.Square(&t0) // x^62 - for i := 1; i < 5; i++ { // x^992 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1 - t1.Square(&t0) // 2^11 - 2 - for i := 1; i < 10; i++ { // 2^20 - 2^10 - t1.Square(&t1) - } - t1.Multiply(&t1, &t0) // 2^20 - 1 - t2.Square(&t1) // 2^21 - 2 - for i := 1; i < 20; i++ { // 2^40 - 2^20 - t2.Square(&t2) - } - t1.Multiply(&t2, &t1) // 2^40 - 1 - t1.Square(&t1) // 2^41 - 2 - for i := 1; i < 10; i++ { // 2^50 - 2^10 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // 2^50 - 1 - t1.Square(&t0) // 2^51 - 2 - for i := 1; i < 50; i++ { // 2^100 - 2^50 - t1.Square(&t1) - } - t1.Multiply(&t1, &t0) // 2^100 - 1 - t2.Square(&t1) // 2^101 - 2 - for i := 1; i < 100; i++ { // 2^200 - 2^100 - t2.Square(&t2) - } - t1.Multiply(&t2, &t1) // 2^200 - 1 - t1.Square(&t1) // 2^201 - 2 - for i := 1; i < 50; i++ { // 2^250 - 2^50 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // 2^250 - 1 - t0.Square(&t0) // 2^251 - 2 - t0.Square(&t0) // 2^252 - 4 - return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3) -} - -// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion. -var sqrtM1 = &Element{1718705420411056, 234908883556509, - 2233514472574048, 2117202627021982, 765476049583133} - -// SqrtRatio sets r to the non-negative square root of the ratio of u and v. -// -// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio -// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00, -// and returns r and 0. -func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) { - var a, b Element - - // r = (u * v3) * (u * v7)^((p-5)/8) - v2 := a.Square(v) - uv3 := b.Multiply(u, b.Multiply(v2, v)) - uv7 := a.Multiply(uv3, a.Square(v2)) - r.Multiply(uv3, r.Pow22523(uv7)) - - check := a.Multiply(v, a.Square(r)) // check = v * r^2 - - uNeg := b.Negate(u) - correctSignSqrt := check.Equal(u) - flippedSignSqrt := check.Equal(uNeg) - flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1)) - - rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r - // r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r) - r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI) - - r.Absolute(r) // Choose the nonnegative square root. - return r, correctSignSqrt | flippedSignSqrt -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go deleted file mode 100644 index 70c54169..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. - -//go:build amd64 && gc && !purego - -package field - -// feMul sets out = a * b. It works like feMulGeneric. -// -//go:noescape -func feMul(out *Element, a *Element, b *Element) - -// feSquare sets out = a * a. It works like feSquareGeneric. -// -//go:noescape -func feSquare(out *Element, a *Element) diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s deleted file mode 100644 index 60817acc..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s +++ /dev/null @@ -1,378 +0,0 @@ -// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. - -//go:build amd64 && gc && !purego - -#include "textflag.h" - -// func feMul(out *Element, a *Element, b *Element) -TEXT ·feMul(SB), NOSPLIT, $0-24 - MOVQ a+8(FP), CX - MOVQ b+16(FP), BX - - // r0 = a0×b0 - MOVQ (CX), AX - MULQ (BX) - MOVQ AX, DI - MOVQ DX, SI - - // r0 += 19×a1×b4 - MOVQ 8(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a2×b3 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a3×b2 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a4×b1 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 8(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r1 = a0×b1 - MOVQ (CX), AX - MULQ 8(BX) - MOVQ AX, R9 - MOVQ DX, R8 - - // r1 += a1×b0 - MOVQ 8(CX), AX - MULQ (BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a2×b4 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a3×b3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a4×b2 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r2 = a0×b2 - MOVQ (CX), AX - MULQ 16(BX) - MOVQ AX, R11 - MOVQ DX, R10 - - // r2 += a1×b1 - MOVQ 8(CX), AX - MULQ 8(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += a2×b0 - MOVQ 16(CX), AX - MULQ (BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += 19×a3×b4 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += 19×a4×b3 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r3 = a0×b3 - MOVQ (CX), AX - MULQ 24(BX) - MOVQ AX, R13 - MOVQ DX, R12 - - // r3 += a1×b2 - MOVQ 8(CX), AX - MULQ 16(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += a2×b1 - MOVQ 16(CX), AX - MULQ 8(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += a3×b0 - MOVQ 24(CX), AX - MULQ (BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += 19×a4×b4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r4 = a0×b4 - MOVQ (CX), AX - MULQ 32(BX) - MOVQ AX, R15 - MOVQ DX, R14 - - // r4 += a1×b3 - MOVQ 8(CX), AX - MULQ 24(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a2×b2 - MOVQ 16(CX), AX - MULQ 16(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a3×b1 - MOVQ 24(CX), AX - MULQ 8(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a4×b0 - MOVQ 32(CX), AX - MULQ (BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // First reduction chain - MOVQ $0x0007ffffffffffff, AX - SHLQ $0x0d, DI, SI - SHLQ $0x0d, R9, R8 - SHLQ $0x0d, R11, R10 - SHLQ $0x0d, R13, R12 - SHLQ $0x0d, R15, R14 - ANDQ AX, DI - IMUL3Q $0x13, R14, R14 - ADDQ R14, DI - ANDQ AX, R9 - ADDQ SI, R9 - ANDQ AX, R11 - ADDQ R8, R11 - ANDQ AX, R13 - ADDQ R10, R13 - ANDQ AX, R15 - ADDQ R12, R15 - - // Second reduction chain (carryPropagate) - MOVQ DI, SI - SHRQ $0x33, SI - MOVQ R9, R8 - SHRQ $0x33, R8 - MOVQ R11, R10 - SHRQ $0x33, R10 - MOVQ R13, R12 - SHRQ $0x33, R12 - MOVQ R15, R14 - SHRQ $0x33, R14 - ANDQ AX, DI - IMUL3Q $0x13, R14, R14 - ADDQ R14, DI - ANDQ AX, R9 - ADDQ SI, R9 - ANDQ AX, R11 - ADDQ R8, R11 - ANDQ AX, R13 - ADDQ R10, R13 - ANDQ AX, R15 - ADDQ R12, R15 - - // Store output - MOVQ out+0(FP), AX - MOVQ DI, (AX) - MOVQ R9, 8(AX) - MOVQ R11, 16(AX) - MOVQ R13, 24(AX) - MOVQ R15, 32(AX) - RET - -// func feSquare(out *Element, a *Element) -TEXT ·feSquare(SB), NOSPLIT, $0-16 - MOVQ a+8(FP), CX - - // r0 = l0×l0 - MOVQ (CX), AX - MULQ (CX) - MOVQ AX, SI - MOVQ DX, BX - - // r0 += 38×l1×l4 - MOVQ 8(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, SI - ADCQ DX, BX - - // r0 += 38×l2×l3 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 24(CX) - ADDQ AX, SI - ADCQ DX, BX - - // r1 = 2×l0×l1 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 8(CX) - MOVQ AX, R8 - MOVQ DX, DI - - // r1 += 38×l2×l4 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R8 - ADCQ DX, DI - - // r1 += 19×l3×l3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(CX) - ADDQ AX, R8 - ADCQ DX, DI - - // r2 = 2×l0×l2 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 16(CX) - MOVQ AX, R10 - MOVQ DX, R9 - - // r2 += l1×l1 - MOVQ 8(CX), AX - MULQ 8(CX) - ADDQ AX, R10 - ADCQ DX, R9 - - // r2 += 38×l3×l4 - MOVQ 24(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R10 - ADCQ DX, R9 - - // r3 = 2×l0×l3 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 24(CX) - MOVQ AX, R12 - MOVQ DX, R11 - - // r3 += 2×l1×l2 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 16(CX) - ADDQ AX, R12 - ADCQ DX, R11 - - // r3 += 19×l4×l4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(CX) - ADDQ AX, R12 - ADCQ DX, R11 - - // r4 = 2×l0×l4 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 32(CX) - MOVQ AX, R14 - MOVQ DX, R13 - - // r4 += 2×l1×l3 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 24(CX) - ADDQ AX, R14 - ADCQ DX, R13 - - // r4 += l2×l2 - MOVQ 16(CX), AX - MULQ 16(CX) - ADDQ AX, R14 - ADCQ DX, R13 - - // First reduction chain - MOVQ $0x0007ffffffffffff, AX - SHLQ $0x0d, SI, BX - SHLQ $0x0d, R8, DI - SHLQ $0x0d, R10, R9 - SHLQ $0x0d, R12, R11 - SHLQ $0x0d, R14, R13 - ANDQ AX, SI - IMUL3Q $0x13, R13, R13 - ADDQ R13, SI - ANDQ AX, R8 - ADDQ BX, R8 - ANDQ AX, R10 - ADDQ DI, R10 - ANDQ AX, R12 - ADDQ R9, R12 - ANDQ AX, R14 - ADDQ R11, R14 - - // Second reduction chain (carryPropagate) - MOVQ SI, BX - SHRQ $0x33, BX - MOVQ R8, DI - SHRQ $0x33, DI - MOVQ R10, R9 - SHRQ $0x33, R9 - MOVQ R12, R11 - SHRQ $0x33, R11 - MOVQ R14, R13 - SHRQ $0x33, R13 - ANDQ AX, SI - IMUL3Q $0x13, R13, R13 - ADDQ R13, SI - ANDQ AX, R8 - ADDQ BX, R8 - ANDQ AX, R10 - ADDQ DI, R10 - ANDQ AX, R12 - ADDQ R9, R12 - ANDQ AX, R14 - ADDQ R11, R14 - - // Store output - MOVQ out+0(FP), AX - MOVQ SI, (AX) - MOVQ R8, 8(AX) - MOVQ R10, 16(AX) - MOVQ R12, 24(AX) - MOVQ R14, 32(AX) - RET diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go deleted file mode 100644 index 9da280d1..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !amd64 || !gc || purego - -package field - -func feMul(v, x, y *Element) { feMulGeneric(v, x, y) } - -func feSquare(v, x *Element) { feSquareGeneric(v, x) } diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go deleted file mode 100644 index 075fe9b9..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build arm64 && gc && !purego - -package field - -//go:noescape -func carryPropagate(v *Element) - -func (v *Element) carryPropagate() *Element { - carryPropagate(v) - return v -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s deleted file mode 100644 index 3126a434..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build arm64 && gc && !purego - -#include "textflag.h" - -// carryPropagate works exactly like carryPropagateGeneric and uses the -// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but -// avoids loading R0-R4 twice and uses LDP and STP. -// -// See https://golang.org/issues/43145 for the main compiler issue. -// -// func carryPropagate(v *Element) -TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8 - MOVD v+0(FP), R20 - - LDP 0(R20), (R0, R1) - LDP 16(R20), (R2, R3) - MOVD 32(R20), R4 - - AND $0x7ffffffffffff, R0, R10 - AND $0x7ffffffffffff, R1, R11 - AND $0x7ffffffffffff, R2, R12 - AND $0x7ffffffffffff, R3, R13 - AND $0x7ffffffffffff, R4, R14 - - ADD R0>>51, R11, R11 - ADD R1>>51, R12, R12 - ADD R2>>51, R13, R13 - ADD R3>>51, R14, R14 - // R4>>51 * 19 + R10 -> R10 - LSR $51, R4, R21 - MOVD $19, R22 - MADD R22, R10, R21, R10 - - STP (R10, R11), 0(R20) - STP (R12, R13), 16(R20) - MOVD R14, 32(R20) - - RET diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go deleted file mode 100644 index fc029ac1..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !arm64 || !gc || purego - -package field - -func (v *Element) carryPropagate() *Element { - return v.carryPropagateGeneric() -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go deleted file mode 100644 index 2671217d..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package field - -import "math/bits" - -// uint128 holds a 128-bit number as two 64-bit limbs, for use with the -// bits.Mul64 and bits.Add64 intrinsics. -type uint128 struct { - lo, hi uint64 -} - -// mul64 returns a * b. -func mul64(a, b uint64) uint128 { - hi, lo := bits.Mul64(a, b) - return uint128{lo, hi} -} - -// addMul64 returns v + a * b. -func addMul64(v uint128, a, b uint64) uint128 { - hi, lo := bits.Mul64(a, b) - lo, c := bits.Add64(lo, v.lo, 0) - hi, _ = bits.Add64(hi, v.hi, c) - return uint128{lo, hi} -} - -// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits. -func shiftRightBy51(a uint128) uint64 { - return (a.hi << (64 - 51)) | (a.lo >> 51) -} - -func feMulGeneric(v, a, b *Element) { - a0 := a.l0 - a1 := a.l1 - a2 := a.l2 - a3 := a.l3 - a4 := a.l4 - - b0 := b.l0 - b1 := b.l1 - b2 := b.l2 - b3 := b.l3 - b4 := b.l4 - - // Limb multiplication works like pen-and-paper columnar multiplication, but - // with 51-bit limbs instead of digits. - // - // a4 a3 a2 a1 a0 x - // b4 b3 b2 b1 b0 = - // ------------------------ - // a4b0 a3b0 a2b0 a1b0 a0b0 + - // a4b1 a3b1 a2b1 a1b1 a0b1 + - // a4b2 a3b2 a2b2 a1b2 a0b2 + - // a4b3 a3b3 a2b3 a1b3 a0b3 + - // a4b4 a3b4 a2b4 a1b4 a0b4 = - // ---------------------------------------------- - // r8 r7 r6 r5 r4 r3 r2 r1 r0 - // - // We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to - // reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5, - // r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc. - // - // Reduction can be carried out simultaneously to multiplication. For - // example, we do not compute r5: whenever the result of a multiplication - // belongs to r5, like a1b4, we multiply it by 19 and add the result to r0. - // - // a4b0 a3b0 a2b0 a1b0 a0b0 + - // a3b1 a2b1 a1b1 a0b1 19×a4b1 + - // a2b2 a1b2 a0b2 19×a4b2 19×a3b2 + - // a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 + - // a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 = - // -------------------------------------- - // r4 r3 r2 r1 r0 - // - // Finally we add up the columns into wide, overlapping limbs. - - a1_19 := a1 * 19 - a2_19 := a2 * 19 - a3_19 := a3 * 19 - a4_19 := a4 * 19 - - // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1) - r0 := mul64(a0, b0) - r0 = addMul64(r0, a1_19, b4) - r0 = addMul64(r0, a2_19, b3) - r0 = addMul64(r0, a3_19, b2) - r0 = addMul64(r0, a4_19, b1) - - // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2) - r1 := mul64(a0, b1) - r1 = addMul64(r1, a1, b0) - r1 = addMul64(r1, a2_19, b4) - r1 = addMul64(r1, a3_19, b3) - r1 = addMul64(r1, a4_19, b2) - - // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3) - r2 := mul64(a0, b2) - r2 = addMul64(r2, a1, b1) - r2 = addMul64(r2, a2, b0) - r2 = addMul64(r2, a3_19, b4) - r2 = addMul64(r2, a4_19, b3) - - // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4 - r3 := mul64(a0, b3) - r3 = addMul64(r3, a1, b2) - r3 = addMul64(r3, a2, b1) - r3 = addMul64(r3, a3, b0) - r3 = addMul64(r3, a4_19, b4) - - // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0 - r4 := mul64(a0, b4) - r4 = addMul64(r4, a1, b3) - r4 = addMul64(r4, a2, b2) - r4 = addMul64(r4, a3, b1) - r4 = addMul64(r4, a4, b0) - - // After the multiplication, we need to reduce (carry) the five coefficients - // to obtain a result with limbs that are at most slightly larger than 2⁵¹, - // to respect the Element invariant. - // - // Overall, the reduction works the same as carryPropagate, except with - // wider inputs: we take the carry for each coefficient by shifting it right - // by 51, and add it to the limb above it. The top carry is multiplied by 19 - // according to the reduction identity and added to the lowest limb. - // - // The largest coefficient (r0) will be at most 111 bits, which guarantees - // that all carries are at most 111 - 51 = 60 bits, which fits in a uint64. - // - // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1) - // r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²) - // r0 < (1 + 19 × 4) × 2⁵² × 2⁵² - // r0 < 2⁷ × 2⁵² × 2⁵² - // r0 < 2¹¹¹ - // - // Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most - // 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and - // allows us to easily apply the reduction identity. - // - // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0 - // r4 < 5 × 2⁵² × 2⁵² - // r4 < 2¹⁰⁷ - // - - c0 := shiftRightBy51(r0) - c1 := shiftRightBy51(r1) - c2 := shiftRightBy51(r2) - c3 := shiftRightBy51(r3) - c4 := shiftRightBy51(r4) - - rr0 := r0.lo&maskLow51Bits + c4*19 - rr1 := r1.lo&maskLow51Bits + c0 - rr2 := r2.lo&maskLow51Bits + c1 - rr3 := r3.lo&maskLow51Bits + c2 - rr4 := r4.lo&maskLow51Bits + c3 - - // Now all coefficients fit into 64-bit registers but are still too large to - // be passed around as a Element. We therefore do one last carry chain, - // where the carries will be small enough to fit in the wiggle room above 2⁵¹. - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() -} - -func feSquareGeneric(v, a *Element) { - l0 := a.l0 - l1 := a.l1 - l2 := a.l2 - l3 := a.l3 - l4 := a.l4 - - // Squaring works precisely like multiplication above, but thanks to its - // symmetry we get to group a few terms together. - // - // l4 l3 l2 l1 l0 x - // l4 l3 l2 l1 l0 = - // ------------------------ - // l4l0 l3l0 l2l0 l1l0 l0l0 + - // l4l1 l3l1 l2l1 l1l1 l0l1 + - // l4l2 l3l2 l2l2 l1l2 l0l2 + - // l4l3 l3l3 l2l3 l1l3 l0l3 + - // l4l4 l3l4 l2l4 l1l4 l0l4 = - // ---------------------------------------------- - // r8 r7 r6 r5 r4 r3 r2 r1 r0 - // - // l4l0 l3l0 l2l0 l1l0 l0l0 + - // l3l1 l2l1 l1l1 l0l1 19×l4l1 + - // l2l2 l1l2 l0l2 19×l4l2 19×l3l2 + - // l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 + - // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 = - // -------------------------------------- - // r4 r3 r2 r1 r0 - // - // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with - // only three Mul64 and four Add64, instead of five and eight. - - l0_2 := l0 * 2 - l1_2 := l1 * 2 - - l1_38 := l1 * 38 - l2_38 := l2 * 38 - l3_38 := l3 * 38 - - l3_19 := l3 * 19 - l4_19 := l4 * 19 - - // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3) - r0 := mul64(l0, l0) - r0 = addMul64(r0, l1_38, l4) - r0 = addMul64(r0, l2_38, l3) - - // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3 - r1 := mul64(l0_2, l1) - r1 = addMul64(r1, l2_38, l4) - r1 = addMul64(r1, l3_19, l3) - - // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4 - r2 := mul64(l0_2, l2) - r2 = addMul64(r2, l1, l1) - r2 = addMul64(r2, l3_38, l4) - - // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4 - r3 := mul64(l0_2, l3) - r3 = addMul64(r3, l1_2, l2) - r3 = addMul64(r3, l4_19, l4) - - // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2 - r4 := mul64(l0_2, l4) - r4 = addMul64(r4, l1_2, l3) - r4 = addMul64(r4, l2, l2) - - c0 := shiftRightBy51(r0) - c1 := shiftRightBy51(r1) - c2 := shiftRightBy51(r2) - c3 := shiftRightBy51(r3) - c4 := shiftRightBy51(r4) - - rr0 := r0.lo&maskLow51Bits + c4*19 - rr1 := r1.lo&maskLow51Bits + c0 - rr2 := r2.lo&maskLow51Bits + c1 - rr3 := r3.lo&maskLow51Bits + c2 - rr4 := r4.lo&maskLow51Bits + c3 - - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() -} - -// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction -// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline -func (v *Element) carryPropagateGeneric() *Element { - c0 := v.l0 >> 51 - c1 := v.l1 >> 51 - c2 := v.l2 >> 51 - c3 := v.l3 >> 51 - c4 := v.l4 >> 51 - - v.l0 = v.l0&maskLow51Bits + c4*19 - v.l1 = v.l1&maskLow51Bits + c0 - v.l2 = v.l2&maskLow51Bits + c1 - v.l3 = v.l3&maskLow51Bits + c2 - v.l4 = v.l4&maskLow51Bits + c3 - - return v -} diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint deleted file mode 100644 index e3685f95..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint +++ /dev/null @@ -1 +0,0 @@ -b0c49ae9f59d233526f8934262c5bbbe14d4358d diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh deleted file mode 100644 index 1ba22a8b..00000000 --- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/bash -set -euo pipefail - -cd "$(git rev-parse --show-toplevel)" - -STD_PATH=src/crypto/ed25519/internal/edwards25519/field -LOCAL_PATH=curve25519/internal/field -LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint) - -git fetch https://go.googlesource.com/go master - -if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then - echo "No changes." -else - NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint) - echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..." - git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \ - git apply -3 --directory=$LOCAL_PATH -fi diff --git a/vendor/golang.org/x/net/dns/dnsmessage/message.go b/vendor/golang.org/x/net/dns/dnsmessage/message.go index a656efc1..7a978b47 100644 --- a/vendor/golang.org/x/net/dns/dnsmessage/message.go +++ b/vendor/golang.org/x/net/dns/dnsmessage/message.go @@ -17,8 +17,21 @@ import ( ) // Message formats - -// A Type is a type of DNS request and response. +// +// To add a new Resource Record type: +// 1. Create Resource Record types +// 1.1. Add a Type constant named "Type" +// 1.2. Add the corresponding entry to the typeNames map +// 1.3. Add a [ResourceBody] implementation named "Resource" +// 2. Implement packing +// 2.1. Implement Builder.Resource() +// 3. Implement unpacking +// 3.1. Add the unpacking code to unpackResourceBody() +// 3.2. Implement Parser.Resource() + +// A Type is the type of a DNS Resource Record, as defined in the [IANA registry]. +// +// [IANA registry]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4 type Type uint16 const ( @@ -33,6 +46,8 @@ const ( TypeAAAA Type = 28 TypeSRV Type = 33 TypeOPT Type = 41 + TypeSVCB Type = 64 + TypeHTTPS Type = 65 // Question.Type TypeWKS Type = 11 @@ -53,6 +68,8 @@ var typeNames = map[Type]string{ TypeAAAA: "TypeAAAA", TypeSRV: "TypeSRV", TypeOPT: "TypeOPT", + TypeSVCB: "TypeSVCB", + TypeHTTPS: "TypeHTTPS", TypeWKS: "TypeWKS", TypeHINFO: "TypeHINFO", TypeMINFO: "TypeMINFO", @@ -273,6 +290,8 @@ var ( errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)") errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)") errStringTooLong = errors.New("character string exceeds maximum length (255)") + errParamOutOfOrder = errors.New("parameter out of order") + errTooLongSVCBValue = errors.New("value too long (>65535 bytes)") ) // Internal constants. @@ -2220,6 +2239,16 @@ func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, rb, err = unpackSRVResource(msg, off) r = &rb name = "SRV" + case TypeSVCB: + var rb SVCBResource + rb, err = unpackSVCBResource(msg, off, hdr.Length) + r = &rb + name = "SVCB" + case TypeHTTPS: + var rb HTTPSResource + rb.SVCBResource, err = unpackSVCBResource(msg, off, hdr.Length) + r = &rb + name = "HTTPS" case TypeOPT: var rb OPTResource rb, err = unpackOPTResource(msg, off, hdr.Length) diff --git a/vendor/golang.org/x/net/dns/dnsmessage/svcb.go b/vendor/golang.org/x/net/dns/dnsmessage/svcb.go new file mode 100644 index 00000000..de1633f0 --- /dev/null +++ b/vendor/golang.org/x/net/dns/dnsmessage/svcb.go @@ -0,0 +1,329 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package dnsmessage + +import ( + "math" + "slices" + "strings" +) + +// An SVCBResource is an SVCB Resource record. +type SVCBResource struct { + Priority uint16 + Target Name + Params []SVCParam // Must be in strict increasing order by Key. +} + +func (r *SVCBResource) realType() Type { + return TypeSVCB +} + +// GoString implements fmt.GoStringer.GoString. +func (r *SVCBResource) GoString() string { + var b strings.Builder + b.WriteString("dnsmessage.SVCBResource{") + b.WriteString("Priority: " + printUint16(r.Priority) + ", ") + b.WriteString("Target: " + r.Target.GoString() + ", ") + b.WriteString("Params: []dnsmessage.SVCParam{") + if len(r.Params) > 0 { + b.WriteString(r.Params[0].GoString()) + for _, p := range r.Params[1:] { + b.WriteString(", " + p.GoString()) + } + } + b.WriteString("}}") + return b.String() +} + +// An HTTPSResource is an HTTPS Resource record. +// It has the same format as the SVCB record. +type HTTPSResource struct { + // Alias for SVCB resource record. + SVCBResource +} + +func (r *HTTPSResource) realType() Type { + return TypeHTTPS +} + +// GoString implements fmt.GoStringer.GoString. +func (r *HTTPSResource) GoString() string { + return "dnsmessage.HTTPSResource{SVCBResource: " + r.SVCBResource.GoString() + "}" +} + +// GetParam returns a parameter value by key. +func (r *SVCBResource) GetParam(key SVCParamKey) (value []byte, ok bool) { + for i := range r.Params { + if r.Params[i].Key == key { + return r.Params[i].Value, true + } + if r.Params[i].Key > key { + break + } + } + return nil, false +} + +// SetParam sets a parameter value by key. +// The Params list is kept sorted by key. +func (r *SVCBResource) SetParam(key SVCParamKey, value []byte) { + i := 0 + for i < len(r.Params) { + if r.Params[i].Key >= key { + break + } + i++ + } + + if i < len(r.Params) && r.Params[i].Key == key { + r.Params[i].Value = value + return + } + + r.Params = slices.Insert(r.Params, i, SVCParam{Key: key, Value: value}) +} + +// DeleteParam deletes a parameter by key. +// It returns true if the parameter was present. +func (r *SVCBResource) DeleteParam(key SVCParamKey) bool { + for i := range r.Params { + if r.Params[i].Key == key { + r.Params = slices.Delete(r.Params, i, i+1) + return true + } + if r.Params[i].Key > key { + break + } + } + return false +} + +// A SVCParam is a service parameter. +type SVCParam struct { + Key SVCParamKey + Value []byte +} + +// GoString implements fmt.GoStringer.GoString. +func (p SVCParam) GoString() string { + return "dnsmessage.SVCParam{" + + "Key: " + p.Key.GoString() + ", " + + "Value: []byte{" + printByteSlice(p.Value) + "}}" +} + +// A SVCParamKey is a key for a service parameter. +type SVCParamKey uint16 + +// Values defined at https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys. +const ( + SVCParamMandatory SVCParamKey = 0 + SVCParamALPN SVCParamKey = 1 + SVCParamNoDefaultALPN SVCParamKey = 2 + SVCParamPort SVCParamKey = 3 + SVCParamIPv4Hint SVCParamKey = 4 + SVCParamECH SVCParamKey = 5 + SVCParamIPv6Hint SVCParamKey = 6 + SVCParamDOHPath SVCParamKey = 7 + SVCParamOHTTP SVCParamKey = 8 + SVCParamTLSSupportedGroups SVCParamKey = 9 +) + +var svcParamKeyNames = map[SVCParamKey]string{ + SVCParamMandatory: "Mandatory", + SVCParamALPN: "ALPN", + SVCParamNoDefaultALPN: "NoDefaultALPN", + SVCParamPort: "Port", + SVCParamIPv4Hint: "IPv4Hint", + SVCParamECH: "ECH", + SVCParamIPv6Hint: "IPv6Hint", + SVCParamDOHPath: "DOHPath", + SVCParamOHTTP: "OHTTP", + SVCParamTLSSupportedGroups: "TLSSupportedGroups", +} + +// String implements fmt.Stringer.String. +func (k SVCParamKey) String() string { + if n, ok := svcParamKeyNames[k]; ok { + return n + } + return printUint16(uint16(k)) +} + +// GoString implements fmt.GoStringer.GoString. +func (k SVCParamKey) GoString() string { + if n, ok := svcParamKeyNames[k]; ok { + return "dnsmessage.SVCParam" + n + } + return printUint16(uint16(k)) +} + +func (r *SVCBResource) pack(msg []byte, _ map[string]uint16, _ int) ([]byte, error) { + oldMsg := msg + msg = packUint16(msg, r.Priority) + // https://datatracker.ietf.org/doc/html/rfc3597#section-4 prohibits name + // compression for RR types that are not "well-known". + // https://datatracker.ietf.org/doc/html/rfc9460#section-2.2 explicitly states that + // compression of the Target is prohibited, following RFC 3597. + msg, err := r.Target.pack(msg, nil, 0) + if err != nil { + return oldMsg, &nestedError{"SVCBResource.Target", err} + } + var previousKey SVCParamKey + for i, param := range r.Params { + if i > 0 && param.Key <= previousKey { + return oldMsg, &nestedError{"SVCBResource.Params", errParamOutOfOrder} + } + if len(param.Value) > math.MaxUint16 { + return oldMsg, &nestedError{"SVCBResource.Params", errTooLongSVCBValue} + } + msg = packUint16(msg, uint16(param.Key)) + msg = packUint16(msg, uint16(len(param.Value))) + msg = append(msg, param.Value...) + } + return msg, nil +} + +func unpackSVCBResource(msg []byte, off int, length uint16) (SVCBResource, error) { + // Wire format reference: https://www.rfc-editor.org/rfc/rfc9460.html#section-2.2. + r := SVCBResource{} + paramsOff := off + bodyEnd := off + int(length) + + var err error + if r.Priority, paramsOff, err = unpackUint16(msg, paramsOff); err != nil { + return SVCBResource{}, &nestedError{"Priority", err} + } + + if paramsOff, err = r.Target.unpack(msg, paramsOff); err != nil { + return SVCBResource{}, &nestedError{"Target", err} + } + + // Two-pass parsing to avoid allocations. + // First, count the number of params. + n := 0 + var totalValueLen uint16 + off = paramsOff + var previousKey uint16 + for off < bodyEnd { + var key, len uint16 + if key, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"Params key", err} + } + if n > 0 && key <= previousKey { + // As per https://www.rfc-editor.org/rfc/rfc9460.html#section-2.2, clients MUST + // consider the RR malformed if the SvcParamKeys are not in strictly increasing numeric order + return SVCBResource{}, &nestedError{"Params", errParamOutOfOrder} + } + if len, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"Params value length", err} + } + if off+int(len) > bodyEnd { + return SVCBResource{}, errResourceLen + } + totalValueLen += len + off += int(len) + n++ + } + if off != bodyEnd { + return SVCBResource{}, errResourceLen + } + + // Second, fill in the params. + r.Params = make([]SVCParam, n) + // valuesBuf is used to hold all param values to reduce allocations. + // Each param's Value slice will point into this buffer. + valuesBuf := make([]byte, totalValueLen) + off = paramsOff + for i := 0; i < n; i++ { + p := &r.Params[i] + var key, len uint16 + if key, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"param key", err} + } + p.Key = SVCParamKey(key) + if len, off, err = unpackUint16(msg, off); err != nil { + return SVCBResource{}, &nestedError{"param length", err} + } + if copy(valuesBuf, msg[off:off+int(len)]) != int(len) { + return SVCBResource{}, &nestedError{"param value", errCalcLen} + } + p.Value = valuesBuf[:len:len] + valuesBuf = valuesBuf[len:] + off += int(len) + } + + return r, nil +} + +// genericSVCBResource parses a single Resource Record compatible with SVCB. +func (p *Parser) genericSVCBResource(svcbType Type) (SVCBResource, error) { + if !p.resHeaderValid || p.resHeaderType != svcbType { + return SVCBResource{}, ErrNotStarted + } + r, err := unpackSVCBResource(p.msg, p.off, p.resHeaderLength) + if err != nil { + return SVCBResource{}, err + } + p.off += int(p.resHeaderLength) + p.resHeaderValid = false + p.index++ + return r, nil +} + +// SVCBResource parses a single SVCBResource. +// +// One of the XXXHeader methods must have been called before calling this +// method. +func (p *Parser) SVCBResource() (SVCBResource, error) { + return p.genericSVCBResource(TypeSVCB) +} + +// HTTPSResource parses a single HTTPSResource. +// +// One of the XXXHeader methods must have been called before calling this +// method. +func (p *Parser) HTTPSResource() (HTTPSResource, error) { + svcb, err := p.genericSVCBResource(TypeHTTPS) + if err != nil { + return HTTPSResource{}, err + } + return HTTPSResource{svcb}, nil +} + +// genericSVCBResource is the generic implementation for adding SVCB-like resources. +func (b *Builder) genericSVCBResource(h ResourceHeader, r SVCBResource) error { + if err := b.checkResourceSection(); err != nil { + return err + } + msg, lenOff, err := h.pack(b.msg, b.compression, b.start) + if err != nil { + return &nestedError{"ResourceHeader", err} + } + preLen := len(msg) + if msg, err = r.pack(msg, b.compression, b.start); err != nil { + return &nestedError{"ResourceBody", err} + } + if err := h.fixLen(msg, lenOff, preLen); err != nil { + return err + } + if err := b.incrementSectionCount(); err != nil { + return err + } + b.msg = msg + return nil +} + +// SVCBResource adds a single SVCBResource. +func (b *Builder) SVCBResource(h ResourceHeader, r SVCBResource) error { + h.Type = r.realType() + return b.genericSVCBResource(h, r) +} + +// HTTPSResource adds a single HTTPSResource. +func (b *Builder) HTTPSResource(h ResourceHeader, r HTTPSResource) error { + h.Type = r.realType() + return b.genericSVCBResource(h, r.SVCBResource) +} diff --git a/vendor/golang.org/x/net/internal/socks/socks.go b/vendor/golang.org/x/net/internal/socks/socks.go index 84fcc32b..8eedb84c 100644 --- a/vendor/golang.org/x/net/internal/socks/socks.go +++ b/vendor/golang.org/x/net/internal/socks/socks.go @@ -297,7 +297,7 @@ func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, b = append(b, up.Username...) b = append(b, byte(len(up.Password))) b = append(b, up.Password...) - // TODO(mikio): handle IO deadlines and cancelation if + // TODO(mikio): handle IO deadlines and cancellation if // necessary if _, err := rw.Write(b); err != nil { return err diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index 63541994..34c9ae76 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -92,6 +92,9 @@ var ARM64 struct { HasSHA2 bool // SHA2 hardware implementation HasCRC32 bool // CRC32 hardware implementation HasATOMICS bool // Atomic memory operation instruction set + HasHPDS bool // Hierarchical permission disables in translations tables + HasLOR bool // Limited ordering regions + HasPAN bool // Privileged access never HasFPHP bool // Half precision floating-point instruction set HasASIMDHP bool // Advanced SIMD half precision instruction set HasCPUID bool // CPUID identification scheme registers diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go index af2aa99f..f449c679 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go @@ -65,10 +65,10 @@ func setMinimalFeatures() { func readARM64Registers() { Initialized = true - parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0()) + parseARM64SystemRegisters(getisar0(), getisar1(), getmmfr1(), getpfr0()) } -func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { +func parseARM64SystemRegisters(isar0, isar1, mmfr1, pfr0 uint64) { // ID_AA64ISAR0_EL1 switch extractBits(isar0, 4, 7) { case 1: @@ -152,6 +152,22 @@ func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { ARM64.HasI8MM = true } + // ID_AA64MMFR1_EL1 + switch extractBits(mmfr1, 12, 15) { + case 1, 2: + ARM64.HasHPDS = true + } + + switch extractBits(mmfr1, 16, 19) { + case 1: + ARM64.HasLOR = true + } + + switch extractBits(mmfr1, 20, 23) { + case 1, 2, 3: + ARM64.HasPAN = true + } + // ID_AA64PFR0_EL1 switch extractBits(pfr0, 16, 19) { case 0: diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s index 22cc9984..a4f24b3b 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.s +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s @@ -9,31 +9,34 @@ // func getisar0() uint64 TEXT ·getisar0(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 0 into x0 - // mrs x0, ID_AA64ISAR0_EL1 = d5380600 - WORD $0xd5380600 + MRS ID_AA64ISAR0_EL1, R0 MOVD R0, ret+0(FP) RET // func getisar1() uint64 TEXT ·getisar1(SB),NOSPLIT,$0-8 // get Instruction Set Attributes 1 into x0 - // mrs x0, ID_AA64ISAR1_EL1 = d5380620 - WORD $0xd5380620 + MRS ID_AA64ISAR1_EL1, R0 + MOVD R0, ret+0(FP) + RET + +// func getmmfr1() uint64 +TEXT ·getmmfr1(SB),NOSPLIT,$0-8 + // get Memory Model Feature Register 1 into x0 + MRS ID_AA64MMFR1_EL1, R0 MOVD R0, ret+0(FP) RET // func getpfr0() uint64 TEXT ·getpfr0(SB),NOSPLIT,$0-8 // get Processor Feature Register 0 into x0 - // mrs x0, ID_AA64PFR0_EL1 = d5380400 - WORD $0xd5380400 + MRS ID_AA64PFR0_EL1, R0 MOVD R0, ret+0(FP) RET // func getzfr0() uint64 TEXT ·getzfr0(SB),NOSPLIT,$0-8 // get SVE Feature Register 0 into x0 - // mrs x0, ID_AA64ZFR0_EL1 = d5380480 - WORD $0xd5380480 + MRS ID_AA64ZFR0_EL1, R0 MOVD R0, ret+0(FP) RET diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go index 6ac6e1ef..e3fc5a8d 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go @@ -8,5 +8,6 @@ package cpu func getisar0() uint64 func getisar1() uint64 +func getmmfr1() uint64 func getpfr0() uint64 func getzfr0() uint64 diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go index 7f194678..8df2079e 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go @@ -8,4 +8,5 @@ package cpu func getisar0() uint64 { return 0 } func getisar1() uint64 { return 0 } +func getmmfr1() uint64 { return 0 } func getpfr0() uint64 { return 0 } diff --git a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go index ebfb3fc8..19aea063 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go @@ -167,7 +167,7 @@ func doinit() { setMinimalFeatures() return } - parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0) + parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64mmfr1, cpuid.aa64pfr0) Initialized = true } diff --git a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go index 85b64d5c..87fd3a77 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go @@ -59,7 +59,7 @@ func doinit() { if !ok { return } - parseARM64SystemRegisters(isar0, isar1, 0) + parseARM64SystemRegisters(isar0, isar1, 0, 0) Initialized = true } diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.s b/vendor/golang.org/x/sys/cpu/cpu_x86.s deleted file mode 100644 index 7d7ba33e..00000000 --- a/vendor/golang.org/x/sys/cpu/cpu_x86.s +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (386 || amd64 || amd64p32) && gc - -#include "textflag.h" - -// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) -TEXT ·cpuid(SB), NOSPLIT, $0-24 - MOVL eaxArg+0(FP), AX - MOVL ecxArg+4(FP), CX - CPUID - MOVL AX, eax+8(FP) - MOVL BX, ebx+12(FP) - MOVL CX, ecx+16(FP) - MOVL DX, edx+20(FP) - RET - -// func xgetbv() (eax, edx uint32) -TEXT ·xgetbv(SB),NOSPLIT,$0-8 - MOVL $0, CX - XGETBV - MOVL AX, eax+0(FP) - MOVL DX, edx+4(FP) - RET diff --git a/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go b/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go deleted file mode 100644 index e07899b9..00000000 --- a/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package unsafeheader contains header declarations for the Go runtime's -// slice and string implementations. -// -// This package allows x/sys to use types equivalent to -// reflect.SliceHeader and reflect.StringHeader without introducing -// a dependency on the (relatively heavy) "reflect" package. -package unsafeheader - -import ( - "unsafe" -) - -// Slice is the runtime representation of a slice. -// It cannot be used safely or portably and its representation may change in a later release. -type Slice struct { - Data unsafe.Pointer - Len int - Cap int -} - -// String is the runtime representation of a string. -// It cannot be used safely or portably and its representation may change in a later release. -type String struct { - Data unsafe.Pointer - Len int -} diff --git a/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go b/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go deleted file mode 100644 index 73687de7..00000000 --- a/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.5 - -package plan9 - -import "syscall" - -func fixwd() { - syscall.Fixwd() -} - -func Getwd() (wd string, err error) { - return syscall.Getwd() -} - -func Chdir(path string) error { - return syscall.Chdir(path) -} diff --git a/vendor/golang.org/x/sys/plan9/pwd_plan9.go b/vendor/golang.org/x/sys/plan9/pwd_plan9.go index fb945821..7a76489d 100644 --- a/vendor/golang.org/x/sys/plan9/pwd_plan9.go +++ b/vendor/golang.org/x/sys/plan9/pwd_plan9.go @@ -2,22 +2,18 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !go1.5 - package plan9 +import "syscall" + func fixwd() { + syscall.Fixwd() } func Getwd() (wd string, err error) { - fd, err := open(".", O_RDONLY) - if err != nil { - return "", err - } - defer Close(fd) - return Fd2path(fd) + return syscall.Getwd() } func Chdir(path string) error { - return chdir(path) + return syscall.Chdir(path) } diff --git a/vendor/golang.org/x/sys/unix/affinity_linux.go b/vendor/golang.org/x/sys/unix/affinity_linux.go index 6e5c81ac..3ea47038 100644 --- a/vendor/golang.org/x/sys/unix/affinity_linux.go +++ b/vendor/golang.org/x/sys/unix/affinity_linux.go @@ -38,8 +38,15 @@ func SchedSetaffinity(pid int, set *CPUSet) error { // Zero clears the set s, so that it contains no CPUs. func (s *CPUSet) Zero() { + clear(s[:]) +} + +// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity] +// will silently ignore any invalid CPU bits in [CPUSet] so this is an +// efficient way of resetting the CPU affinity of a process. +func (s *CPUSet) Fill() { for i := range s { - s[i] = 0 + s[i] = ^cpuMask(0) } } diff --git a/vendor/golang.org/x/sys/unix/epoll_zos.go b/vendor/golang.org/x/sys/unix/epoll_zos.go deleted file mode 100644 index 7753fdde..00000000 --- a/vendor/golang.org/x/sys/unix/epoll_zos.go +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build zos && s390x - -package unix - -import ( - "sync" -) - -// This file simulates epoll on z/OS using poll. - -// Analogous to epoll_event on Linux. -// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove? -type EpollEvent struct { - Events uint32 - Fd int32 - Pad int32 -} - -const ( - EPOLLERR = 0x8 - EPOLLHUP = 0x10 - EPOLLIN = 0x1 - EPOLLMSG = 0x400 - EPOLLOUT = 0x4 - EPOLLPRI = 0x2 - EPOLLRDBAND = 0x80 - EPOLLRDNORM = 0x40 - EPOLLWRBAND = 0x200 - EPOLLWRNORM = 0x100 - EPOLL_CTL_ADD = 0x1 - EPOLL_CTL_DEL = 0x2 - EPOLL_CTL_MOD = 0x3 - // The following constants are part of the epoll API, but represent - // currently unsupported functionality on z/OS. - // EPOLL_CLOEXEC = 0x80000 - // EPOLLET = 0x80000000 - // EPOLLONESHOT = 0x40000000 - // EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis - // EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode - // EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability -) - -// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL -// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16). - -// epToPollEvt converts epoll event field to poll equivalent. -// In epoll, Events is a 32-bit field, while poll uses 16 bits. -func epToPollEvt(events uint32) int16 { - var ep2p = map[uint32]int16{ - EPOLLIN: POLLIN, - EPOLLOUT: POLLOUT, - EPOLLHUP: POLLHUP, - EPOLLPRI: POLLPRI, - EPOLLERR: POLLERR, - } - - var pollEvts int16 = 0 - for epEvt, pEvt := range ep2p { - if (events & epEvt) != 0 { - pollEvts |= pEvt - } - } - - return pollEvts -} - -// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields. -func pToEpollEvt(revents int16) uint32 { - var p2ep = map[int16]uint32{ - POLLIN: EPOLLIN, - POLLOUT: EPOLLOUT, - POLLHUP: EPOLLHUP, - POLLPRI: EPOLLPRI, - POLLERR: EPOLLERR, - } - - var epollEvts uint32 = 0 - for pEvt, epEvt := range p2ep { - if (revents & pEvt) != 0 { - epollEvts |= epEvt - } - } - - return epollEvts -} - -// Per-process epoll implementation. -type epollImpl struct { - mu sync.Mutex - epfd2ep map[int]*eventPoll - nextEpfd int -} - -// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances. -// On Linux, this is an in-kernel data structure accessed through a fd. -type eventPoll struct { - mu sync.Mutex - fds map[int]*EpollEvent -} - -// epoll impl for this process. -var impl epollImpl = epollImpl{ - epfd2ep: make(map[int]*eventPoll), - nextEpfd: 0, -} - -func (e *epollImpl) epollcreate(size int) (epfd int, err error) { - e.mu.Lock() - defer e.mu.Unlock() - epfd = e.nextEpfd - e.nextEpfd++ - - e.epfd2ep[epfd] = &eventPoll{ - fds: make(map[int]*EpollEvent), - } - return epfd, nil -} - -func (e *epollImpl) epollcreate1(flag int) (fd int, err error) { - return e.epollcreate(4) -} - -func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) { - e.mu.Lock() - defer e.mu.Unlock() - - ep, ok := e.epfd2ep[epfd] - if !ok { - - return EBADF - } - - switch op { - case EPOLL_CTL_ADD: - // TODO(neeilan): When we make epfds and fds disjoint, detect epoll - // loops here (instances watching each other) and return ELOOP. - if _, ok := ep.fds[fd]; ok { - return EEXIST - } - ep.fds[fd] = event - case EPOLL_CTL_MOD: - if _, ok := ep.fds[fd]; !ok { - return ENOENT - } - ep.fds[fd] = event - case EPOLL_CTL_DEL: - if _, ok := ep.fds[fd]; !ok { - return ENOENT - } - delete(ep.fds, fd) - - } - return nil -} - -// Must be called while holding ep.mu -func (ep *eventPoll) getFds() []int { - fds := make([]int, len(ep.fds)) - for fd := range ep.fds { - fds = append(fds, fd) - } - return fds -} - -func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) { - e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait - ep, ok := e.epfd2ep[epfd] - - if !ok { - e.mu.Unlock() - return 0, EBADF - } - - pollfds := make([]PollFd, 4) - for fd, epollevt := range ep.fds { - pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)}) - } - e.mu.Unlock() - - n, err = Poll(pollfds, msec) - if err != nil { - return n, err - } - - i := 0 - for _, pFd := range pollfds { - if pFd.Revents != 0 { - events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)} - i++ - } - - if i == n { - break - } - } - - return n, nil -} - -func EpollCreate(size int) (fd int, err error) { - return impl.epollcreate(size) -} - -func EpollCreate1(flag int) (fd int, err error) { - return impl.epollcreate1(flag) -} - -func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { - return impl.epollctl(epfd, op, fd, event) -} - -// Because EpollWait mutates events, the caller is expected to coordinate -// concurrent access if calling with the same epfd from multiple goroutines. -func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { - return impl.epollwait(epfd, events, msec) -} diff --git a/vendor/golang.org/x/sys/unix/fdset.go b/vendor/golang.org/x/sys/unix/fdset.go index 9e83d18c..62ed1264 100644 --- a/vendor/golang.org/x/sys/unix/fdset.go +++ b/vendor/golang.org/x/sys/unix/fdset.go @@ -23,7 +23,5 @@ func (fds *FdSet) IsSet(fd int) bool { // Zero clears the set fds. func (fds *FdSet) Zero() { - for i := range fds.Bits { - fds.Bits[i] = 0 - } + clear(fds.Bits[:]) } diff --git a/vendor/golang.org/x/sys/unix/fstatfs_zos.go b/vendor/golang.org/x/sys/unix/fstatfs_zos.go deleted file mode 100644 index c8bde601..00000000 --- a/vendor/golang.org/x/sys/unix/fstatfs_zos.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build zos && s390x - -package unix - -import ( - "unsafe" -) - -// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent. - -func Fstatfs(fd int, stat *Statfs_t) (err error) { - var stat_v Statvfs_t - err = Fstatvfs(fd, &stat_v) - if err == nil { - // populate stat - stat.Type = 0 - stat.Bsize = stat_v.Bsize - stat.Blocks = stat_v.Blocks - stat.Bfree = stat_v.Bfree - stat.Bavail = stat_v.Bavail - stat.Files = stat_v.Files - stat.Ffree = stat_v.Ffree - stat.Fsid = stat_v.Fsid - stat.Namelen = stat_v.Namemax - stat.Frsize = stat_v.Frsize - stat.Flags = stat_v.Flag - for passn := 0; passn < 5; passn++ { - switch passn { - case 0: - err = tryGetmntent64(stat) - break - case 1: - err = tryGetmntent128(stat) - break - case 2: - err = tryGetmntent256(stat) - break - case 3: - err = tryGetmntent512(stat) - break - case 4: - err = tryGetmntent1024(stat) - break - default: - break - } - //proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred) - if err == nil || err != nil && err != ERANGE { - break - } - } - } - return err -} - -func tryGetmntent64(stat *Statfs_t) (err error) { - var mnt_ent_buffer struct { - header W_Mnth - filesys_info [64]W_Mntent - } - var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) - fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) - if err != nil { - return err - } - err = ERANGE //return ERANGE if no match is found in this batch - for i := 0; i < fs_count; i++ { - if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { - stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) - err = nil - break - } - } - return err -} - -func tryGetmntent128(stat *Statfs_t) (err error) { - var mnt_ent_buffer struct { - header W_Mnth - filesys_info [128]W_Mntent - } - var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) - fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) - if err != nil { - return err - } - err = ERANGE //return ERANGE if no match is found in this batch - for i := 0; i < fs_count; i++ { - if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { - stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) - err = nil - break - } - } - return err -} - -func tryGetmntent256(stat *Statfs_t) (err error) { - var mnt_ent_buffer struct { - header W_Mnth - filesys_info [256]W_Mntent - } - var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) - fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) - if err != nil { - return err - } - err = ERANGE //return ERANGE if no match is found in this batch - for i := 0; i < fs_count; i++ { - if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { - stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) - err = nil - break - } - } - return err -} - -func tryGetmntent512(stat *Statfs_t) (err error) { - var mnt_ent_buffer struct { - header W_Mnth - filesys_info [512]W_Mntent - } - var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) - fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) - if err != nil { - return err - } - err = ERANGE //return ERANGE if no match is found in this batch - for i := 0; i < fs_count; i++ { - if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { - stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) - err = nil - break - } - } - return err -} - -func tryGetmntent1024(stat *Statfs_t) (err error) { - var mnt_ent_buffer struct { - header W_Mnth - filesys_info [1024]W_Mntent - } - var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) - fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) - if err != nil { - return err - } - err = ERANGE //return ERANGE if no match is found in this batch - for i := 0; i < fs_count; i++ { - if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { - stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) - err = nil - break - } - } - return err -} diff --git a/vendor/golang.org/x/sys/unix/ifreq_linux.go b/vendor/golang.org/x/sys/unix/ifreq_linux.go index 848840ae..309f5a2b 100644 --- a/vendor/golang.org/x/sys/unix/ifreq_linux.go +++ b/vendor/golang.org/x/sys/unix/ifreq_linux.go @@ -111,9 +111,7 @@ func (ifr *Ifreq) SetUint32(v uint32) { // clear zeroes the ifreq's union field to prevent trailing garbage data from // being sent to the kernel if an ifreq is reused. func (ifr *Ifreq) clear() { - for i := range ifr.raw.Ifru { - ifr.raw.Ifru[i] = 0 - } + clear(ifr.raw.Ifru[:]) } // TODO(mdlayher): export as IfreqData? For now we can provide helpers such as diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index e6f31d37..d0ed6119 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -49,6 +49,7 @@ esac if [[ "$GOOS" = "linux" ]]; then # Use the Docker-based build system # Files generated through docker (use $cmd so you can Ctl-C the build or run) + set -e $cmd docker build --tag generate:$GOOS $GOOS $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS exit diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 6ab02b6c..42517077 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -226,6 +226,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -349,6 +350,9 @@ struct ltchars { #define _HIDIOCGRAWPHYS HIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN) #define _HIDIOCGRAWUNIQ HIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN) +// Renamed in v6.16, commit c6d732c38f93 ("net: ethtool: remove duplicate defines for family info") +#define ETHTOOL_FAMILY_NAME ETHTOOL_GENL_NAME +#define ETHTOOL_FAMILY_VERSION ETHTOOL_GENL_VERSION ' includes_NetBSD=' @@ -526,6 +530,7 @@ ccflags="$@" $2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ || $2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ || + $2 ~ /^(DT|EI|ELF|EV|NN|NT|PF|SHF|SHN|SHT|STB|STT|VER)_/ || $2 ~ /^O?XTABS$/ || $2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^IN_/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 798f61ad..7838ca5d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -602,14 +602,9 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI return } -// sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) const minIovec = 8 func Readv(fd int, iovs [][]byte) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } - iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) n, err = readv(fd, iovecs) @@ -618,9 +613,6 @@ func Readv(fd int, iovs [][]byte) (n int, err error) { } func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) n, err = preadv(fd, iovecs, offset) @@ -629,10 +621,6 @@ func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { } func Writev(fd int, iovs [][]byte) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } - iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) if raceenabled { @@ -644,10 +632,6 @@ func Writev(fd int, iovs [][]byte) (n int, err error) { } func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { - if !darwinKernelVersionMin(11, 0, 0) { - return 0, ENOSYS - } - iovecs := make([]Iovec, 0, minIovec) iovecs = appendBytes(iovecs, iovs) if raceenabled { @@ -707,45 +691,7 @@ func readvRacedetect(iovecs []Iovec, n int, err error) { } } -func darwinMajorMinPatch() (maj, min, patch int, err error) { - var un Utsname - err = Uname(&un) - if err != nil { - return - } - - var mmp [3]int - c := 0 -Loop: - for _, b := range un.Release[:] { - switch { - case b >= '0' && b <= '9': - mmp[c] = 10*mmp[c] + int(b-'0') - case b == '.': - c++ - if c > 2 { - return 0, 0, 0, ENOTSUP - } - case b == 0: - break Loop - default: - return 0, 0, 0, ENOTSUP - } - } - if c != 2 { - return 0, 0, 0, ENOTSUP - } - return mmp[0], mmp[1], mmp[2], nil -} - -func darwinKernelVersionMin(maj, min, patch int) bool { - actualMaj, actualMin, actualPatch, err := darwinMajorMinPatch() - if err != nil { - return false - } - return actualMaj > maj || actualMaj == maj && (actualMin > min || actualMin == min && actualPatch >= patch) -} - +//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 4958a657..06c0eea6 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -801,9 +801,7 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { // one. The kernel expects SID to be in network byte order. binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) copy(sa.raw[8:14], sa.Remote) - for i := 14; i < 14+IFNAMSIZ; i++ { - sa.raw[i] = 0 - } + clear(sa.raw[14 : 14+IFNAMSIZ]) copy(sa.raw[14:], sa.Dev) return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil } @@ -2645,3 +2643,9 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) //sys Mseal(b []byte, flags uint) (err error) + +//sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY + +func SetMemPolicy(mode int, mask *CPUSet) error { + return setMemPolicy(mode, mask, _CPU_SETSIZE) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index 88162099..34a46769 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -248,6 +248,23 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { return Statvfs1(path, buf, ST_WAIT) } +func Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) { + var ( + _p0 unsafe.Pointer + bufsize uintptr + ) + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + bufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf)) + } + r0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) + n = int(r0) + if e1 != 0 { + err = e1 + } + return +} + /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index abc39554..18a3d9bd 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -629,7 +629,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Kill(pid int, signum syscall.Signal) (err error) //sys Lchown(path string, uid int, gid int) (err error) //sys Link(path string, link string) (err error) -//sys Listen(s int, backlog int) (err error) = libsocket.__xnet_llisten +//sys Listen(s int, backlog int) (err error) = libsocket.__xnet_listen //sys Lstat(path string, stat *Stat_t) (err error) //sys Madvise(b []byte, advice int) (err error) //sys Mkdir(path string, mode uint32) (err error) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 4f432bfe..d0a75da5 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -319,6 +319,7 @@ const ( AUDIT_INTEGRITY_POLICY_RULE = 0x70f AUDIT_INTEGRITY_RULE = 0x70d AUDIT_INTEGRITY_STATUS = 0x70a + AUDIT_INTEGRITY_USERSPACE = 0x710 AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f AUDIT_IPE_ACCESS = 0x58c @@ -327,6 +328,8 @@ const ( AUDIT_KERNEL = 0x7d0 AUDIT_KERNEL_OTHER = 0x524 AUDIT_KERN_MODULE = 0x532 + AUDIT_LANDLOCK_ACCESS = 0x58f + AUDIT_LANDLOCK_DOMAIN = 0x590 AUDIT_LAST_FEATURE = 0x1 AUDIT_LAST_KERN_ANOM_MSG = 0x707 AUDIT_LAST_USER_MSG = 0x4af @@ -491,6 +494,7 @@ const ( BPF_F_BEFORE = 0x8 BPF_F_ID = 0x20 BPF_F_NETFILTER_IP_DEFRAG = 0x1 + BPF_F_PREORDER = 0x40 BPF_F_QUERY_EFFECTIVE = 0x1 BPF_F_REDIRECT_FLAGS = 0x19 BPF_F_REPLACE = 0x4 @@ -527,6 +531,7 @@ const ( BPF_LDX = 0x1 BPF_LEN = 0x80 BPF_LL_OFF = -0x200000 + BPF_LOAD_ACQ = 0x100 BPF_LSH = 0x60 BPF_MAJOR_VERSION = 0x1 BPF_MAXINSNS = 0x1000 @@ -554,6 +559,7 @@ const ( BPF_RET = 0x6 BPF_RSH = 0x70 BPF_ST = 0x2 + BPF_STORE_REL = 0x110 BPF_STX = 0x3 BPF_SUB = 0x10 BPF_TAG_SIZE = 0x8 @@ -843,24 +849,90 @@ const ( DM_UUID_FLAG = 0x4000 DM_UUID_LEN = 0x81 DM_VERSION = 0xc138fd00 - DM_VERSION_EXTRA = "-ioctl (2023-03-01)" + DM_VERSION_EXTRA = "-ioctl (2025-04-28)" DM_VERSION_MAJOR = 0x4 - DM_VERSION_MINOR = 0x30 + DM_VERSION_MINOR = 0x32 DM_VERSION_PATCHLEVEL = 0x0 + DT_ADDRRNGHI = 0x6ffffeff + DT_ADDRRNGLO = 0x6ffffe00 DT_BLK = 0x6 DT_CHR = 0x2 + DT_DEBUG = 0x15 DT_DIR = 0x4 + DT_ENCODING = 0x20 DT_FIFO = 0x1 + DT_FINI = 0xd + DT_FLAGS_1 = 0x6ffffffb + DT_GNU_HASH = 0x6ffffef5 + DT_HASH = 0x4 + DT_HIOS = 0x6ffff000 + DT_HIPROC = 0x7fffffff + DT_INIT = 0xc + DT_JMPREL = 0x17 DT_LNK = 0xa + DT_LOOS = 0x6000000d + DT_LOPROC = 0x70000000 + DT_NEEDED = 0x1 + DT_NULL = 0x0 + DT_PLTGOT = 0x3 + DT_PLTREL = 0x14 + DT_PLTRELSZ = 0x2 DT_REG = 0x8 + DT_REL = 0x11 + DT_RELA = 0x7 + DT_RELACOUNT = 0x6ffffff9 + DT_RELAENT = 0x9 + DT_RELASZ = 0x8 + DT_RELCOUNT = 0x6ffffffa + DT_RELENT = 0x13 + DT_RELSZ = 0x12 + DT_RPATH = 0xf DT_SOCK = 0xc + DT_SONAME = 0xe + DT_STRSZ = 0xa + DT_STRTAB = 0x5 + DT_SYMBOLIC = 0x10 + DT_SYMENT = 0xb + DT_SYMTAB = 0x6 + DT_TEXTREL = 0x16 DT_UNKNOWN = 0x0 + DT_VALRNGHI = 0x6ffffdff + DT_VALRNGLO = 0x6ffffd00 + DT_VERDEF = 0x6ffffffc + DT_VERDEFNUM = 0x6ffffffd + DT_VERNEED = 0x6ffffffe + DT_VERNEEDNUM = 0x6fffffff + DT_VERSYM = 0x6ffffff0 DT_WHT = 0xe ECHO = 0x8 ECRYPTFS_SUPER_MAGIC = 0xf15f EFD_SEMAPHORE = 0x1 EFIVARFS_MAGIC = 0xde5e81e4 EFS_SUPER_MAGIC = 0x414a53 + EI_CLASS = 0x4 + EI_DATA = 0x5 + EI_MAG0 = 0x0 + EI_MAG1 = 0x1 + EI_MAG2 = 0x2 + EI_MAG3 = 0x3 + EI_NIDENT = 0x10 + EI_OSABI = 0x7 + EI_PAD = 0x8 + EI_VERSION = 0x6 + ELFCLASS32 = 0x1 + ELFCLASS64 = 0x2 + ELFCLASSNONE = 0x0 + ELFCLASSNUM = 0x3 + ELFDATA2LSB = 0x1 + ELFDATA2MSB = 0x2 + ELFDATANONE = 0x0 + ELFMAG = "\177ELF" + ELFMAG0 = 0x7f + ELFMAG1 = 'E' + ELFMAG2 = 'L' + ELFMAG3 = 'F' + ELFOSABI_LINUX = 0x3 + ELFOSABI_NONE = 0x0 EM_386 = 0x3 EM_486 = 0x6 EM_68K = 0x4 @@ -936,11 +1008,10 @@ const ( EPOLL_CTL_MOD = 0x3 EPOLL_IOC_TYPE = 0x8a EROFS_SUPER_MAGIC_V1 = 0xe0f5e1e2 - ESP_V4_FLOW = 0xa - ESP_V6_FLOW = 0xc - ETHER_FLOW = 0x12 ETHTOOL_BUSINFO_LEN = 0x20 ETHTOOL_EROMVERS_LEN = 0x20 + ETHTOOL_FAMILY_NAME = "ethtool" + ETHTOOL_FAMILY_VERSION = 0x1 ETHTOOL_FEC_AUTO = 0x2 ETHTOOL_FEC_BASER = 0x10 ETHTOOL_FEC_LLRS = 0x20 @@ -1147,14 +1218,24 @@ const ( ETH_P_WCCP = 0x883e ETH_P_X25 = 0x805 ETH_P_XDSA = 0xf8 + ET_CORE = 0x4 + ET_DYN = 0x3 + ET_EXEC = 0x2 + ET_HIPROC = 0xffff + ET_LOPROC = 0xff00 + ET_NONE = 0x0 + ET_REL = 0x1 EV_ABS = 0x3 EV_CNT = 0x20 + EV_CURRENT = 0x1 EV_FF = 0x15 EV_FF_STATUS = 0x17 EV_KEY = 0x1 EV_LED = 0x11 EV_MAX = 0x1f EV_MSC = 0x4 + EV_NONE = 0x0 + EV_NUM = 0x2 EV_PWR = 0x16 EV_REL = 0x2 EV_REP = 0x14 @@ -1203,13 +1284,18 @@ const ( FAN_DENY = 0x2 FAN_ENABLE_AUDIT = 0x40 FAN_EPIDFD = -0x2 + FAN_ERRNO_BITS = 0x8 + FAN_ERRNO_MASK = 0xff + FAN_ERRNO_SHIFT = 0x18 FAN_EVENT_INFO_TYPE_DFID = 0x3 FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 FAN_EVENT_INFO_TYPE_ERROR = 0x5 FAN_EVENT_INFO_TYPE_FID = 0x1 + FAN_EVENT_INFO_TYPE_MNT = 0x7 FAN_EVENT_INFO_TYPE_NEW_DFID_NAME = 0xc FAN_EVENT_INFO_TYPE_OLD_DFID_NAME = 0xa FAN_EVENT_INFO_TYPE_PIDFD = 0x4 + FAN_EVENT_INFO_TYPE_RANGE = 0x6 FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_ON_CHILD = 0x8000000 FAN_FS_ERROR = 0x8000 @@ -1224,9 +1310,12 @@ const ( FAN_MARK_IGNORED_SURV_MODIFY = 0x40 FAN_MARK_IGNORE_SURV = 0x440 FAN_MARK_INODE = 0x0 + FAN_MARK_MNTNS = 0x110 FAN_MARK_MOUNT = 0x10 FAN_MARK_ONLYDIR = 0x8 FAN_MARK_REMOVE = 0x2 + FAN_MNT_ATTACH = 0x1000000 + FAN_MNT_DETACH = 0x2000000 FAN_MODIFY = 0x2 FAN_MOVE = 0xc0 FAN_MOVED_FROM = 0x40 @@ -1240,6 +1329,7 @@ const ( FAN_OPEN_EXEC = 0x1000 FAN_OPEN_EXEC_PERM = 0x40000 FAN_OPEN_PERM = 0x10000 + FAN_PRE_ACCESS = 0x100000 FAN_Q_OVERFLOW = 0x4000 FAN_RENAME = 0x10000000 FAN_REPORT_DFID_NAME = 0xc00 @@ -1247,6 +1337,7 @@ const ( FAN_REPORT_DIR_FID = 0x400 FAN_REPORT_FD_ERROR = 0x2000 FAN_REPORT_FID = 0x200 + FAN_REPORT_MNT = 0x4000 FAN_REPORT_NAME = 0x800 FAN_REPORT_PIDFD = 0x80 FAN_REPORT_TARGET_FID = 0x1000 @@ -1266,6 +1357,7 @@ const ( FIB_RULE_PERMANENT = 0x1 FIB_RULE_UNRESOLVED = 0x4 FIDEDUPERANGE = 0xc0189436 + FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED = 0x1 FSCRYPT_KEY_DESCRIPTOR_SIZE = 0x8 FSCRYPT_KEY_DESC_PREFIX = "fscrypt:" FSCRYPT_KEY_DESC_PREFIX_SIZE = 0x8 @@ -1574,7 +1666,6 @@ const ( IPV6_DONTFRAG = 0x3e IPV6_DROP_MEMBERSHIP = 0x15 IPV6_DSTOPTS = 0x3b - IPV6_FLOW = 0x11 IPV6_FREEBIND = 0x4e IPV6_HDRINCL = 0x24 IPV6_HOPLIMIT = 0x34 @@ -1625,7 +1716,6 @@ const ( IPV6_TRANSPARENT = 0x4b IPV6_UNICAST_HOPS = 0x10 IPV6_UNICAST_IF = 0x4c - IPV6_USER_FLOW = 0xe IPV6_V6ONLY = 0x1a IPV6_VERSION = 0x60 IPV6_VERSION_MASK = 0xf0 @@ -1687,7 +1777,6 @@ const ( IP_TTL = 0x2 IP_UNBLOCK_SOURCE = 0x25 IP_UNICAST_IF = 0x32 - IP_USER_FLOW = 0xd IP_XFRM_POLICY = 0x11 ISOFS_SUPER_MAGIC = 0x9660 ISTRIP = 0x20 @@ -1809,7 +1898,11 @@ const ( LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 + LANDLOCK_CREATE_RULESET_ERRATA = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 + LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON = 0x2 + LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF = 0x1 + LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF = 0x4 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = 0x1 LANDLOCK_SCOPE_SIGNAL = 0x2 LINUX_REBOOT_CMD_CAD_OFF = 0x0 @@ -2259,7 +2352,167 @@ const ( NLM_F_REPLACE = 0x100 NLM_F_REQUEST = 0x1 NLM_F_ROOT = 0x100 + NN_386_IOPERM = "LINUX" + NN_386_TLS = "LINUX" + NN_ARC_V2 = "LINUX" + NN_ARM_FPMR = "LINUX" + NN_ARM_GCS = "LINUX" + NN_ARM_HW_BREAK = "LINUX" + NN_ARM_HW_WATCH = "LINUX" + NN_ARM_PACA_KEYS = "LINUX" + NN_ARM_PACG_KEYS = "LINUX" + NN_ARM_PAC_ENABLED_KEYS = "LINUX" + NN_ARM_PAC_MASK = "LINUX" + NN_ARM_POE = "LINUX" + NN_ARM_SSVE = "LINUX" + NN_ARM_SVE = "LINUX" + NN_ARM_SYSTEM_CALL = "LINUX" + NN_ARM_TAGGED_ADDR_CTRL = "LINUX" + NN_ARM_TLS = "LINUX" + NN_ARM_VFP = "LINUX" + NN_ARM_ZA = "LINUX" + NN_ARM_ZT = "LINUX" + NN_AUXV = "CORE" + NN_FILE = "CORE" + NN_GNU_PROPERTY_TYPE_0 = "GNU" + NN_LOONGARCH_CPUCFG = "LINUX" + NN_LOONGARCH_CSR = "LINUX" + NN_LOONGARCH_HW_BREAK = "LINUX" + NN_LOONGARCH_HW_WATCH = "LINUX" + NN_LOONGARCH_LASX = "LINUX" + NN_LOONGARCH_LBT = "LINUX" + NN_LOONGARCH_LSX = "LINUX" + NN_MIPS_DSP = "LINUX" + NN_MIPS_FP_MODE = "LINUX" + NN_MIPS_MSA = "LINUX" + NN_PPC_DEXCR = "LINUX" + NN_PPC_DSCR = "LINUX" + NN_PPC_EBB = "LINUX" + NN_PPC_HASHKEYR = "LINUX" + NN_PPC_PKEY = "LINUX" + NN_PPC_PMU = "LINUX" + NN_PPC_PPR = "LINUX" + NN_PPC_SPE = "LINUX" + NN_PPC_TAR = "LINUX" + NN_PPC_TM_CDSCR = "LINUX" + NN_PPC_TM_CFPR = "LINUX" + NN_PPC_TM_CGPR = "LINUX" + NN_PPC_TM_CPPR = "LINUX" + NN_PPC_TM_CTAR = "LINUX" + NN_PPC_TM_CVMX = "LINUX" + NN_PPC_TM_CVSX = "LINUX" + NN_PPC_TM_SPR = "LINUX" + NN_PPC_VMX = "LINUX" + NN_PPC_VSX = "LINUX" + NN_PRFPREG = "CORE" + NN_PRPSINFO = "CORE" + NN_PRSTATUS = "CORE" + NN_PRXFPREG = "LINUX" + NN_RISCV_CSR = "LINUX" + NN_RISCV_TAGGED_ADDR_CTRL = "LINUX" + NN_RISCV_VECTOR = "LINUX" + NN_S390_CTRS = "LINUX" + NN_S390_GS_BC = "LINUX" + NN_S390_GS_CB = "LINUX" + NN_S390_HIGH_GPRS = "LINUX" + NN_S390_LAST_BREAK = "LINUX" + NN_S390_PREFIX = "LINUX" + NN_S390_PV_CPU_DATA = "LINUX" + NN_S390_RI_CB = "LINUX" + NN_S390_SYSTEM_CALL = "LINUX" + NN_S390_TDB = "LINUX" + NN_S390_TIMER = "LINUX" + NN_S390_TODCMP = "LINUX" + NN_S390_TODPREG = "LINUX" + NN_S390_VXRS_HIGH = "LINUX" + NN_S390_VXRS_LOW = "LINUX" + NN_SIGINFO = "CORE" + NN_TASKSTRUCT = "CORE" + NN_VMCOREDD = "LINUX" + NN_X86_SHSTK = "LINUX" + NN_X86_XSAVE_LAYOUT = "LINUX" + NN_X86_XSTATE = "LINUX" NSFS_MAGIC = 0x6e736673 + NT_386_IOPERM = 0x201 + NT_386_TLS = 0x200 + NT_ARC_V2 = 0x600 + NT_ARM_FPMR = 0x40e + NT_ARM_GCS = 0x410 + NT_ARM_HW_BREAK = 0x402 + NT_ARM_HW_WATCH = 0x403 + NT_ARM_PACA_KEYS = 0x407 + NT_ARM_PACG_KEYS = 0x408 + NT_ARM_PAC_ENABLED_KEYS = 0x40a + NT_ARM_PAC_MASK = 0x406 + NT_ARM_POE = 0x40f + NT_ARM_SSVE = 0x40b + NT_ARM_SVE = 0x405 + NT_ARM_SYSTEM_CALL = 0x404 + NT_ARM_TAGGED_ADDR_CTRL = 0x409 + NT_ARM_TLS = 0x401 + NT_ARM_VFP = 0x400 + NT_ARM_ZA = 0x40c + NT_ARM_ZT = 0x40d + NT_AUXV = 0x6 + NT_FILE = 0x46494c45 + NT_GNU_PROPERTY_TYPE_0 = 0x5 + NT_LOONGARCH_CPUCFG = 0xa00 + NT_LOONGARCH_CSR = 0xa01 + NT_LOONGARCH_HW_BREAK = 0xa05 + NT_LOONGARCH_HW_WATCH = 0xa06 + NT_LOONGARCH_LASX = 0xa03 + NT_LOONGARCH_LBT = 0xa04 + NT_LOONGARCH_LSX = 0xa02 + NT_MIPS_DSP = 0x800 + NT_MIPS_FP_MODE = 0x801 + NT_MIPS_MSA = 0x802 + NT_PPC_DEXCR = 0x111 + NT_PPC_DSCR = 0x105 + NT_PPC_EBB = 0x106 + NT_PPC_HASHKEYR = 0x112 + NT_PPC_PKEY = 0x110 + NT_PPC_PMU = 0x107 + NT_PPC_PPR = 0x104 + NT_PPC_SPE = 0x101 + NT_PPC_TAR = 0x103 + NT_PPC_TM_CDSCR = 0x10f + NT_PPC_TM_CFPR = 0x109 + NT_PPC_TM_CGPR = 0x108 + NT_PPC_TM_CPPR = 0x10e + NT_PPC_TM_CTAR = 0x10d + NT_PPC_TM_CVMX = 0x10a + NT_PPC_TM_CVSX = 0x10b + NT_PPC_TM_SPR = 0x10c + NT_PPC_VMX = 0x100 + NT_PPC_VSX = 0x102 + NT_PRFPREG = 0x2 + NT_PRPSINFO = 0x3 + NT_PRSTATUS = 0x1 + NT_PRXFPREG = 0x46e62b7f + NT_RISCV_CSR = 0x900 + NT_RISCV_TAGGED_ADDR_CTRL = 0x902 + NT_RISCV_VECTOR = 0x901 + NT_S390_CTRS = 0x304 + NT_S390_GS_BC = 0x30c + NT_S390_GS_CB = 0x30b + NT_S390_HIGH_GPRS = 0x300 + NT_S390_LAST_BREAK = 0x306 + NT_S390_PREFIX = 0x305 + NT_S390_PV_CPU_DATA = 0x30e + NT_S390_RI_CB = 0x30d + NT_S390_SYSTEM_CALL = 0x307 + NT_S390_TDB = 0x308 + NT_S390_TIMER = 0x301 + NT_S390_TODCMP = 0x302 + NT_S390_TODPREG = 0x303 + NT_S390_VXRS_HIGH = 0x30a + NT_S390_VXRS_LOW = 0x309 + NT_SIGINFO = 0x53494749 + NT_TASKSTRUCT = 0x4 + NT_VMCOREDD = 0x700 + NT_X86_SHSTK = 0x204 + NT_X86_XSAVE_LAYOUT = 0x205 + NT_X86_XSTATE = 0x202 OCFS2_SUPER_MAGIC = 0x7461636f OCRNL = 0x8 OFDEL = 0x80 @@ -2446,6 +2699,59 @@ const ( PERF_RECORD_MISC_USER = 0x2 PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 + PF_ALG = 0x26 + PF_APPLETALK = 0x5 + PF_ASH = 0x12 + PF_ATMPVC = 0x8 + PF_ATMSVC = 0x14 + PF_AX25 = 0x3 + PF_BLUETOOTH = 0x1f + PF_BRIDGE = 0x7 + PF_CAIF = 0x25 + PF_CAN = 0x1d + PF_DECnet = 0xc + PF_ECONET = 0x13 + PF_FILE = 0x1 + PF_IB = 0x1b + PF_IEEE802154 = 0x24 + PF_INET = 0x2 + PF_INET6 = 0xa + PF_IPX = 0x4 + PF_IRDA = 0x17 + PF_ISDN = 0x22 + PF_IUCV = 0x20 + PF_KCM = 0x29 + PF_KEY = 0xf + PF_LLC = 0x1a + PF_LOCAL = 0x1 + PF_MAX = 0x2e + PF_MCTP = 0x2d + PF_MPLS = 0x1c + PF_NETBEUI = 0xd + PF_NETLINK = 0x10 + PF_NETROM = 0x6 + PF_NFC = 0x27 + PF_PACKET = 0x11 + PF_PHONET = 0x23 + PF_PPPOX = 0x18 + PF_QIPCRTR = 0x2a + PF_R = 0x4 + PF_RDS = 0x15 + PF_ROSE = 0xb + PF_ROUTE = 0x10 + PF_RXRPC = 0x21 + PF_SECURITY = 0xe + PF_SMC = 0x2b + PF_SNA = 0x16 + PF_TIPC = 0x1e + PF_UNIX = 0x1 + PF_UNSPEC = 0x0 + PF_VSOCK = 0x28 + PF_W = 0x2 + PF_WANPIPE = 0x19 + PF_X = 0x1 + PF_X25 = 0x9 + PF_XDP = 0x2c PID_FS_MAGIC = 0x50494446 PIPEFS_MAGIC = 0x50495045 PPPIOCGNPMODE = 0xc008744c @@ -2485,6 +2791,10 @@ const ( PR_FP_EXC_UND = 0x40000 PR_FP_MODE_FR = 0x1 PR_FP_MODE_FRE = 0x2 + PR_FUTEX_HASH = 0x4e + PR_FUTEX_HASH_GET_IMMUTABLE = 0x3 + PR_FUTEX_HASH_GET_SLOTS = 0x2 + PR_FUTEX_HASH_SET_SLOTS = 0x1 PR_GET_AUXV = 0x41555856 PR_GET_CHILD_SUBREAPER = 0x25 PR_GET_DUMPABLE = 0x3 @@ -2644,6 +2954,10 @@ const ( PR_TAGGED_ADDR_ENABLE = 0x1 PR_TASK_PERF_EVENTS_DISABLE = 0x1f PR_TASK_PERF_EVENTS_ENABLE = 0x20 + PR_TIMER_CREATE_RESTORE_IDS = 0x4d + PR_TIMER_CREATE_RESTORE_IDS_GET = 0x2 + PR_TIMER_CREATE_RESTORE_IDS_OFF = 0x0 + PR_TIMER_CREATE_RESTORE_IDS_ON = 0x1 PR_TIMING_STATISTICAL = 0x0 PR_TIMING_TIMESTAMP = 0x1 PR_TSC_ENABLE = 0x1 @@ -2724,6 +3038,7 @@ const ( PTRACE_SETREGSET = 0x4205 PTRACE_SETSIGINFO = 0x4203 PTRACE_SETSIGMASK = 0x420b + PTRACE_SET_SYSCALL_INFO = 0x4212 PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG = 0x4210 PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 @@ -2732,6 +3047,23 @@ const ( PTRACE_SYSCALL_INFO_NONE = 0x0 PTRACE_SYSCALL_INFO_SECCOMP = 0x3 PTRACE_TRACEME = 0x0 + PT_AARCH64_MEMTAG_MTE = 0x70000002 + PT_DYNAMIC = 0x2 + PT_GNU_EH_FRAME = 0x6474e550 + PT_GNU_PROPERTY = 0x6474e553 + PT_GNU_RELRO = 0x6474e552 + PT_GNU_STACK = 0x6474e551 + PT_HIOS = 0x6fffffff + PT_HIPROC = 0x7fffffff + PT_INTERP = 0x3 + PT_LOAD = 0x1 + PT_LOOS = 0x60000000 + PT_LOPROC = 0x70000000 + PT_NOTE = 0x4 + PT_NULL = 0x0 + PT_PHDR = 0x6 + PT_SHLIB = 0x5 + PT_TLS = 0x7 P_ALL = 0x0 P_PGID = 0x2 P_PID = 0x1 @@ -2787,7 +3119,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1e + RTA_MAX = 0x1f RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -2864,10 +3196,12 @@ const ( RTM_DELACTION = 0x31 RTM_DELADDR = 0x15 RTM_DELADDRLABEL = 0x49 + RTM_DELANYCAST = 0x3d RTM_DELCHAIN = 0x65 RTM_DELLINK = 0x11 RTM_DELLINKPROP = 0x6d RTM_DELMDB = 0x55 + RTM_DELMULTICAST = 0x39 RTM_DELNEIGH = 0x1d RTM_DELNETCONF = 0x51 RTM_DELNEXTHOP = 0x69 @@ -2917,11 +3251,13 @@ const ( RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWANYCAST = 0x3c RTM_NEWCACHEREPORT = 0x60 RTM_NEWCHAIN = 0x64 RTM_NEWLINK = 0x10 RTM_NEWLINKPROP = 0x6c RTM_NEWMDB = 0x54 + RTM_NEWMULTICAST = 0x38 RTM_NEWNDUSEROPT = 0x44 RTM_NEWNEIGH = 0x1c RTM_NEWNEIGHTBL = 0x40 @@ -2970,6 +3306,7 @@ const ( RTPROT_NTK = 0xf RTPROT_OPENR = 0x63 RTPROT_OSPF = 0xbc + RTPROT_OVN = 0x54 RTPROT_RA = 0x9 RTPROT_REDIRECT = 0x1 RTPROT_RIP = 0xbd @@ -2987,11 +3324,12 @@ const ( RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 RWF_ATOMIC = 0x40 + RWF_DONTCACHE = 0x80 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x7f + RWF_SUPPORTED = 0xff RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 @@ -3059,6 +3397,47 @@ const ( SEEK_MAX = 0x4 SEEK_SET = 0x0 SELINUX_MAGIC = 0xf97cff8c + SHF_ALLOC = 0x2 + SHF_EXCLUDE = 0x8000000 + SHF_EXECINSTR = 0x4 + SHF_GROUP = 0x200 + SHF_INFO_LINK = 0x40 + SHF_LINK_ORDER = 0x80 + SHF_MASKOS = 0xff00000 + SHF_MASKPROC = 0xf0000000 + SHF_MERGE = 0x10 + SHF_ORDERED = 0x4000000 + SHF_OS_NONCONFORMING = 0x100 + SHF_RELA_LIVEPATCH = 0x100000 + SHF_RO_AFTER_INIT = 0x200000 + SHF_STRINGS = 0x20 + SHF_TLS = 0x400 + SHF_WRITE = 0x1 + SHN_ABS = 0xfff1 + SHN_COMMON = 0xfff2 + SHN_HIPROC = 0xff1f + SHN_HIRESERVE = 0xffff + SHN_LIVEPATCH = 0xff20 + SHN_LOPROC = 0xff00 + SHN_LORESERVE = 0xff00 + SHN_UNDEF = 0x0 + SHT_DYNAMIC = 0x6 + SHT_DYNSYM = 0xb + SHT_HASH = 0x5 + SHT_HIPROC = 0x7fffffff + SHT_HIUSER = 0xffffffff + SHT_LOPROC = 0x70000000 + SHT_LOUSER = 0x80000000 + SHT_NOBITS = 0x8 + SHT_NOTE = 0x7 + SHT_NULL = 0x0 + SHT_NUM = 0xc + SHT_PROGBITS = 0x1 + SHT_REL = 0x9 + SHT_RELA = 0x4 + SHT_SHLIB = 0xa + SHT_STRTAB = 0x3 + SHT_SYMTAB = 0x2 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -3271,6 +3650,7 @@ const ( STATX_BTIME = 0x800 STATX_CTIME = 0x80 STATX_DIOALIGN = 0x2000 + STATX_DIO_READ_ALIGN = 0x20000 STATX_GID = 0x10 STATX_INO = 0x100 STATX_MNT_ID = 0x1000 @@ -3284,6 +3664,16 @@ const ( STATX_UID = 0x8 STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 + STB_GLOBAL = 0x1 + STB_LOCAL = 0x0 + STB_WEAK = 0x2 + STT_COMMON = 0x5 + STT_FILE = 0x4 + STT_FUNC = 0x2 + STT_NOTYPE = 0x0 + STT_OBJECT = 0x1 + STT_SECTION = 0x3 + STT_TLS = 0x6 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 SYNC_FILE_RANGE_WRITE = 0x2 @@ -3322,7 +3712,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0xe + TASKSTATS_VERSION = 0x10 TCIFLUSH = 0x0 TCIOFF = 0x2 TCIOFLUSH = 0x2 @@ -3392,8 +3782,6 @@ const ( TCP_TX_DELAY = 0x25 TCP_ULP = 0x1f TCP_USER_TIMEOUT = 0x12 - TCP_V4_FLOW = 0x1 - TCP_V6_FLOW = 0x5 TCP_WINDOW_CLAMP = 0xa TCP_ZEROCOPY_RECEIVE = 0x23 TFD_TIMER_ABSTIME = 0x1 @@ -3503,6 +3891,7 @@ const ( TP_STATUS_WRONG_FORMAT = 0x4 TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 + UBI_IOCECNFO = 0xc01c6f06 UDF_SUPER_MAGIC = 0x15013346 UDP_CORK = 0x1 UDP_ENCAP = 0x64 @@ -3515,14 +3904,14 @@ const ( UDP_NO_CHECK6_RX = 0x66 UDP_NO_CHECK6_TX = 0x65 UDP_SEGMENT = 0x67 - UDP_V4_FLOW = 0x2 - UDP_V6_FLOW = 0x6 UMOUNT_NOFOLLOW = 0x8 USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff UTIME_OMIT = 0x3ffffffe V9FS_MAGIC = 0x1021997 VERASE = 0x2 + VER_FLG_BASE = 0x1 + VER_FLG_WEAK = 0x2 VINTR = 0x0 VKILL = 0x3 VLNEXT = 0xf @@ -3559,7 +3948,7 @@ const ( WDIOS_TEMPPANIC = 0x4 WDIOS_UNKNOWN = -0x1 WEXITED = 0x4 - WGALLOWEDIP_A_MAX = 0x3 + WGALLOWEDIP_A_MAX = 0x4 WGDEVICE_A_MAX = 0x8 WGPEER_A_MAX = 0xa WG_CMD_MAX = 0x1 @@ -3673,6 +4062,7 @@ const ( XDP_SHARED_UMEM = 0x1 XDP_STATISTICS = 0x7 XDP_TXMD_FLAGS_CHECKSUM = 0x2 + XDP_TXMD_FLAGS_LAUNCH_TIME = 0x4 XDP_TXMD_FLAGS_TIMESTAMP = 0x1 XDP_TX_METADATA = 0x2 XDP_TX_RING = 0x3 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 75207613..1c37f9fb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -360,6 +361,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -372,6 +374,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index c68acda5..6f54d34a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -361,6 +362,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -373,6 +375,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index a8c607ab..783ec5c1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -366,6 +367,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -378,6 +380,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 18563dd8..ca83d3ba 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 22912cda..607e611c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -353,6 +354,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -365,6 +367,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 29344eb3..b9cb5bd3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 20d51fb9..65b078a6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 321b6090..5298a303 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 9bacdf1e..7bc557c8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -359,6 +360,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 @@ -371,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c2242726..152399bb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -414,6 +415,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -426,6 +428,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 6270c8ee..1a1ce240 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -418,6 +419,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -430,6 +432,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 9966c194..4231a1fb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -68,6 +68,7 @@ const ( CS8 = 0x300 CSIZE = 0x300 CSTOPB = 0x400 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x40 @@ -418,6 +419,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 @@ -430,6 +432,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 848e5fcc..21c0e952 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -350,6 +351,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -362,6 +364,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 669b2adb..f00d1cd7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -68,6 +68,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0xfd12 ECCGETLAYOUT = 0x81484d11 ECCGETSTATS = 0x80104d12 ECHOCTL = 0x200 @@ -422,6 +423,7 @@ const ( SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 SO_PASSPIDFD = 0x4c + SO_PASSRIGHTS = 0x53 SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 @@ -434,6 +436,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 4834e575..bc8d539e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -71,6 +71,7 @@ const ( CS8 = 0x30 CSIZE = 0x30 CSTOPB = 0x40 + DM_MPATH_PROBE_PATHS = 0x2000fd12 ECCGETLAYOUT = 0x41484d11 ECCGETSTATS = 0x40104d12 ECHOCTL = 0x200 @@ -461,6 +462,7 @@ const ( SO_OOBINLINE = 0x100 SO_PASSCRED = 0x2 SO_PASSPIDFD = 0x55 + SO_PASSRIGHTS = 0x5c SO_PASSSEC = 0x1f SO_PEEK_OFF = 0x26 SO_PEERCRED = 0x40 @@ -473,6 +475,7 @@ const ( SO_RCVBUFFORCE = 0x100b SO_RCVLOWAT = 0x800 SO_RCVMARK = 0x54 + SO_RCVPRIORITY = 0x5b SO_RCVTIMEO = 0x2000 SO_RCVTIMEO_NEW = 0x44 SO_RCVTIMEO_OLD = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 5cc1e8eb..8935d10a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -2238,3 +2238,13 @@ func Mseal(b []byte, flags uint) (err error) { } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func setMemPolicy(mode int, mask *CPUSet, size int) (err error) { + _, _, e1 := Syscall(SYS_SET_MEMPOLICY, uintptr(mode), uintptr(unsafe.Pointer(mask)), uintptr(size)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index c6545413..b4609c20 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -72,7 +72,7 @@ import ( //go:cgo_import_dynamic libc_kill kill "libc.so" //go:cgo_import_dynamic libc_lchown lchown "libc.so" //go:cgo_import_dynamic libc_link link "libc.so" -//go:cgo_import_dynamic libc___xnet_llisten __xnet_llisten "libsocket.so" +//go:cgo_import_dynamic libc___xnet_listen __xnet_listen "libsocket.so" //go:cgo_import_dynamic libc_lstat lstat "libc.so" //go:cgo_import_dynamic libc_madvise madvise "libc.so" //go:cgo_import_dynamic libc_mkdir mkdir "libc.so" @@ -221,7 +221,7 @@ import ( //go:linkname procKill libc_kill //go:linkname procLchown libc_lchown //go:linkname procLink libc_link -//go:linkname proc__xnet_llisten libc___xnet_llisten +//go:linkname proc__xnet_listen libc___xnet_listen //go:linkname procLstat libc_lstat //go:linkname procMadvise libc_madvise //go:linkname procMkdir libc_mkdir @@ -371,7 +371,7 @@ var ( procKill, procLchown, procLink, - proc__xnet_llisten, + proc__xnet_listen, procLstat, procMadvise, procMkdir, @@ -1178,7 +1178,7 @@ func Link(path string, link string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func Listen(s int, backlog int) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_llisten)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_listen)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) if e1 != 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index c79aaff3..aca56ee4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -462,4 +462,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 5eb45069..2ea1ef58 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -385,4 +385,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 05e50297..d22c8af3 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -426,4 +426,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 38c53ec5..5ee264ae 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -329,4 +329,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 31d2e71a..f9f03ebf 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -325,4 +325,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index f4184a33..87c2118e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -446,4 +446,5 @@ const ( SYS_GETXATTRAT = 4464 SYS_LISTXATTRAT = 4465 SYS_REMOVEXATTRAT = 4466 + SYS_OPEN_TREE_ATTR = 4467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 05b99622..391ad102 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -376,4 +376,5 @@ const ( SYS_GETXATTRAT = 5464 SYS_LISTXATTRAT = 5465 SYS_REMOVEXATTRAT = 5466 + SYS_OPEN_TREE_ATTR = 5467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 43a256e9..56561577 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -376,4 +376,5 @@ const ( SYS_GETXATTRAT = 5464 SYS_LISTXATTRAT = 5465 SYS_REMOVEXATTRAT = 5466 + SYS_OPEN_TREE_ATTR = 5467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index eea5ddfc..0482b52e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -446,4 +446,5 @@ const ( SYS_GETXATTRAT = 4464 SYS_LISTXATTRAT = 4465 SYS_REMOVEXATTRAT = 4466 + SYS_OPEN_TREE_ATTR = 4467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index 0d777bfb..71806f08 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -453,4 +453,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index b4463650..e35a7105 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -425,4 +425,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 0c7d21c1..2aea4767 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -425,4 +425,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 84053916..6c9bb4e5 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -330,4 +330,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index fcf1b790..680bc991 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -391,4 +391,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 52d15b5f..620f2710 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -404,4 +404,5 @@ const ( SYS_GETXATTRAT = 464 SYS_LISTXATTRAT = 465 SYS_REMOVEXATTRAT = 466 + SYS_OPEN_TREE_ATTR = 467 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index a46abe64..c1a46701 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -114,8 +114,10 @@ type Statx_t struct { Atomic_write_unit_min uint32 Atomic_write_unit_max uint32 Atomic_write_segments_max uint32 + Dio_read_offset_align uint32 + Atomic_write_unit_max_opt uint32 _ [1]uint32 - _ [9]uint64 + _ [8]uint64 } type Fsid struct { @@ -199,7 +201,8 @@ type FscryptAddKeyArg struct { Key_spec FscryptKeySpecifier Raw_size uint32 Key_id uint32 - _ [8]uint32 + Flags uint32 + _ [7]uint32 } type FscryptRemoveKeyArg struct { @@ -629,6 +632,8 @@ const ( IFA_FLAGS = 0x8 IFA_RT_PRIORITY = 0x9 IFA_TARGET_NETNSID = 0xa + IFAL_LABEL = 0x2 + IFAL_ADDRESS = 0x1 RT_SCOPE_UNIVERSE = 0x0 RT_SCOPE_SITE = 0xc8 RT_SCOPE_LINK = 0xfd @@ -686,6 +691,7 @@ const ( SizeofRtAttr = 0x4 SizeofIfInfomsg = 0x10 SizeofIfAddrmsg = 0x8 + SizeofIfAddrlblmsg = 0xc SizeofIfaCacheinfo = 0x10 SizeofRtMsg = 0xc SizeofRtNexthop = 0x8 @@ -737,6 +743,15 @@ type IfAddrmsg struct { Index uint32 } +type IfAddrlblmsg struct { + Family uint8 + _ uint8 + Prefixlen uint8 + Flags uint8 + Index uint32 + Seq uint32 +} + type IfaCacheinfo struct { Prefered uint32 Valid uint32 @@ -2226,8 +2241,11 @@ const ( NFT_PAYLOAD_LL_HEADER = 0x0 NFT_PAYLOAD_NETWORK_HEADER = 0x1 NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_INNER_HEADER = 0x3 + NFT_PAYLOAD_TUN_HEADER = 0x4 NFT_PAYLOAD_CSUM_NONE = 0x0 NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_CSUM_SCTP = 0x2 NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 NFTA_PAYLOAD_UNSPEC = 0x0 NFTA_PAYLOAD_DREG = 0x1 @@ -2314,6 +2332,11 @@ const ( NFT_CT_AVGPKT = 0x10 NFT_CT_ZONE = 0x11 NFT_CT_EVENTMASK = 0x12 + NFT_CT_SRC_IP = 0x13 + NFT_CT_DST_IP = 0x14 + NFT_CT_SRC_IP6 = 0x15 + NFT_CT_DST_IP6 = 0x16 + NFT_CT_ID = 0x17 NFTA_CT_UNSPEC = 0x0 NFTA_CT_DREG = 0x1 NFTA_CT_KEY = 0x2 @@ -2594,8 +2617,8 @@ const ( SOF_TIMESTAMPING_BIND_PHC = 0x8000 SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 - SOF_TIMESTAMPING_LAST = 0x20000 - SOF_TIMESTAMPING_MASK = 0x3ffff + SOF_TIMESTAMPING_LAST = 0x40000 + SOF_TIMESTAMPING_MASK = 0x7ffff SCM_TSTAMP_SND = 0x0 SCM_TSTAMP_SCHED = 0x1 @@ -3041,6 +3064,23 @@ const ( ) const ( + TCA_UNSPEC = 0x0 + TCA_KIND = 0x1 + TCA_OPTIONS = 0x2 + TCA_STATS = 0x3 + TCA_XSTATS = 0x4 + TCA_RATE = 0x5 + TCA_FCNT = 0x6 + TCA_STATS2 = 0x7 + TCA_STAB = 0x8 + TCA_PAD = 0x9 + TCA_DUMP_INVISIBLE = 0xa + TCA_CHAIN = 0xb + TCA_HW_OFFLOAD = 0xc + TCA_INGRESS_BLOCK = 0xd + TCA_EGRESS_BLOCK = 0xe + TCA_DUMP_FLAGS = 0xf + TCA_EXT_WARN_MSG = 0x10 RTNLGRP_NONE = 0x0 RTNLGRP_LINK = 0x1 RTNLGRP_NOTIFY = 0x2 @@ -3075,6 +3115,18 @@ const ( RTNLGRP_IPV6_MROUTE_R = 0x1f RTNLGRP_NEXTHOP = 0x20 RTNLGRP_BRVLAN = 0x21 + RTNLGRP_MCTP_IFADDR = 0x22 + RTNLGRP_TUNNEL = 0x23 + RTNLGRP_STATS = 0x24 + RTNLGRP_IPV4_MCADDR = 0x25 + RTNLGRP_IPV6_MCADDR = 0x26 + RTNLGRP_IPV6_ACADDR = 0x27 + TCA_ROOT_UNSPEC = 0x0 + TCA_ROOT_TAB = 0x1 + TCA_ROOT_FLAGS = 0x2 + TCA_ROOT_COUNT = 0x3 + TCA_ROOT_TIME_DELTA = 0x4 + TCA_ROOT_EXT_WARN_MSG = 0x5 ) type CapUserHeader struct { @@ -3538,6 +3590,8 @@ type Nhmsg struct { Flags uint32 } +const SizeofNhmsg = 0x8 + type NexthopGrp struct { Id uint32 Weight uint8 @@ -3545,6 +3599,8 @@ type NexthopGrp struct { Resvd2 uint16 } +const SizeofNexthopGrp = 0x8 + const ( NHA_UNSPEC = 0x0 NHA_ID = 0x1 @@ -3802,7 +3858,16 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2d + ETHTOOL_MSG_PLCA_GET_CFG = 0x27 + ETHTOOL_MSG_PLCA_SET_CFG = 0x28 + ETHTOOL_MSG_PLCA_GET_STATUS = 0x29 + ETHTOOL_MSG_MM_GET = 0x2a + ETHTOOL_MSG_MM_SET = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_ACT = 0x2c + ETHTOOL_MSG_PHY_GET = 0x2d + ETHTOOL_MSG_TSCONFIG_GET = 0x2e + ETHTOOL_MSG_TSCONFIG_SET = 0x2f + ETHTOOL_MSG_USER_MAX = 0x2f ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3842,7 +3907,17 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2e + ETHTOOL_MSG_PLCA_GET_CFG_REPLY = 0x27 + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY = 0x28 + ETHTOOL_MSG_PLCA_NTF = 0x29 + ETHTOOL_MSG_MM_GET_REPLY = 0x2a + ETHTOOL_MSG_MM_NTF = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_NTF = 0x2c + ETHTOOL_MSG_PHY_GET_REPLY = 0x2d + ETHTOOL_MSG_PHY_NTF = 0x2e + ETHTOOL_MSG_TSCONFIG_GET_REPLY = 0x2f + ETHTOOL_MSG_TSCONFIG_SET_REPLY = 0x30 + ETHTOOL_MSG_KERNEL_MAX = 0x30 ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3949,7 +4024,12 @@ const ( ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb ETHTOOL_A_RINGS_CQE_SIZE = 0xc ETHTOOL_A_RINGS_TX_PUSH = 0xd - ETHTOOL_A_RINGS_MAX = 0x10 + ETHTOOL_A_RINGS_RX_PUSH = 0xe + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN = 0xf + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX = 0x10 + ETHTOOL_A_RINGS_HDS_THRESH = 0x11 + ETHTOOL_A_RINGS_HDS_THRESH_MAX = 0x12 + ETHTOOL_A_RINGS_MAX = 0x12 ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ETHTOOL_A_CHANNELS_HEADER = 0x1 ETHTOOL_A_CHANNELS_RX_MAX = 0x2 @@ -4015,7 +4095,9 @@ const ( ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 - ETHTOOL_A_TSINFO_MAX = 0x6 + ETHTOOL_A_TSINFO_STATS = 0x6 + ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER = 0x7 + ETHTOOL_A_TSINFO_MAX = 0x9 ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ETHTOOL_A_CABLE_TEST_MAX = 0x1 @@ -4101,6 +4183,19 @@ const ( ETHTOOL_A_TUNNEL_INFO_MAX = 0x2 ) +const ( + TCP_V4_FLOW = 0x1 + UDP_V4_FLOW = 0x2 + TCP_V6_FLOW = 0x5 + UDP_V6_FLOW = 0x6 + ESP_V4_FLOW = 0xa + ESP_V6_FLOW = 0xc + IP_USER_FLOW = 0xd + IPV6_USER_FLOW = 0xe + IPV6_FLOW = 0x11 + ETHER_FLOW = 0x12 +) + const SPEED_UNKNOWN = -0x1 type EthtoolDrvinfo struct { @@ -4613,6 +4708,7 @@ const ( NL80211_ATTR_AKM_SUITES = 0x4c NL80211_ATTR_AP_ISOLATE = 0x60 NL80211_ATTR_AP_SETTINGS_FLAGS = 0x135 + NL80211_ATTR_ASSOC_SPP_AMSDU = 0x14a NL80211_ATTR_AUTH_DATA = 0x9c NL80211_ATTR_AUTH_TYPE = 0x35 NL80211_ATTR_BANDS = 0xef @@ -4623,6 +4719,7 @@ const ( NL80211_ATTR_BSS_BASIC_RATES = 0x24 NL80211_ATTR_BSS = 0x2f NL80211_ATTR_BSS_CTS_PROT = 0x1c + NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA = 0x147 NL80211_ATTR_BSS_HT_OPMODE = 0x6d NL80211_ATTR_BSSID = 0xf5 NL80211_ATTR_BSS_SELECT = 0xe3 @@ -4682,6 +4779,7 @@ const ( NL80211_ATTR_DTIM_PERIOD = 0xd NL80211_ATTR_DURATION = 0x57 NL80211_ATTR_EHT_CAPABILITY = 0x136 + NL80211_ATTR_EMA_RNR_ELEMS = 0x145 NL80211_ATTR_EML_CAPABILITY = 0x13d NL80211_ATTR_EXT_CAPA = 0xa9 NL80211_ATTR_EXT_CAPA_MASK = 0xaa @@ -4717,6 +4815,7 @@ const ( NL80211_ATTR_HIDDEN_SSID = 0x7e NL80211_ATTR_HT_CAPABILITY = 0x1f NL80211_ATTR_HT_CAPABILITY_MASK = 0x94 + NL80211_ATTR_HW_TIMESTAMP_ENABLED = 0x144 NL80211_ATTR_IE_ASSOC_RESP = 0x80 NL80211_ATTR_IE = 0x2a NL80211_ATTR_IE_PROBE_RESP = 0x7f @@ -4747,9 +4846,10 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14d + NL80211_ATTR_MAX = 0x151 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce + NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS = 0x143 NL80211_ATTR_MAX_MATCH_SETS = 0x85 NL80211_ATTR_MAX_NUM_AKM_SUITES = 0x13c NL80211_ATTR_MAX_NUM_PMKIDS = 0x56 @@ -4774,9 +4874,12 @@ const ( NL80211_ATTR_MGMT_SUBTYPE = 0x29 NL80211_ATTR_MLD_ADDR = 0x13a NL80211_ATTR_MLD_CAPA_AND_OPS = 0x13e + NL80211_ATTR_MLO_LINK_DISABLED = 0x146 NL80211_ATTR_MLO_LINK_ID = 0x139 NL80211_ATTR_MLO_LINKS = 0x138 NL80211_ATTR_MLO_SUPPORT = 0x13b + NL80211_ATTR_MLO_TTLM_DLINK = 0x148 + NL80211_ATTR_MLO_TTLM_ULINK = 0x149 NL80211_ATTR_MNTR_FLAGS = 0x17 NL80211_ATTR_MPATH_INFO = 0x1b NL80211_ATTR_MPATH_NEXT_HOP = 0x1a @@ -4809,12 +4912,14 @@ const ( NL80211_ATTR_PORT_AUTHORIZED = 0x103 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN = 0x5 NL80211_ATTR_POWER_RULE_MAX_EIRP = 0x6 + NL80211_ATTR_POWER_RULE_PSD = 0x8 NL80211_ATTR_PREV_BSSID = 0x4f NL80211_ATTR_PRIVACY = 0x46 NL80211_ATTR_PROBE_RESP = 0x91 NL80211_ATTR_PROBE_RESP_OFFLOAD = 0x90 NL80211_ATTR_PROTOCOL_FEATURES = 0xad NL80211_ATTR_PS_STATE = 0x5d + NL80211_ATTR_PUNCT_BITMAP = 0x142 NL80211_ATTR_QOS_MAP = 0xc7 NL80211_ATTR_RADAR_BACKGROUND = 0x134 NL80211_ATTR_RADAR_EVENT = 0xa8 @@ -4943,7 +5048,9 @@ const ( NL80211_ATTR_WIPHY_FREQ = 0x26 NL80211_ATTR_WIPHY_FREQ_HINT = 0xc9 NL80211_ATTR_WIPHY_FREQ_OFFSET = 0x122 + NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS = 0x14c NL80211_ATTR_WIPHY_NAME = 0x2 + NL80211_ATTR_WIPHY_RADIOS = 0x14b NL80211_ATTR_WIPHY_RETRY_LONG = 0x3e NL80211_ATTR_WIPHY_RETRY_SHORT = 0x3d NL80211_ATTR_WIPHY_RTS_THRESHOLD = 0x40 @@ -4978,6 +5085,8 @@ const ( NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 NL80211_BAND_ATTR_MAX = 0xd NL80211_BAND_ATTR_RATES = 0x2 + NL80211_BAND_ATTR_S1G_CAPA = 0xd + NL80211_BAND_ATTR_S1G_MCS_NSS_SET = 0xc NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC = 0x8 @@ -5001,6 +5110,10 @@ const ( NL80211_BSS_BEACON_INTERVAL = 0x4 NL80211_BSS_BEACON_TSF = 0xd NL80211_BSS_BSSID = 0x1 + NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 0x2 + NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 0x1 + NL80211_BSS_CANNOT_USE_REASONS = 0x18 + NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH = 0x2 NL80211_BSS_CAPABILITY = 0x5 NL80211_BSS_CHAIN_SIGNAL = 0x13 NL80211_BSS_CHAN_WIDTH_10 = 0x1 @@ -5032,6 +5145,9 @@ const ( NL80211_BSS_STATUS = 0x9 NL80211_BSS_STATUS_IBSS_JOINED = 0x2 NL80211_BSS_TSF = 0x3 + NL80211_BSS_USE_FOR = 0x17 + NL80211_BSS_USE_FOR_MLD_LINK = 0x2 + NL80211_BSS_USE_FOR_NORMAL = 0x1 NL80211_CHAN_HT20 = 0x1 NL80211_CHAN_HT40MINUS = 0x2 NL80211_CHAN_HT40PLUS = 0x3 @@ -5117,7 +5233,8 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x9b + NL80211_CMD_LINKS_REMOVED = 0x9a + NL80211_CMD_MAX = 0x9d NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 @@ -5161,6 +5278,7 @@ const ( NL80211_CMD_SET_COALESCE = 0x65 NL80211_CMD_SET_CQM = 0x3f NL80211_CMD_SET_FILS_AAD = 0x92 + NL80211_CMD_SET_HW_TIMESTAMP = 0x99 NL80211_CMD_SET_INTERFACE = 0x6 NL80211_CMD_SET_KEY = 0xa NL80211_CMD_SET_MAC_ACL = 0x5d @@ -5180,6 +5298,7 @@ const ( NL80211_CMD_SET_SAR_SPECS = 0x8c NL80211_CMD_SET_STATION = 0x12 NL80211_CMD_SET_TID_CONFIG = 0x89 + NL80211_CMD_SET_TID_TO_LINK_MAPPING = 0x9b NL80211_CMD_SET_TX_BITRATE_MASK = 0x39 NL80211_CMD_SET_WDS_PEER = 0x42 NL80211_CMD_SET_WIPHY = 0x2 @@ -5247,6 +5366,7 @@ const ( NL80211_EXT_FEATURE_AIRTIME_FAIRNESS = 0x21 NL80211_EXT_FEATURE_AP_PMKSA_CACHING = 0x22 NL80211_EXT_FEATURE_AQL = 0x28 + NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA = 0x40 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT = 0x2e NL80211_EXT_FEATURE_BEACON_PROTECTION = 0x29 NL80211_EXT_FEATURE_BEACON_RATE_HE = 0x36 @@ -5262,6 +5382,7 @@ const ( NL80211_EXT_FEATURE_CQM_RSSI_LIST = 0xd NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = 0x1b NL80211_EXT_FEATURE_DEL_IBSS_STA = 0x2c + NL80211_EXT_FEATURE_DFS_CONCURRENT = 0x43 NL80211_EXT_FEATURE_DFS_OFFLOAD = 0x19 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 0x20 NL80211_EXT_FEATURE_EXT_KEY_ID = 0x24 @@ -5281,9 +5402,12 @@ const ( NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x14 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE = 0x13 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION = 0x31 + NL80211_EXT_FEATURE_OWE_OFFLOAD_AP = 0x42 + NL80211_EXT_FEATURE_OWE_OFFLOAD = 0x41 NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE = 0x3d NL80211_EXT_FEATURE_PROTECTED_TWT = 0x2b NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE = 0x39 + NL80211_EXT_FEATURE_PUNCT = 0x3e NL80211_EXT_FEATURE_RADAR_BACKGROUND = 0x3c NL80211_EXT_FEATURE_RRM = 0x1 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP = 0x33 @@ -5295,8 +5419,10 @@ const ( NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD = 0x23 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI = 0xc NL80211_EXT_FEATURE_SECURE_LTF = 0x37 + NL80211_EXT_FEATURE_SECURE_NAN = 0x3f NL80211_EXT_FEATURE_SECURE_RTT = 0x38 NL80211_EXT_FEATURE_SET_SCAN_DWELL = 0x5 + NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT = 0x44 NL80211_EXT_FEATURE_STA_TX_PWR = 0x25 NL80211_EXT_FEATURE_TXQS = 0x1c NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP = 0x35 @@ -5343,7 +5469,10 @@ const ( NL80211_FREQUENCY_ATTR_2MHZ = 0x16 NL80211_FREQUENCY_ATTR_4MHZ = 0x17 NL80211_FREQUENCY_ATTR_8MHZ = 0x18 + NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP = 0x21 + NL80211_FREQUENCY_ATTR_CAN_MONITOR = 0x20 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME = 0xd + NL80211_FREQUENCY_ATTR_DFS_CONCURRENT = 0x1d NL80211_FREQUENCY_ATTR_DFS_STATE = 0x7 NL80211_FREQUENCY_ATTR_DFS_TIME = 0x8 NL80211_FREQUENCY_ATTR_DISABLED = 0x2 @@ -5351,12 +5480,14 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x21 + NL80211_FREQUENCY_ATTR_MAX = 0x22 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc NL80211_FREQUENCY_ATTR_NO_20MHZ = 0x10 NL80211_FREQUENCY_ATTR_NO_320MHZ = 0x1a + NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_NO_80MHZ = 0xb NL80211_FREQUENCY_ATTR_NO_EHT = 0x1b NL80211_FREQUENCY_ATTR_NO_HE = 0x13 @@ -5364,8 +5495,11 @@ const ( NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 0xa NL80211_FREQUENCY_ATTR_NO_IBSS = 0x3 NL80211_FREQUENCY_ATTR_NO_IR = 0x3 + NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_OFFSET = 0x14 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN = 0x3 + NL80211_FREQUENCY_ATTR_PSD = 0x1c NL80211_FREQUENCY_ATTR_RADAR = 0x5 NL80211_FREQUENCY_ATTR_WMM = 0x12 NL80211_FTM_RESP_ATTR_CIVICLOC = 0x3 @@ -5430,6 +5564,7 @@ const ( NL80211_IFTYPE_STATION = 0x2 NL80211_IFTYPE_UNSPECIFIED = 0x0 NL80211_IFTYPE_WDS = 0x5 + NL80211_KCK_EXT_LEN_32 = 0x20 NL80211_KCK_EXT_LEN = 0x18 NL80211_KCK_LEN = 0x10 NL80211_KEK_EXT_LEN = 0x20 @@ -5458,9 +5593,10 @@ const ( NL80211_MAX_SUPP_HT_RATES = 0x4d NL80211_MAX_SUPP_RATES = 0x20 NL80211_MAX_SUPP_REG_RULES = 0x80 + NL80211_MAX_SUPP_SELECTORS = 0x80 NL80211_MBSSID_CONFIG_ATTR_EMA = 0x5 NL80211_MBSSID_CONFIG_ATTR_INDEX = 0x3 - NL80211_MBSSID_CONFIG_ATTR_MAX = 0x5 + NL80211_MBSSID_CONFIG_ATTR_MAX = 0x6 NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY = 0x2 NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES = 0x1 NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX = 0x4 @@ -5703,11 +5839,16 @@ const ( NL80211_RADAR_PRE_CAC_EXPIRED = 0x4 NL80211_RATE_INFO_10_MHZ_WIDTH = 0xb NL80211_RATE_INFO_160_MHZ_WIDTH = 0xa + NL80211_RATE_INFO_16_MHZ_WIDTH = 0x1d + NL80211_RATE_INFO_1_MHZ_WIDTH = 0x19 + NL80211_RATE_INFO_2_MHZ_WIDTH = 0x1a NL80211_RATE_INFO_320_MHZ_WIDTH = 0x12 NL80211_RATE_INFO_40_MHZ_WIDTH = 0x3 + NL80211_RATE_INFO_4_MHZ_WIDTH = 0x1b NL80211_RATE_INFO_5_MHZ_WIDTH = 0xc NL80211_RATE_INFO_80_MHZ_WIDTH = 0x8 NL80211_RATE_INFO_80P80_MHZ_WIDTH = 0x9 + NL80211_RATE_INFO_8_MHZ_WIDTH = 0x1c NL80211_RATE_INFO_BITRATE32 = 0x5 NL80211_RATE_INFO_BITRATE = 0x1 NL80211_RATE_INFO_EHT_GI_0_8 = 0x0 @@ -5753,6 +5894,8 @@ const ( NL80211_RATE_INFO_HE_RU_ALLOC = 0x11 NL80211_RATE_INFO_MAX = 0x1d NL80211_RATE_INFO_MCS = 0x2 + NL80211_RATE_INFO_S1G_MCS = 0x17 + NL80211_RATE_INFO_S1G_NSS = 0x18 NL80211_RATE_INFO_SHORT_GI = 0x4 NL80211_RATE_INFO_VHT_MCS = 0x6 NL80211_RATE_INFO_VHT_NSS = 0x7 @@ -5770,14 +5913,19 @@ const ( NL80211_REKEY_DATA_KEK = 0x1 NL80211_REKEY_DATA_REPLAY_CTR = 0x3 NL80211_REPLAY_CTR_LEN = 0x8 + NL80211_RRF_ALLOW_6GHZ_VLP_AP = 0x1000000 NL80211_RRF_AUTO_BW = 0x800 NL80211_RRF_DFS = 0x10 + NL80211_RRF_DFS_CONCURRENT = 0x200000 NL80211_RRF_GO_CONCURRENT = 0x1000 NL80211_RRF_IR_CONCURRENT = 0x1000 NL80211_RRF_NO_160MHZ = 0x10000 NL80211_RRF_NO_320MHZ = 0x40000 + NL80211_RRF_NO_6GHZ_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_6GHZ_VLP_CLIENT = 0x400000 NL80211_RRF_NO_80MHZ = 0x8000 NL80211_RRF_NO_CCK = 0x2 + NL80211_RRF_NO_EHT = 0x80000 NL80211_RRF_NO_HE = 0x20000 NL80211_RRF_NO_HT40 = 0x6000 NL80211_RRF_NO_HT40MINUS = 0x2000 @@ -5788,7 +5936,10 @@ const ( NL80211_RRF_NO_IR = 0x80 NL80211_RRF_NO_OFDM = 0x1 NL80211_RRF_NO_OUTDOOR = 0x8 + NL80211_RRF_NO_UHB_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_UHB_VLP_CLIENT = 0x400000 NL80211_RRF_PASSIVE_SCAN = 0x80 + NL80211_RRF_PSD = 0x100000 NL80211_RRF_PTMP_ONLY = 0x40 NL80211_RRF_PTP_ONLY = 0x20 NL80211_RXMGMT_FLAG_ANSWERED = 0x1 @@ -5849,6 +6000,7 @@ const ( NL80211_STA_FLAG_MAX_OLD_API = 0x6 NL80211_STA_FLAG_MFP = 0x4 NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2 + NL80211_STA_FLAG_SPP_AMSDU = 0x8 NL80211_STA_FLAG_TDLS_PEER = 0x6 NL80211_STA_FLAG_WME = 0x3 NL80211_STA_INFO_ACK_SIGNAL_AVG = 0x23 @@ -6007,6 +6159,13 @@ const ( NL80211_VHT_CAPABILITY_LEN = 0xc NL80211_VHT_NSS_MAX = 0x8 NL80211_WIPHY_NAME_MAXLEN = 0x40 + NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE = 0x2 + NL80211_WIPHY_RADIO_ATTR_INDEX = 0x1 + NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION = 0x3 + NL80211_WIPHY_RADIO_ATTR_MAX = 0x4 + NL80211_WIPHY_RADIO_FREQ_ATTR_END = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_START = 0x1 NL80211_WMMR_AIFSN = 0x3 NL80211_WMMR_CW_MAX = 0x2 NL80211_WMMR_CW_MIN = 0x1 @@ -6038,6 +6197,7 @@ const ( NL80211_WOWLAN_TRIG_PKT_PATTERN = 0x4 NL80211_WOWLAN_TRIG_RFKILL_RELEASE = 0x9 NL80211_WOWLAN_TRIG_TCP_CONNECTION = 0xe + NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC = 0x14 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 = 0xa NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN = 0xb NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 = 0xc @@ -6176,3 +6336,30 @@ type SockDiagReq struct { } const RTM_NEWNVLAN = 0x70 + +const ( + MPOL_BIND = 0x2 + MPOL_DEFAULT = 0x0 + MPOL_F_ADDR = 0x2 + MPOL_F_MEMS_ALLOWED = 0x4 + MPOL_F_MOF = 0x8 + MPOL_F_MORON = 0x10 + MPOL_F_NODE = 0x1 + MPOL_F_NUMA_BALANCING = 0x2000 + MPOL_F_RELATIVE_NODES = 0x4000 + MPOL_F_SHARED = 0x1 + MPOL_F_STATIC_NODES = 0x8000 + MPOL_INTERLEAVE = 0x3 + MPOL_LOCAL = 0x4 + MPOL_MAX = 0x7 + MPOL_MF_INTERNAL = 0x10 + MPOL_MF_LAZY = 0x8 + MPOL_MF_MOVE_ALL = 0x4 + MPOL_MF_MOVE = 0x2 + MPOL_MF_STRICT = 0x1 + MPOL_MF_VALID = 0x7 + MPOL_MODE_FLAGS = 0xe000 + MPOL_PREFERRED = 0x1 + MPOL_PREFERRED_MANY = 0x5 + MPOL_WEIGHTED_INTERLEAVE = 0x6 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index fd402da4..485f2d3a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -282,7 +282,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -338,6 +338,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index eb7a5e18..ecbd1ad8 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -351,6 +351,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index d78ac108..02f0463a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -91,7 +91,7 @@ type Stat_t struct { Gid uint32 Rdev uint64 _ uint16 - _ [4]byte + _ [6]byte Size int64 Blksize int32 _ [4]byte @@ -273,7 +273,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -329,6 +329,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index cd06d47f..6f4d400d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -330,6 +330,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 2f28fe26..cd532cfa 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -331,6 +331,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 71d6cac2..41336208 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -278,7 +278,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -334,6 +334,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 8596d453..eaa37eb7 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -333,6 +333,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index cd60ea18..98ae6a1e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -333,6 +333,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index b0ae420c..cae19615 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -278,7 +278,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -334,6 +334,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index 83597287..6ce3b4e0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -90,7 +90,7 @@ type Stat_t struct { Gid uint32 Rdev uint64 _ uint16 - _ [4]byte + _ [6]byte Size int64 Blksize int32 _ [4]byte @@ -285,7 +285,7 @@ type Taskstats struct { Ac_exitcode uint32 Ac_flag uint8 Ac_nice uint8 - _ [4]byte + _ [6]byte Cpu_count uint64 Cpu_delay_total uint64 Blkio_count uint64 @@ -341,6 +341,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 69eb6a5c..c7429c6a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -340,6 +340,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 5f583cb6..4bf4baf4 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -340,6 +340,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index ad05b51a..e9709d70 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -358,6 +358,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index cf3ce900..fb44268c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -353,6 +353,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 590b5673..9c38265c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -335,6 +335,22 @@ type Taskstats struct { Wpcopy_delay_total uint64 Irq_count uint64 Irq_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/windows/empty.s b/vendor/golang.org/x/sys/windows/empty.s deleted file mode 100644 index ba64caca..00000000 --- a/vendor/golang.org/x/sys/windows/empty.s +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.12 - -// This file is here to allow bodyless functions with go:linkname for Go 1.11 -// and earlier (see https://golang.org/issue/23311). diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 640f6b15..69439df2 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -321,6 +321,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents +//sys FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot //sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW @@ -890,8 +892,12 @@ const socket_error = uintptr(^uint32(0)) //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx //sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex +//sys GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) = iphlpapi.GetIpForwardEntry2 +//sys GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) = iphlpapi.GetIpForwardTable2 //sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry +//sys FreeMibTable(memory unsafe.Pointer) = iphlpapi.FreeMibTable //sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange +//sys NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyRouteChange2 //sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange //sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 @@ -914,6 +920,17 @@ type RawSockaddrInet6 struct { Scope_id uint32 } +// RawSockaddrInet is a union that contains an IPv4, an IPv6 address, or an address family. See +// https://learn.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet. +// +// A [*RawSockaddrInet] may be converted to a [*RawSockaddrInet4] or [*RawSockaddrInet6] using +// unsafe, depending on the address family. +type RawSockaddrInet struct { + Family uint16 + Port uint16 + Data [6]uint32 +} + type RawSockaddr struct { Family uint16 Data [14]int8 diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 958bcf47..6e4f50eb 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -65,6 +65,22 @@ var signals = [...]string{ 15: "terminated", } +// File flags for [os.OpenFile]. The O_ prefix is used to indicate +// that these flags are specific to the OpenFile function. +const ( + O_FILE_FLAG_OPEN_NO_RECALL = FILE_FLAG_OPEN_NO_RECALL + O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT + O_FILE_FLAG_SESSION_AWARE = FILE_FLAG_SESSION_AWARE + O_FILE_FLAG_POSIX_SEMANTICS = FILE_FLAG_POSIX_SEMANTICS + O_FILE_FLAG_BACKUP_SEMANTICS = FILE_FLAG_BACKUP_SEMANTICS + O_FILE_FLAG_DELETE_ON_CLOSE = FILE_FLAG_DELETE_ON_CLOSE + O_FILE_FLAG_SEQUENTIAL_SCAN = FILE_FLAG_SEQUENTIAL_SCAN + O_FILE_FLAG_RANDOM_ACCESS = FILE_FLAG_RANDOM_ACCESS + O_FILE_FLAG_NO_BUFFERING = FILE_FLAG_NO_BUFFERING + O_FILE_FLAG_OVERLAPPED = FILE_FLAG_OVERLAPPED + O_FILE_FLAG_WRITE_THROUGH = FILE_FLAG_WRITE_THROUGH +) + const ( FILE_READ_DATA = 0x00000001 FILE_READ_ATTRIBUTES = 0x00000080 @@ -1976,6 +1992,12 @@ const ( SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1 ) +// FILE_ZERO_DATA_INFORMATION from winioctl.h +type FileZeroDataInformation struct { + FileOffset int64 + BeyondFinalZero int64 +} + const ( ComputerNameNetBIOS = 0 ComputerNameDnsHostname = 1 @@ -2298,6 +2320,82 @@ type MibIfRow2 struct { OutQLen uint64 } +// IP_ADDRESS_PREFIX stores an IP address prefix. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-ip_address_prefix. +type IpAddressPrefix struct { + Prefix RawSockaddrInet + PrefixLength uint8 +} + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_origin. +const ( + NlroManual = 0 + NlroWellKnown = 1 + NlroDHCP = 2 + NlroRouterAdvertisement = 3 + Nlro6to4 = 4 +) + +// NL_ROUTE_ORIGIN enumeration from nldef.h or +// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_route_protocol. +const ( + MIB_IPPROTO_OTHER = 1 + MIB_IPPROTO_LOCAL = 2 + MIB_IPPROTO_NETMGMT = 3 + MIB_IPPROTO_ICMP = 4 + MIB_IPPROTO_EGP = 5 + MIB_IPPROTO_GGP = 6 + MIB_IPPROTO_HELLO = 7 + MIB_IPPROTO_RIP = 8 + MIB_IPPROTO_IS_IS = 9 + MIB_IPPROTO_ES_IS = 10 + MIB_IPPROTO_CISCO = 11 + MIB_IPPROTO_BBN = 12 + MIB_IPPROTO_OSPF = 13 + MIB_IPPROTO_BGP = 14 + MIB_IPPROTO_IDPR = 15 + MIB_IPPROTO_EIGRP = 16 + MIB_IPPROTO_DVMRP = 17 + MIB_IPPROTO_RPL = 18 + MIB_IPPROTO_DHCP = 19 + MIB_IPPROTO_NT_AUTOSTATIC = 10002 + MIB_IPPROTO_NT_STATIC = 10006 + MIB_IPPROTO_NT_STATIC_NON_DOD = 10007 +) + +// MIB_IPFORWARD_ROW2 stores information about an IP route entry. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_row2. +type MibIpForwardRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + DestinationPrefix IpAddressPrefix + NextHop RawSockaddrInet + SitePrefixLength uint8 + ValidLifetime uint32 + PreferredLifetime uint32 + Metric uint32 + Protocol uint32 + Loopback uint8 + AutoconfigureAddress uint8 + Publish uint8 + Immortal uint8 + Age uint32 + Origin uint32 +} + +// MIB_IPFORWARD_TABLE2 contains a table of IP route entries. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipforward_table2. +type MibIpForwardTable2 struct { + NumEntries uint32 + Table [1]MibIpForwardRow2 +} + +// Rows returns the IP route entries in the table. +func (t *MibIpForwardTable2) Rows() []MibIpForwardRow2 { + return unsafe.Slice(&t.Table[0], t.NumEntries) +} + // MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See // https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. type MibUnicastIpAddressRow struct { diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index a58bc48b..f25b7308 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -182,13 +182,17 @@ var ( procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") + procFreeMibTable = modiphlpapi.NewProc("FreeMibTable") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") + procGetIpForwardEntry2 = modiphlpapi.NewProc("GetIpForwardEntry2") + procGetIpForwardTable2 = modiphlpapi.NewProc("GetIpForwardTable2") procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") + procNotifyRouteChange2 = modiphlpapi.NewProc("NotifyRouteChange2") procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") @@ -238,6 +242,7 @@ var ( procFindResourceW = modkernel32.NewProc("FindResourceW") procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") procFindVolumeMountPointClose = modkernel32.NewProc("FindVolumeMountPointClose") + procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer") procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers") procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile") procFormatMessageW = modkernel32.NewProc("FormatMessageW") @@ -284,6 +289,7 @@ var ( procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") + procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -546,25 +552,25 @@ var ( ) func cm_Get_DevNode_Status(status *uint32, problemNumber *uint32, devInst DEVINST, flags uint32) (ret CONFIGRET) { - r0, _, _ := syscall.Syscall6(procCM_Get_DevNode_Status.Addr(), 4, uintptr(unsafe.Pointer(status)), uintptr(unsafe.Pointer(problemNumber)), uintptr(devInst), uintptr(flags), 0, 0) + r0, _, _ := syscall.SyscallN(procCM_Get_DevNode_Status.Addr(), uintptr(unsafe.Pointer(status)), uintptr(unsafe.Pointer(problemNumber)), uintptr(devInst), uintptr(flags)) ret = CONFIGRET(r0) return } func cm_Get_Device_Interface_List(interfaceClass *GUID, deviceID *uint16, buffer *uint16, bufferLen uint32, flags uint32) (ret CONFIGRET) { - r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_ListW.Addr(), 5, uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(flags), 0) + r0, _, _ := syscall.SyscallN(procCM_Get_Device_Interface_ListW.Addr(), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferLen), uintptr(flags)) ret = CONFIGRET(r0) return } func cm_Get_Device_Interface_List_Size(len *uint32, interfaceClass *GUID, deviceID *uint16, flags uint32) (ret CONFIGRET) { - r0, _, _ := syscall.Syscall6(procCM_Get_Device_Interface_List_SizeW.Addr(), 4, uintptr(unsafe.Pointer(len)), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(flags), 0, 0) + r0, _, _ := syscall.SyscallN(procCM_Get_Device_Interface_List_SizeW.Addr(), uintptr(unsafe.Pointer(len)), uintptr(unsafe.Pointer(interfaceClass)), uintptr(unsafe.Pointer(deviceID)), uintptr(flags)) ret = CONFIGRET(r0) return } func cm_MapCrToWin32Err(configRet CONFIGRET, defaultWin32Error Errno) (ret Errno) { - r0, _, _ := syscall.Syscall(procCM_MapCrToWin32Err.Addr(), 2, uintptr(configRet), uintptr(defaultWin32Error), 0) + r0, _, _ := syscall.SyscallN(procCM_MapCrToWin32Err.Addr(), uintptr(configRet), uintptr(defaultWin32Error)) ret = Errno(r0) return } @@ -574,7 +580,7 @@ func AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, if resetToDefault { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procAdjustTokenGroups.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + r1, _, e1 := syscall.SyscallN(procAdjustTokenGroups.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) if r1 == 0 { err = errnoErr(e1) } @@ -586,7 +592,7 @@ func AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tok if disableAllPrivileges { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + r1, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) if r1 == 0 { err = errnoErr(e1) } @@ -594,7 +600,7 @@ func AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tok } func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0) + r1, _, e1 := syscall.SyscallN(procAllocateAndInitializeSid.Addr(), uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid))) if r1 == 0 { err = errnoErr(e1) } @@ -602,7 +608,7 @@ func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, s } func buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procBuildSecurityDescriptorW.Addr(), 9, uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSecurityDescriptor)), uintptr(unsafe.Pointer(sizeNewSecurityDescriptor)), uintptr(unsafe.Pointer(newSecurityDescriptor))) + r0, _, _ := syscall.SyscallN(procBuildSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(countAccessEntries), uintptr(unsafe.Pointer(accessEntries)), uintptr(countAuditEntries), uintptr(unsafe.Pointer(auditEntries)), uintptr(unsafe.Pointer(oldSecurityDescriptor)), uintptr(unsafe.Pointer(sizeNewSecurityDescriptor)), uintptr(unsafe.Pointer(newSecurityDescriptor))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -610,7 +616,7 @@ func buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries } func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) + r1, _, e1 := syscall.SyscallN(procChangeServiceConfig2W.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -618,7 +624,7 @@ func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err err } func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0) + r1, _, e1 := syscall.SyscallN(procChangeServiceConfigW.Addr(), uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName))) if r1 == 0 { err = errnoErr(e1) } @@ -626,7 +632,7 @@ func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, e } func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) { - r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) + r1, _, e1 := syscall.SyscallN(procCheckTokenMembership.Addr(), uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember))) if r1 == 0 { err = errnoErr(e1) } @@ -634,7 +640,7 @@ func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) ( } func CloseServiceHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procCloseServiceHandle.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -642,7 +648,7 @@ func CloseServiceHandle(handle Handle) (err error) { } func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) + r1, _, e1 := syscall.SyscallN(procControlService.Addr(), uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status))) if r1 == 0 { err = errnoErr(e1) } @@ -650,7 +656,7 @@ func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err } func convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(securityInformation), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(strLen)), 0) + r1, _, e1 := syscall.SyscallN(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(securityInformation), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(strLen))) if r1 == 0 { err = errnoErr(e1) } @@ -658,7 +664,7 @@ func convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR } func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0) + r1, _, e1 := syscall.SyscallN(procConvertSidToStringSidW.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid))) if r1 == 0 { err = errnoErr(e1) } @@ -675,7 +681,7 @@ func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision ui } func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size))) if r1 == 0 { err = errnoErr(e1) } @@ -683,7 +689,7 @@ func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision } func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { - r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0) + r1, _, e1 := syscall.SyscallN(procConvertStringSidToSidW.Addr(), uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid))) if r1 == 0 { err = errnoErr(e1) } @@ -691,7 +697,7 @@ func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) { } func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) + r1, _, e1 := syscall.SyscallN(procCopySid.Addr(), uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid))) if r1 == 0 { err = errnoErr(e1) } @@ -703,7 +709,7 @@ func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, proc if inheritHandles { _p0 = 1 } - r1, _, e1 := syscall.Syscall12(procCreateProcessAsUserW.Addr(), 11, uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0) + r1, _, e1 := syscall.SyscallN(procCreateProcessAsUserW.Addr(), uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo))) if r1 == 0 { err = errnoErr(e1) } @@ -711,7 +717,7 @@ func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, proc } func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateServiceW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -720,7 +726,7 @@ func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access } func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCreateWellKnownSid.Addr(), 4, uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCreateWellKnownSid.Addr(), uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid))) if r1 == 0 { err = errnoErr(e1) } @@ -728,7 +734,7 @@ func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, s } func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCryptAcquireContextW.Addr(), uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -736,7 +742,7 @@ func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16 } func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { - r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) + r1, _, e1 := syscall.SyscallN(procCryptGenRandom.Addr(), uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf))) if r1 == 0 { err = errnoErr(e1) } @@ -744,7 +750,7 @@ func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) { } func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCryptReleaseContext.Addr(), uintptr(provhandle), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -752,7 +758,7 @@ func CryptReleaseContext(provhandle Handle, flags uint32) (err error) { } func DeleteService(service Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeleteService.Addr(), uintptr(service)) if r1 == 0 { err = errnoErr(e1) } @@ -760,7 +766,7 @@ func DeleteService(service Handle) (err error) { } func DeregisterEventSource(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeregisterEventSource.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -768,7 +774,7 @@ func DeregisterEventSource(handle Handle) (err error) { } func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) { - r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(existingToken), uintptr(desiredAccess), uintptr(unsafe.Pointer(tokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(newToken))) + r1, _, e1 := syscall.SyscallN(procDuplicateTokenEx.Addr(), uintptr(existingToken), uintptr(desiredAccess), uintptr(unsafe.Pointer(tokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(newToken))) if r1 == 0 { err = errnoErr(e1) } @@ -776,7 +782,7 @@ func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes } func EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procEnumDependentServicesW.Addr(), 6, uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned))) + r1, _, e1 := syscall.SyscallN(procEnumDependentServicesW.Addr(), uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned))) if r1 == 0 { err = errnoErr(e1) } @@ -784,7 +790,7 @@ func EnumDependentServices(service Handle, activityState uint32, services *ENUM_ } func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { - r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) + r1, _, e1 := syscall.SyscallN(procEnumServicesStatusExW.Addr(), uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName))) if r1 == 0 { err = errnoErr(e1) } @@ -792,13 +798,13 @@ func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serv } func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) { - r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0) + r0, _, _ := syscall.SyscallN(procEqualSid.Addr(), uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2))) isEqual = r0 != 0 return } func FreeSid(sid *SID) (err error) { - r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r1, _, e1 := syscall.SyscallN(procFreeSid.Addr(), uintptr(unsafe.Pointer(sid))) if r1 != 0 { err = errnoErr(e1) } @@ -806,7 +812,7 @@ func FreeSid(sid *SID) (err error) { } func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) { - r1, _, e1 := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce))) + r1, _, e1 := syscall.SyscallN(procGetAce.Addr(), uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce))) if r1 == 0 { err = errnoErr(e1) } @@ -814,7 +820,7 @@ func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (err error) { } func GetLengthSid(sid *SID) (len uint32) { - r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetLengthSid.Addr(), uintptr(unsafe.Pointer(sid))) len = uint32(r0) return } @@ -829,7 +835,7 @@ func getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, security } func _getNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procGetNamedSecurityInfoW.Addr(), 8, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) + r0, _, _ := syscall.SyscallN(procGetNamedSecurityInfoW.Addr(), uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -837,7 +843,7 @@ func _getNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securi } func getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(control)), uintptr(unsafe.Pointer(revision))) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(control)), uintptr(unsafe.Pointer(revision))) if r1 == 0 { err = errnoErr(e1) } @@ -853,7 +859,7 @@ func getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl if *daclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorDacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(&_p1))) *daclPresent = _p0 != 0 *daclDefaulted = _p1 != 0 if r1 == 0 { @@ -867,7 +873,7 @@ func getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefau if *groupDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(&_p0))) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorGroup.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(&_p0))) *groupDefaulted = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -876,7 +882,7 @@ func getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefau } func getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetSecurityDescriptorLength.Addr(), uintptr(unsafe.Pointer(sd))) len = uint32(r0) return } @@ -886,7 +892,7 @@ func getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefau if *ownerDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procGetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(&_p0))) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorOwner.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(&_p0))) *ownerDefaulted = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -895,7 +901,7 @@ func getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefau } func getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) + r0, _, _ := syscall.SyscallN(procGetSecurityDescriptorRMControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -911,7 +917,7 @@ func getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl if *saclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(&_p1)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetSecurityDescriptorSacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(&_p0)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(&_p1))) *saclPresent = _p0 != 0 *saclDefaulted = _p1 != 0 if r1 == 0 { @@ -921,7 +927,7 @@ func getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl } func getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) { - r0, _, _ := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd)), 0) + r0, _, _ := syscall.SyscallN(procGetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(sd))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -929,25 +935,25 @@ func getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformati } func getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) { - r0, _, _ := syscall.Syscall(procGetSidIdentifierAuthority.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetSidIdentifierAuthority.Addr(), uintptr(unsafe.Pointer(sid))) authority = (*SidIdentifierAuthority)(unsafe.Pointer(r0)) return } func getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) { - r0, _, _ := syscall.Syscall(procGetSidSubAuthority.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(index), 0) + r0, _, _ := syscall.SyscallN(procGetSidSubAuthority.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(index)) subAuthority = (*uint32)(unsafe.Pointer(r0)) return } func getSidSubAuthorityCount(sid *SID) (count *uint8) { - r0, _, _ := syscall.Syscall(procGetSidSubAuthorityCount.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetSidSubAuthorityCount.Addr(), uintptr(unsafe.Pointer(sid))) count = (*uint8)(unsafe.Pointer(r0)) return } func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0) + r1, _, e1 := syscall.SyscallN(procGetTokenInformation.Addr(), uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen))) if r1 == 0 { err = errnoErr(e1) } @@ -955,7 +961,7 @@ func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint } func ImpersonateSelf(impersonationlevel uint32) (err error) { - r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0) + r1, _, e1 := syscall.SyscallN(procImpersonateSelf.Addr(), uintptr(impersonationlevel)) if r1 == 0 { err = errnoErr(e1) } @@ -963,7 +969,7 @@ func ImpersonateSelf(impersonationlevel uint32) (err error) { } func initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) { - r1, _, e1 := syscall.Syscall(procInitializeSecurityDescriptor.Addr(), 2, uintptr(unsafe.Pointer(absoluteSD)), uintptr(revision), 0) + r1, _, e1 := syscall.SyscallN(procInitializeSecurityDescriptor.Addr(), uintptr(unsafe.Pointer(absoluteSD)), uintptr(revision)) if r1 == 0 { err = errnoErr(e1) } @@ -979,7 +985,7 @@ func InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint if rebootAfterShutdown { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procInitiateSystemShutdownExW.Addr(), 6, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(message)), uintptr(timeout), uintptr(_p0), uintptr(_p1), uintptr(reason)) + r1, _, e1 := syscall.SyscallN(procInitiateSystemShutdownExW.Addr(), uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(message)), uintptr(timeout), uintptr(_p0), uintptr(_p1), uintptr(reason)) if r1 == 0 { err = errnoErr(e1) } @@ -987,7 +993,7 @@ func InitiateSystemShutdownEx(machineName *uint16, message *uint16, timeout uint } func isTokenRestricted(tokenHandle Token) (ret bool, err error) { - r0, _, e1 := syscall.Syscall(procIsTokenRestricted.Addr(), 1, uintptr(tokenHandle), 0, 0) + r0, _, e1 := syscall.SyscallN(procIsTokenRestricted.Addr(), uintptr(tokenHandle)) ret = r0 != 0 if !ret { err = errnoErr(e1) @@ -996,25 +1002,25 @@ func isTokenRestricted(tokenHandle Token) (ret bool, err error) { } func isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) { - r0, _, _ := syscall.Syscall(procIsValidSecurityDescriptor.Addr(), 1, uintptr(unsafe.Pointer(sd)), 0, 0) + r0, _, _ := syscall.SyscallN(procIsValidSecurityDescriptor.Addr(), uintptr(unsafe.Pointer(sd))) isValid = r0 != 0 return } func isValidSid(sid *SID) (isValid bool) { - r0, _, _ := syscall.Syscall(procIsValidSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0) + r0, _, _ := syscall.SyscallN(procIsValidSid.Addr(), uintptr(unsafe.Pointer(sid))) isValid = r0 != 0 return } func isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) { - r0, _, _ := syscall.Syscall(procIsWellKnownSid.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(sidType), 0) + r0, _, _ := syscall.SyscallN(procIsWellKnownSid.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(sidType)) isWellKnown = r0 != 0 return } func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + r1, _, e1 := syscall.SyscallN(procLookupAccountNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use))) if r1 == 0 { err = errnoErr(e1) } @@ -1022,7 +1028,7 @@ func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen } func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0) + r1, _, e1 := syscall.SyscallN(procLookupAccountSidW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use))) if r1 == 0 { err = errnoErr(e1) } @@ -1030,7 +1036,7 @@ func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint3 } func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) + r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { err = errnoErr(e1) } @@ -1038,7 +1044,7 @@ func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err err } func makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall12(procMakeAbsoluteSD.Addr(), 11, uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(absoluteSDSize)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclSize)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(saclSize)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(ownerSize)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(groupSize)), 0) + r1, _, e1 := syscall.SyscallN(procMakeAbsoluteSD.Addr(), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(absoluteSDSize)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclSize)), uintptr(unsafe.Pointer(sacl)), uintptr(unsafe.Pointer(saclSize)), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(ownerSize)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(groupSize))) if r1 == 0 { err = errnoErr(e1) } @@ -1046,7 +1052,7 @@ func makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DE } func makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMakeSelfRelativeSD.Addr(), 3, uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(selfRelativeSDSize))) + r1, _, e1 := syscall.SyscallN(procMakeSelfRelativeSD.Addr(), uintptr(unsafe.Pointer(absoluteSD)), uintptr(unsafe.Pointer(selfRelativeSD)), uintptr(unsafe.Pointer(selfRelativeSDSize))) if r1 == 0 { err = errnoErr(e1) } @@ -1054,7 +1060,7 @@ func makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURIT } func NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) { - r0, _, _ := syscall.Syscall(procNotifyServiceStatusChangeW.Addr(), 3, uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier))) + r0, _, _ := syscall.SyscallN(procNotifyServiceStatusChangeW.Addr(), uintptr(service), uintptr(notifyMask), uintptr(unsafe.Pointer(notifier))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1062,7 +1068,7 @@ func NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERV } func OpenProcessToken(process Handle, access uint32, token *Token) (err error) { - r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(process), uintptr(access), uintptr(unsafe.Pointer(token))) + r1, _, e1 := syscall.SyscallN(procOpenProcessToken.Addr(), uintptr(process), uintptr(access), uintptr(unsafe.Pointer(token))) if r1 == 0 { err = errnoErr(e1) } @@ -1070,7 +1076,7 @@ func OpenProcessToken(process Handle, access uint32, token *Token) (err error) { } func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) + r0, _, e1 := syscall.SyscallN(procOpenSCManagerW.Addr(), uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1079,7 +1085,7 @@ func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (ha } func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) + r0, _, e1 := syscall.SyscallN(procOpenServiceW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1092,7 +1098,7 @@ func OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token if openAsSelf { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) + r1, _, e1 := syscall.SyscallN(procOpenThreadToken.Addr(), uintptr(thread), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token))) if r1 == 0 { err = errnoErr(e1) } @@ -1100,7 +1106,7 @@ func OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token } func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceConfig2W.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1108,7 +1114,7 @@ func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize } func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceConfigW.Addr(), uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1120,7 +1126,7 @@ func QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInf if err != nil { return } - r1, _, e1 := syscall.Syscall(procQueryServiceDynamicInformation.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(dynamicInfo)) + r1, _, e1 := syscall.SyscallN(procQueryServiceDynamicInformation.Addr(), uintptr(service), uintptr(infoLevel), uintptr(dynamicInfo)) if r1 == 0 { err = errnoErr(e1) } @@ -1128,7 +1134,7 @@ func QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInf } func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceLockStatusW.Addr(), 4, uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceLockStatusW.Addr(), uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1136,7 +1142,7 @@ func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, b } func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceStatus.Addr(), uintptr(service), uintptr(unsafe.Pointer(status))) if r1 == 0 { err = errnoErr(e1) } @@ -1144,7 +1150,7 @@ func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) { } func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryServiceStatusEx.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0) + r1, _, e1 := syscall.SyscallN(procQueryServiceStatusEx.Addr(), uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -1152,7 +1158,7 @@ func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize } func RegCloseKey(key Handle) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0) + r0, _, _ := syscall.SyscallN(procRegCloseKey.Addr(), uintptr(key)) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1160,7 +1166,7 @@ func RegCloseKey(key Handle) (regerrno error) { } func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0) + r0, _, _ := syscall.SyscallN(procRegEnumKeyExW.Addr(), uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1176,7 +1182,7 @@ func RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, if asynchronous { _p1 = 1 } - r0, _, _ := syscall.Syscall6(procRegNotifyChangeKeyValue.Addr(), 5, uintptr(key), uintptr(_p0), uintptr(notifyFilter), uintptr(event), uintptr(_p1), 0) + r0, _, _ := syscall.SyscallN(procRegNotifyChangeKeyValue.Addr(), uintptr(key), uintptr(_p0), uintptr(notifyFilter), uintptr(event), uintptr(_p1)) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1184,7 +1190,7 @@ func RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, } func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0) + r0, _, _ := syscall.SyscallN(procRegOpenKeyExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1192,7 +1198,7 @@ func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint } func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) { - r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) + r0, _, _ := syscall.SyscallN(procRegQueryInfoKeyW.Addr(), uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1200,7 +1206,7 @@ func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint } func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) + r0, _, _ := syscall.SyscallN(procRegQueryValueExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen))) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -1208,7 +1214,7 @@ func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32 } func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0) + r0, _, e1 := syscall.SyscallN(procRegisterEventSourceW.Addr(), uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1217,7 +1223,7 @@ func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Hand } func RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procRegisterServiceCtrlHandlerExW.Addr(), 3, uintptr(unsafe.Pointer(serviceName)), uintptr(handlerProc), uintptr(context)) + r0, _, e1 := syscall.SyscallN(procRegisterServiceCtrlHandlerExW.Addr(), uintptr(unsafe.Pointer(serviceName)), uintptr(handlerProc), uintptr(context)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1226,7 +1232,7 @@ func RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, cont } func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) + r1, _, e1 := syscall.SyscallN(procReportEventW.Addr(), uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData))) if r1 == 0 { err = errnoErr(e1) } @@ -1234,7 +1240,7 @@ func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrS } func RevertToSelf() (err error) { - r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) + r1, _, e1 := syscall.SyscallN(procRevertToSelf.Addr()) if r1 == 0 { err = errnoErr(e1) } @@ -1242,7 +1248,7 @@ func RevertToSelf() (err error) { } func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) { - r0, _, _ := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(countExplicitEntries), uintptr(unsafe.Pointer(explicitEntries)), uintptr(unsafe.Pointer(oldACL)), uintptr(unsafe.Pointer(newACL)), 0, 0) + r0, _, _ := syscall.SyscallN(procSetEntriesInAclW.Addr(), uintptr(countExplicitEntries), uintptr(unsafe.Pointer(explicitEntries)), uintptr(unsafe.Pointer(oldACL)), uintptr(unsafe.Pointer(newACL))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1250,7 +1256,7 @@ func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCE } func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) { - r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) + r1, _, e1 := syscall.SyscallN(procSetKernelObjectSecurity.Addr(), uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) if r1 == 0 { err = errnoErr(e1) } @@ -1267,7 +1273,7 @@ func SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, security } func _SetNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { - r0, _, _ := syscall.Syscall9(procSetNamedSecurityInfoW.Addr(), 7, uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) + r0, _, _ := syscall.SyscallN(procSetNamedSecurityInfoW.Addr(), uintptr(unsafe.Pointer(objectName)), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1275,7 +1281,7 @@ func _SetNamedSecurityInfo(objectName *uint16, objectType SE_OBJECT_TYPE, securi } func setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) { - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorControl.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(controlBitsOfInterest), uintptr(controlBitsToSet)) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(controlBitsOfInterest), uintptr(controlBitsToSet)) if r1 == 0 { err = errnoErr(e1) } @@ -1291,7 +1297,7 @@ func setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl * if daclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(dacl)), uintptr(_p1), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorDacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(dacl)), uintptr(_p1)) if r1 == 0 { err = errnoErr(e1) } @@ -1303,7 +1309,7 @@ func setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaul if groupDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorGroup.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(_p0)) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorGroup.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(group)), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -1315,7 +1321,7 @@ func setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaul if ownerDefaulted { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procSetSecurityDescriptorOwner.Addr(), 3, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(_p0)) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorOwner.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(owner)), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -1323,7 +1329,7 @@ func setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaul } func setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) { - syscall.Syscall(procSetSecurityDescriptorRMControl.Addr(), 2, uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl)), 0) + syscall.SyscallN(procSetSecurityDescriptorRMControl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(rmControl))) return } @@ -1336,7 +1342,7 @@ func setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl * if saclDefaulted { _p1 = 1 } - r1, _, e1 := syscall.Syscall6(procSetSecurityDescriptorSacl.Addr(), 4, uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(sacl)), uintptr(_p1), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetSecurityDescriptorSacl.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(_p0), uintptr(unsafe.Pointer(sacl)), uintptr(_p1)) if r1 == 0 { err = errnoErr(e1) } @@ -1344,7 +1350,7 @@ func setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl * } func SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) { - r0, _, _ := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl)), 0, 0) + r0, _, _ := syscall.SyscallN(procSetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(securityInformation), uintptr(unsafe.Pointer(owner)), uintptr(unsafe.Pointer(group)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(sacl))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1352,7 +1358,7 @@ func SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformati } func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) { - r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0) + r1, _, e1 := syscall.SyscallN(procSetServiceStatus.Addr(), uintptr(service), uintptr(unsafe.Pointer(serviceStatus))) if r1 == 0 { err = errnoErr(e1) } @@ -1360,7 +1366,7 @@ func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) } func SetThreadToken(thread *Handle, token Token) (err error) { - r1, _, e1 := syscall.Syscall(procSetThreadToken.Addr(), 2, uintptr(unsafe.Pointer(thread)), uintptr(token), 0) + r1, _, e1 := syscall.SyscallN(procSetThreadToken.Addr(), uintptr(unsafe.Pointer(thread)), uintptr(token)) if r1 == 0 { err = errnoErr(e1) } @@ -1368,7 +1374,7 @@ func SetThreadToken(thread *Handle, token Token) (err error) { } func SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetTokenInformation.Addr(), uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen)) if r1 == 0 { err = errnoErr(e1) } @@ -1376,7 +1382,7 @@ func SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint } func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0) + r1, _, e1 := syscall.SyscallN(procStartServiceCtrlDispatcherW.Addr(), uintptr(unsafe.Pointer(serviceTable))) if r1 == 0 { err = errnoErr(e1) } @@ -1384,7 +1390,7 @@ func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) { } func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) + r1, _, e1 := syscall.SyscallN(procStartServiceW.Addr(), uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) if r1 == 0 { err = errnoErr(e1) } @@ -1392,7 +1398,7 @@ func StartService(service Handle, numArgs uint32, argVectors **uint16) (err erro } func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) { - r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertAddCertificateContextToStore.Addr(), uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext))) if r1 == 0 { err = errnoErr(e1) } @@ -1400,7 +1406,7 @@ func CertAddCertificateContextToStore(store Handle, certContext *CertContext, ad } func CertCloseStore(store Handle, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procCertCloseStore.Addr(), uintptr(store), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -1408,7 +1414,7 @@ func CertCloseStore(store Handle, flags uint32) (err error) { } func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) + r0, _, e1 := syscall.SyscallN(procCertCreateCertificateContext.Addr(), uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen)) context = (*CertContext)(unsafe.Pointer(r0)) if context == nil { err = errnoErr(e1) @@ -1417,7 +1423,7 @@ func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, en } func CertDeleteCertificateFromStore(certContext *CertContext) (err error) { - r1, _, e1 := syscall.Syscall(procCertDeleteCertificateFromStore.Addr(), 1, uintptr(unsafe.Pointer(certContext)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertDeleteCertificateFromStore.Addr(), uintptr(unsafe.Pointer(certContext))) if r1 == 0 { err = errnoErr(e1) } @@ -1425,13 +1431,13 @@ func CertDeleteCertificateFromStore(certContext *CertContext) (err error) { } func CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext) { - r0, _, _ := syscall.Syscall(procCertDuplicateCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(certContext)), 0, 0) + r0, _, _ := syscall.SyscallN(procCertDuplicateCertificateContext.Addr(), uintptr(unsafe.Pointer(certContext))) dupContext = (*CertContext)(unsafe.Pointer(r0)) return } func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { - r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) + r0, _, e1 := syscall.SyscallN(procCertEnumCertificatesInStore.Addr(), uintptr(store), uintptr(unsafe.Pointer(prevContext))) context = (*CertContext)(unsafe.Pointer(r0)) if context == nil { err = errnoErr(e1) @@ -1440,7 +1446,7 @@ func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (contex } func CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevCertContext *CertContext) (cert *CertContext, err error) { - r0, _, e1 := syscall.Syscall6(procCertFindCertificateInStore.Addr(), 6, uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevCertContext))) + r0, _, e1 := syscall.SyscallN(procCertFindCertificateInStore.Addr(), uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevCertContext))) cert = (*CertContext)(unsafe.Pointer(r0)) if cert == nil { err = errnoErr(e1) @@ -1449,7 +1455,7 @@ func CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags } func CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevChainContext *CertChainContext) (certchain *CertChainContext, err error) { - r0, _, e1 := syscall.Syscall6(procCertFindChainInStore.Addr(), 6, uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevChainContext))) + r0, _, e1 := syscall.SyscallN(procCertFindChainInStore.Addr(), uintptr(store), uintptr(certEncodingType), uintptr(findFlags), uintptr(findType), uintptr(findPara), uintptr(unsafe.Pointer(prevChainContext))) certchain = (*CertChainContext)(unsafe.Pointer(r0)) if certchain == nil { err = errnoErr(e1) @@ -1458,18 +1464,18 @@ func CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint3 } func CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) { - r0, _, _ := syscall.Syscall(procCertFindExtension.Addr(), 3, uintptr(unsafe.Pointer(objId)), uintptr(countExtensions), uintptr(unsafe.Pointer(extensions))) + r0, _, _ := syscall.SyscallN(procCertFindExtension.Addr(), uintptr(unsafe.Pointer(objId)), uintptr(countExtensions), uintptr(unsafe.Pointer(extensions))) ret = (*CertExtension)(unsafe.Pointer(r0)) return } func CertFreeCertificateChain(ctx *CertChainContext) { - syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + syscall.SyscallN(procCertFreeCertificateChain.Addr(), uintptr(unsafe.Pointer(ctx))) return } func CertFreeCertificateContext(ctx *CertContext) (err error) { - r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertFreeCertificateContext.Addr(), uintptr(unsafe.Pointer(ctx))) if r1 == 0 { err = errnoErr(e1) } @@ -1477,7 +1483,7 @@ func CertFreeCertificateContext(ctx *CertContext) (err error) { } func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) { - r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0) + r1, _, e1 := syscall.SyscallN(procCertGetCertificateChain.Addr(), uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx))) if r1 == 0 { err = errnoErr(e1) } @@ -1485,13 +1491,13 @@ func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, a } func CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) { - r0, _, _ := syscall.Syscall6(procCertGetNameStringW.Addr(), 6, uintptr(unsafe.Pointer(certContext)), uintptr(nameType), uintptr(flags), uintptr(typePara), uintptr(unsafe.Pointer(name)), uintptr(size)) + r0, _, _ := syscall.SyscallN(procCertGetNameStringW.Addr(), uintptr(unsafe.Pointer(certContext)), uintptr(nameType), uintptr(flags), uintptr(typePara), uintptr(unsafe.Pointer(name)), uintptr(size)) chars = uint32(r0) return } func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0) + r0, _, e1 := syscall.SyscallN(procCertOpenStore.Addr(), uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1500,7 +1506,7 @@ func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptPr } func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { - r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0) + r0, _, e1 := syscall.SyscallN(procCertOpenSystemStoreW.Addr(), uintptr(hprov), uintptr(unsafe.Pointer(name))) store = Handle(r0) if store == 0 { err = errnoErr(e1) @@ -1509,7 +1515,7 @@ func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) { } func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) { - r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCertVerifyCertificateChainPolicy.Addr(), uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status))) if r1 == 0 { err = errnoErr(e1) } @@ -1521,7 +1527,7 @@ func CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, paramete if *callerFreeProvOrNCryptKey { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procCryptAcquireCertificatePrivateKey.Addr(), 6, uintptr(unsafe.Pointer(cert)), uintptr(flags), uintptr(parameters), uintptr(unsafe.Pointer(cryptProvOrNCryptKey)), uintptr(unsafe.Pointer(keySpec)), uintptr(unsafe.Pointer(&_p0))) + r1, _, e1 := syscall.SyscallN(procCryptAcquireCertificatePrivateKey.Addr(), uintptr(unsafe.Pointer(cert)), uintptr(flags), uintptr(parameters), uintptr(unsafe.Pointer(cryptProvOrNCryptKey)), uintptr(unsafe.Pointer(keySpec)), uintptr(unsafe.Pointer(&_p0))) *callerFreeProvOrNCryptKey = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -1530,7 +1536,7 @@ func CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, paramete } func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procCryptDecodeObject.Addr(), 7, uintptr(encodingType), uintptr(unsafe.Pointer(structType)), uintptr(unsafe.Pointer(encodedBytes)), uintptr(lenEncodedBytes), uintptr(flags), uintptr(decoded), uintptr(unsafe.Pointer(decodedLen)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptDecodeObject.Addr(), uintptr(encodingType), uintptr(unsafe.Pointer(structType)), uintptr(unsafe.Pointer(encodedBytes)), uintptr(lenEncodedBytes), uintptr(flags), uintptr(decoded), uintptr(unsafe.Pointer(decodedLen))) if r1 == 0 { err = errnoErr(e1) } @@ -1538,7 +1544,7 @@ func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte } func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { - r1, _, e1 := syscall.Syscall9(procCryptProtectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptProtectData.Addr(), uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut))) if r1 == 0 { err = errnoErr(e1) } @@ -1546,7 +1552,7 @@ func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, } func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) { - r1, _, e1 := syscall.Syscall12(procCryptQueryObject.Addr(), 11, uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context)), 0) + r1, _, e1 := syscall.SyscallN(procCryptQueryObject.Addr(), uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context))) if r1 == 0 { err = errnoErr(e1) } @@ -1554,7 +1560,7 @@ func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentT } func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { - r1, _, e1 := syscall.Syscall9(procCryptUnprotectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCryptUnprotectData.Addr(), uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut))) if r1 == 0 { err = errnoErr(e1) } @@ -1562,7 +1568,7 @@ func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBl } func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) { - r0, _, e1 := syscall.Syscall(procPFXImportCertStore.Addr(), 3, uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags)) + r0, _, e1 := syscall.SyscallN(procPFXImportCertStore.Addr(), uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags)) store = Handle(r0) if store == 0 { err = errnoErr(e1) @@ -1571,7 +1577,7 @@ func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (sto } func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { - r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) + r0, _, _ := syscall.SyscallN(procDnsNameCompare_W.Addr(), uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2))) same = r0 != 0 return } @@ -1586,7 +1592,7 @@ func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSR } func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) { - r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) + r0, _, _ := syscall.SyscallN(procDnsQuery_W.Addr(), uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr))) if r0 != 0 { status = syscall.Errno(r0) } @@ -1594,12 +1600,12 @@ func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DN } func DnsRecordListFree(rl *DNSRecord, freetype uint32) { - syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0) + syscall.SyscallN(procDnsRecordListFree.Addr(), uintptr(unsafe.Pointer(rl)), uintptr(freetype)) return } func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { - r0, _, _ := syscall.Syscall6(procDwmGetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + r0, _, _ := syscall.SyscallN(procDwmGetWindowAttribute.Addr(), uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1607,7 +1613,7 @@ func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si } func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) { - r0, _, _ := syscall.Syscall6(procDwmSetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0) + r0, _, _ := syscall.SyscallN(procDwmSetWindowAttribute.Addr(), uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -1615,15 +1621,20 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si } func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { - r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0) + r0, _, _ := syscall.SyscallN(procCancelMibChangeNotify2.Addr(), uintptr(notificationHandle)) if r0 != 0 { errcode = syscall.Errno(r0) } return } +func FreeMibTable(memory unsafe.Pointer) { + syscall.SyscallN(procFreeMibTable.Addr(), uintptr(memory)) + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { - r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) + r0, _, _ := syscall.SyscallN(procGetAdaptersAddresses.Addr(), uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1631,7 +1642,7 @@ func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapter } func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { - r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0) + r0, _, _ := syscall.SyscallN(procGetAdaptersInfo.Addr(), uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1639,7 +1650,7 @@ func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) { } func getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) { - r0, _, _ := syscall.Syscall(procGetBestInterfaceEx.Addr(), 2, uintptr(sockaddr), uintptr(unsafe.Pointer(pdwBestIfIndex)), 0) + r0, _, _ := syscall.SyscallN(procGetBestInterfaceEx.Addr(), uintptr(sockaddr), uintptr(unsafe.Pointer(pdwBestIfIndex))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1647,7 +1658,7 @@ func getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcod } func GetIfEntry(pIfRow *MibIfRow) (errcode error) { - r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetIfEntry.Addr(), uintptr(unsafe.Pointer(pIfRow))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1655,7 +1666,23 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) { } func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { - r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0) + r0, _, _ := syscall.SyscallN(procGetIfEntry2Ex.Addr(), uintptr(level), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardEntry2(row *MibIpForwardRow2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardEntry2.Addr(), uintptr(unsafe.Pointer(row))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetIpForwardTable2(family uint16, table **MibIpForwardTable2) (errcode error) { + r0, _, _ := syscall.SyscallN(procGetIpForwardTable2.Addr(), uintptr(family), uintptr(unsafe.Pointer(table))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1663,7 +1690,7 @@ func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { } func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { - r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1675,7 +1702,19 @@ func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsa if initialNotification { _p0 = 1 } - r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + r0, _, _ := syscall.SyscallN(procNotifyIpInterfaceChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyRouteChange2(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.SyscallN(procNotifyRouteChange2.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1687,7 +1726,7 @@ func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext if initialNotification { _p0 = 1 } - r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + r0, _, _ := syscall.SyscallN(procNotifyUnicastIpAddressChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1695,7 +1734,7 @@ func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext } func AddDllDirectory(path *uint16) (cookie uintptr, err error) { - r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r0, _, e1 := syscall.SyscallN(procAddDllDirectory.Addr(), uintptr(unsafe.Pointer(path))) cookie = uintptr(r0) if cookie == 0 { err = errnoErr(e1) @@ -1704,7 +1743,7 @@ func AddDllDirectory(path *uint16) (cookie uintptr, err error) { } func AssignProcessToJobObject(job Handle, process Handle) (err error) { - r1, _, e1 := syscall.Syscall(procAssignProcessToJobObject.Addr(), 2, uintptr(job), uintptr(process), 0) + r1, _, e1 := syscall.SyscallN(procAssignProcessToJobObject.Addr(), uintptr(job), uintptr(process)) if r1 == 0 { err = errnoErr(e1) } @@ -1712,7 +1751,7 @@ func AssignProcessToJobObject(job Handle, process Handle) (err error) { } func CancelIo(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0) + r1, _, e1 := syscall.SyscallN(procCancelIo.Addr(), uintptr(s)) if r1 == 0 { err = errnoErr(e1) } @@ -1720,7 +1759,7 @@ func CancelIo(s Handle) (err error) { } func CancelIoEx(s Handle, o *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0) + r1, _, e1 := syscall.SyscallN(procCancelIoEx.Addr(), uintptr(s), uintptr(unsafe.Pointer(o))) if r1 == 0 { err = errnoErr(e1) } @@ -1728,7 +1767,7 @@ func CancelIoEx(s Handle, o *Overlapped) (err error) { } func ClearCommBreak(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procClearCommBreak.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -1736,7 +1775,7 @@ func ClearCommBreak(handle Handle) (err error) { } func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error) { - r1, _, e1 := syscall.Syscall(procClearCommError.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat))) + r1, _, e1 := syscall.SyscallN(procClearCommError.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpErrors)), uintptr(unsafe.Pointer(lpStat))) if r1 == 0 { err = errnoErr(e1) } @@ -1744,7 +1783,7 @@ func ClearCommError(handle Handle, lpErrors *uint32, lpStat *ComStat) (err error } func CloseHandle(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procCloseHandle.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -1752,12 +1791,12 @@ func CloseHandle(handle Handle) (err error) { } func ClosePseudoConsole(console Handle) { - syscall.Syscall(procClosePseudoConsole.Addr(), 1, uintptr(console), 0, 0) + syscall.SyscallN(procClosePseudoConsole.Addr(), uintptr(console)) return } func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procConnectNamedPipe.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -1765,7 +1804,7 @@ func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) { } func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { - r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0) + r1, _, e1 := syscall.SyscallN(procCreateDirectoryW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa))) if r1 == 0 { err = errnoErr(e1) } @@ -1773,7 +1812,7 @@ func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) { } func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateEventExW.Addr(), uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess)) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1782,7 +1821,7 @@ func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, d } func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateEventW.Addr(), uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1791,7 +1830,7 @@ func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialStat } func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procCreateFileMappingW.Addr(), uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1800,7 +1839,7 @@ func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxS } func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile Handle) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -1809,7 +1848,7 @@ func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes } func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procCreateHardLinkW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved)) if r1&0xff == 0 { err = errnoErr(e1) } @@ -1817,7 +1856,7 @@ func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr } func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, threadcnt uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateIoCompletionPort.Addr(), uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1826,7 +1865,7 @@ func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uintptr, thr } func CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateJobObjectW.Addr(), 2, uintptr(unsafe.Pointer(jobAttr)), uintptr(unsafe.Pointer(name)), 0) + r0, _, e1 := syscall.SyscallN(procCreateJobObjectW.Addr(), uintptr(unsafe.Pointer(jobAttr)), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -1835,7 +1874,7 @@ func CreateJobObject(jobAttr *SecurityAttributes, name *uint16) (handle Handle, } func CreateMutexEx(mutexAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateMutexExW.Addr(), 4, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0) + r0, _, e1 := syscall.SyscallN(procCreateMutexExW.Addr(), uintptr(unsafe.Pointer(mutexAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess)) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1848,7 +1887,7 @@ func CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16 if initialOwner { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procCreateMutexW.Addr(), 3, uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procCreateMutexW.Addr(), uintptr(unsafe.Pointer(mutexAttrs)), uintptr(_p0), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 || e1 == ERROR_ALREADY_EXISTS { err = errnoErr(e1) @@ -1857,7 +1896,7 @@ func CreateMutex(mutexAttrs *SecurityAttributes, initialOwner bool, name *uint16 } func CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) + r0, _, e1 := syscall.SyscallN(procCreateNamedPipeW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa))) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -1866,7 +1905,7 @@ func CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances u } func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0) + r1, _, e1 := syscall.SyscallN(procCreatePipe.Addr(), uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size)) if r1 == 0 { err = errnoErr(e1) } @@ -1878,7 +1917,7 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA if inheritHandles { _p0 = 1 } - r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0) + r1, _, e1 := syscall.SyscallN(procCreateProcessW.Addr(), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo))) if r1 == 0 { err = errnoErr(e1) } @@ -1886,7 +1925,7 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA } func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) { - r0, _, _ := syscall.Syscall6(procCreatePseudoConsole.Addr(), 5, uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole)), 0) + r0, _, _ := syscall.SyscallN(procCreatePseudoConsole.Addr(), uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole))) if r0 != 0 { hr = syscall.Errno(r0) } @@ -1894,7 +1933,7 @@ func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pcons } func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procCreateSymbolicLinkW.Addr(), uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) if r1&0xff == 0 { err = errnoErr(e1) } @@ -1902,7 +1941,7 @@ func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags u } func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0) + r0, _, e1 := syscall.SyscallN(procCreateToolhelp32Snapshot.Addr(), uintptr(flags), uintptr(processId)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -1911,7 +1950,7 @@ func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, er } func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDefineDosDeviceW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) + r1, _, e1 := syscall.SyscallN(procDefineDosDeviceW.Addr(), uintptr(flags), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath))) if r1 == 0 { err = errnoErr(e1) } @@ -1919,7 +1958,7 @@ func DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err } func DeleteFile(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeleteFileW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -1927,12 +1966,12 @@ func DeleteFile(path *uint16) (err error) { } func deleteProcThreadAttributeList(attrlist *ProcThreadAttributeList) { - syscall.Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0) + syscall.SyscallN(procDeleteProcThreadAttributeList.Addr(), uintptr(unsafe.Pointer(attrlist))) return } func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDeleteVolumeMountPointW.Addr(), 1, uintptr(unsafe.Pointer(volumeMountPoint)), 0, 0) + r1, _, e1 := syscall.SyscallN(procDeleteVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint))) if r1 == 0 { err = errnoErr(e1) } @@ -1940,7 +1979,7 @@ func DeleteVolumeMountPoint(volumeMountPoint *uint16) (err error) { } func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procDeviceIoControl.Addr(), uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -1948,7 +1987,7 @@ func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBuff } func DisconnectNamedPipe(pipe Handle) (err error) { - r1, _, e1 := syscall.Syscall(procDisconnectNamedPipe.Addr(), 1, uintptr(pipe), 0, 0) + r1, _, e1 := syscall.SyscallN(procDisconnectNamedPipe.Addr(), uintptr(pipe)) if r1 == 0 { err = errnoErr(e1) } @@ -1960,7 +1999,7 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP if bInheritHandle { _p0 = 1 } - r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0) + r1, _, e1 := syscall.SyscallN(procDuplicateHandle.Addr(), uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions)) if r1 == 0 { err = errnoErr(e1) } @@ -1968,7 +2007,7 @@ func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetP } func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) { - r1, _, e1 := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(dwFunc), 0) + r1, _, e1 := syscall.SyscallN(procEscapeCommFunction.Addr(), uintptr(handle), uintptr(dwFunc)) if r1 == 0 { err = errnoErr(e1) } @@ -1976,12 +2015,12 @@ func EscapeCommFunction(handle Handle, dwFunc uint32) (err error) { } func ExitProcess(exitcode uint32) { - syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0) + syscall.SyscallN(procExitProcess.Addr(), uintptr(exitcode)) return } func ExpandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) + r0, _, e1 := syscall.SyscallN(procExpandEnvironmentStringsW.Addr(), uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -1990,7 +2029,7 @@ func ExpandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, } func FindClose(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindClose.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -1998,7 +2037,7 @@ func FindClose(handle Handle) (err error) { } func FindCloseChangeNotification(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindCloseChangeNotification.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindCloseChangeNotification.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2019,7 +2058,7 @@ func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter if watchSubtree { _p1 = 1 } - r0, _, e1 := syscall.Syscall(procFindFirstChangeNotificationW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter)) + r0, _, e1 := syscall.SyscallN(procFindFirstChangeNotificationW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(_p1), uintptr(notifyFilter)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2028,7 +2067,7 @@ func _FindFirstChangeNotification(path *uint16, watchSubtree bool, notifyFilter } func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0) + r0, _, e1 := syscall.SyscallN(procFindFirstFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data))) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2037,7 +2076,7 @@ func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err erro } func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + r0, _, e1 := syscall.SyscallN(procFindFirstVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2046,7 +2085,7 @@ func FindFirstVolumeMountPoint(rootPathName *uint16, volumeMountPoint *uint16, b } func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength), 0) + r0, _, e1 := syscall.SyscallN(procFindFirstVolumeW.Addr(), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2055,7 +2094,7 @@ func FindFirstVolume(volumeName *uint16, bufferLength uint32) (handle Handle, er } func FindNextChangeNotification(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextChangeNotification.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindNextChangeNotification.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2063,7 +2102,7 @@ func FindNextChangeNotification(handle Handle) (err error) { } func findNextFile1(handle Handle, data *win32finddata1) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + r1, _, e1 := syscall.SyscallN(procFindNextFileW.Addr(), uintptr(handle), uintptr(unsafe.Pointer(data))) if r1 == 0 { err = errnoErr(e1) } @@ -2071,7 +2110,7 @@ func findNextFile1(handle Handle, data *win32finddata1) (err error) { } func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeMountPointW.Addr(), 3, uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) + r1, _, e1 := syscall.SyscallN(procFindNextVolumeMountPointW.Addr(), uintptr(findVolumeMountPoint), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(bufferLength)) if r1 == 0 { err = errnoErr(e1) } @@ -2079,7 +2118,7 @@ func FindNextVolumeMountPoint(findVolumeMountPoint Handle, volumeMountPoint *uin } func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) + r1, _, e1 := syscall.SyscallN(procFindNextVolumeW.Addr(), uintptr(findVolume), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferLength)) if r1 == 0 { err = errnoErr(e1) } @@ -2087,7 +2126,7 @@ func FindNextVolume(findVolume Handle, volumeName *uint16, bufferLength uint32) } func findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, err error) { - r0, _, e1 := syscall.Syscall(procFindResourceW.Addr(), 3, uintptr(module), uintptr(name), uintptr(resType)) + r0, _, e1 := syscall.SyscallN(procFindResourceW.Addr(), uintptr(module), uintptr(name), uintptr(resType)) resInfo = Handle(r0) if resInfo == 0 { err = errnoErr(e1) @@ -2096,7 +2135,7 @@ func findResource(module Handle, name uintptr, resType uintptr) (resInfo Handle, } func FindVolumeClose(findVolume Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(findVolume), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindVolumeClose.Addr(), uintptr(findVolume)) if r1 == 0 { err = errnoErr(e1) } @@ -2104,7 +2143,15 @@ func FindVolumeClose(findVolume Handle) (err error) { } func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFindVolumeMountPointClose.Addr(), 1, uintptr(findVolumeMountPoint), 0, 0) + r1, _, e1 := syscall.SyscallN(procFindVolumeMountPointClose.Addr(), uintptr(findVolumeMountPoint)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func FlushConsoleInputBuffer(console Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procFlushConsoleInputBuffer.Addr(), uintptr(console)) if r1 == 0 { err = errnoErr(e1) } @@ -2112,7 +2159,7 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) { } func FlushFileBuffers(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFlushFileBuffers.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2120,7 +2167,7 @@ func FlushFileBuffers(handle Handle) (err error) { } func FlushViewOfFile(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0) + r1, _, e1 := syscall.SyscallN(procFlushViewOfFile.Addr(), uintptr(addr), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -2132,7 +2179,7 @@ func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, bu if len(buf) > 0 { _p0 = &buf[0] } - r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0) + r0, _, e1 := syscall.SyscallN(procFormatMessageW.Addr(), uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2141,7 +2188,7 @@ func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, bu } func FreeEnvironmentStrings(envs *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0) + r1, _, e1 := syscall.SyscallN(procFreeEnvironmentStringsW.Addr(), uintptr(unsafe.Pointer(envs))) if r1 == 0 { err = errnoErr(e1) } @@ -2149,7 +2196,7 @@ func FreeEnvironmentStrings(envs *uint16) (err error) { } func FreeLibrary(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procFreeLibrary.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -2157,7 +2204,7 @@ func FreeLibrary(handle Handle) (err error) { } func GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGenerateConsoleCtrlEvent.Addr(), 2, uintptr(ctrlEvent), uintptr(processGroupID), 0) + r1, _, e1 := syscall.SyscallN(procGenerateConsoleCtrlEvent.Addr(), uintptr(ctrlEvent), uintptr(processGroupID)) if r1 == 0 { err = errnoErr(e1) } @@ -2165,19 +2212,19 @@ func GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err erro } func GetACP() (acp uint32) { - r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetACP.Addr()) acp = uint32(r0) return } func GetActiveProcessorCount(groupNumber uint16) (ret uint32) { - r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) + r0, _, _ := syscall.SyscallN(procGetActiveProcessorCount.Addr(), uintptr(groupNumber)) ret = uint32(r0) return } func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpModemStat)), 0) + r1, _, e1 := syscall.SyscallN(procGetCommModemStatus.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpModemStat))) if r1 == 0 { err = errnoErr(e1) } @@ -2185,7 +2232,7 @@ func GetCommModemStatus(handle Handle, lpModemStat *uint32) (err error) { } func GetCommState(handle Handle, lpDCB *DCB) (err error) { - r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0) + r1, _, e1 := syscall.SyscallN(procGetCommState.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpDCB))) if r1 == 0 { err = errnoErr(e1) } @@ -2193,7 +2240,7 @@ func GetCommState(handle Handle, lpDCB *DCB) (err error) { } func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { - r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) + r1, _, e1 := syscall.SyscallN(procGetCommTimeouts.Addr(), uintptr(handle), uintptr(unsafe.Pointer(timeouts))) if r1 == 0 { err = errnoErr(e1) } @@ -2201,13 +2248,13 @@ func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { } func GetCommandLine() (cmd *uint16) { - r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetCommandLineW.Addr()) cmd = (*uint16)(unsafe.Pointer(r0)) return } func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) + r1, _, e1 := syscall.SyscallN(procGetComputerNameExW.Addr(), uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) if r1 == 0 { err = errnoErr(e1) } @@ -2215,7 +2262,7 @@ func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) { } func GetComputerName(buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0) + r1, _, e1 := syscall.SyscallN(procGetComputerNameW.Addr(), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) if r1 == 0 { err = errnoErr(e1) } @@ -2223,7 +2270,7 @@ func GetComputerName(buf *uint16, n *uint32) (err error) { } func GetConsoleCP() (cp uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetConsoleCP.Addr()) cp = uint32(r0) if cp == 0 { err = errnoErr(e1) @@ -2232,7 +2279,7 @@ func GetConsoleCP() (cp uint32, err error) { } func GetConsoleMode(console Handle, mode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) + r1, _, e1 := syscall.SyscallN(procGetConsoleMode.Addr(), uintptr(console), uintptr(unsafe.Pointer(mode))) if r1 == 0 { err = errnoErr(e1) } @@ -2240,7 +2287,7 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) { } func GetConsoleOutputCP() (cp uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetConsoleOutputCP.Addr()) cp = uint32(r0) if cp == 0 { err = errnoErr(e1) @@ -2249,7 +2296,7 @@ func GetConsoleOutputCP() (cp uint32, err error) { } func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) + r1, _, e1 := syscall.SyscallN(procGetConsoleScreenBufferInfo.Addr(), uintptr(console), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -2257,7 +2304,7 @@ func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) ( } func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + r0, _, e1 := syscall.SyscallN(procGetCurrentDirectoryW.Addr(), uintptr(buflen), uintptr(unsafe.Pointer(buf))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2266,19 +2313,19 @@ func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) { } func GetCurrentProcessId() (pid uint32) { - r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetCurrentProcessId.Addr()) pid = uint32(r0) return } func GetCurrentThreadId() (id uint32) { - r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetCurrentThreadId.Addr()) id = uint32(r0) return } func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { - r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetDiskFreeSpaceExW.Addr(), uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes))) if r1 == 0 { err = errnoErr(e1) } @@ -2286,13 +2333,13 @@ func GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *uint6 } func GetDriveType(rootPathName *uint16) (driveType uint32) { - r0, _, _ := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetDriveTypeW.Addr(), uintptr(unsafe.Pointer(rootPathName))) driveType = uint32(r0) return } func GetEnvironmentStrings() (envs *uint16, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetEnvironmentStringsW.Addr()) envs = (*uint16)(unsafe.Pointer(r0)) if envs == nil { err = errnoErr(e1) @@ -2301,7 +2348,7 @@ func GetEnvironmentStrings() (envs *uint16, err error) { } func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) + r0, _, e1 := syscall.SyscallN(procGetEnvironmentVariableW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2310,7 +2357,7 @@ func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32 } func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0) + r1, _, e1 := syscall.SyscallN(procGetExitCodeProcess.Addr(), uintptr(handle), uintptr(unsafe.Pointer(exitcode))) if r1 == 0 { err = errnoErr(e1) } @@ -2318,7 +2365,7 @@ func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) { } func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) + r1, _, e1 := syscall.SyscallN(procGetFileAttributesExW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -2326,7 +2373,7 @@ func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) { } func GetFileAttributes(name *uint16) (attrs uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFileAttributesW.Addr(), uintptr(unsafe.Pointer(name))) attrs = uint32(r0) if attrs == INVALID_FILE_ATTRIBUTES { err = errnoErr(e1) @@ -2335,7 +2382,7 @@ func GetFileAttributes(name *uint16) (attrs uint32, err error) { } func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) { - r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0) + r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandle.Addr(), uintptr(handle), uintptr(unsafe.Pointer(data))) if r1 == 0 { err = errnoErr(e1) } @@ -2343,7 +2390,7 @@ func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (e } func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, outBufferLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetFileInformationByHandleEx.Addr(), uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferLen)) if r1 == 0 { err = errnoErr(e1) } @@ -2351,7 +2398,7 @@ func GetFileInformationByHandleEx(handle Handle, class uint32, outBuffer *byte, } func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetFileTime.Addr(), uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime))) if r1 == 0 { err = errnoErr(e1) } @@ -2359,7 +2406,7 @@ func GetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim } func GetFileType(filehandle Handle) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFileType.Addr(), uintptr(filehandle)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2368,7 +2415,7 @@ func GetFileType(filehandle Handle) (n uint32, err error) { } func GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFinalPathNameByHandleW.Addr(), uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2377,7 +2424,7 @@ func GetFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32 } func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetFullPathNameW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2386,13 +2433,13 @@ func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) ( } func GetLargePageMinimum() (size uintptr) { - r0, _, _ := syscall.Syscall(procGetLargePageMinimum.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetLargePageMinimum.Addr()) size = uintptr(r0) return } func GetLastError() (lasterr error) { - r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetLastError.Addr()) if r0 != 0 { lasterr = syscall.Errno(r0) } @@ -2400,7 +2447,7 @@ func GetLastError() (lasterr error) { } func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) + r0, _, e1 := syscall.SyscallN(procGetLogicalDriveStringsW.Addr(), uintptr(bufferLength), uintptr(unsafe.Pointer(buffer))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2409,7 +2456,7 @@ func GetLogicalDriveStrings(bufferLength uint32, buffer *uint16) (n uint32, err } func GetLogicalDrives() (drivesBitMask uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLogicalDrives.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetLogicalDrives.Addr()) drivesBitMask = uint32(r0) if drivesBitMask == 0 { err = errnoErr(e1) @@ -2418,7 +2465,7 @@ func GetLogicalDrives() (drivesBitMask uint32, err error) { } func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) + r0, _, e1 := syscall.SyscallN(procGetLongPathNameW.Addr(), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2427,13 +2474,13 @@ func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err er } func GetMaximumProcessorCount(groupNumber uint16) (ret uint32) { - r0, _, _ := syscall.Syscall(procGetMaximumProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) + r0, _, _ := syscall.SyscallN(procGetMaximumProcessorCount.Addr(), uintptr(groupNumber)) ret = uint32(r0) return } func GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) + r0, _, e1 := syscall.SyscallN(procGetModuleFileNameW.Addr(), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2442,7 +2489,7 @@ func GetModuleFileName(module Handle, filename *uint16, size uint32) (n uint32, } func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err error) { - r1, _, e1 := syscall.Syscall(procGetModuleHandleExW.Addr(), 3, uintptr(flags), uintptr(unsafe.Pointer(moduleName)), uintptr(unsafe.Pointer(module))) + r1, _, e1 := syscall.SyscallN(procGetModuleHandleExW.Addr(), uintptr(flags), uintptr(unsafe.Pointer(moduleName)), uintptr(unsafe.Pointer(module))) if r1 == 0 { err = errnoErr(e1) } @@ -2450,7 +2497,7 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er } func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeClientProcessId.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID))) if r1 == 0 { err = errnoErr(e1) } @@ -2458,7 +2505,7 @@ func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err erro } func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeHandleStateW.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize)) if r1 == 0 { err = errnoErr(e1) } @@ -2466,7 +2513,7 @@ func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, m } func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeInfo.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances))) if r1 == 0 { err = errnoErr(e1) } @@ -2474,7 +2521,15 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3 } func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0) + r1, _, e1 := syscall.SyscallN(procGetNamedPipeServerProcessId.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNumberOfConsoleInputEvents.Addr(), uintptr(console), uintptr(unsafe.Pointer(numevents))) if r1 == 0 { err = errnoErr(e1) } @@ -2486,7 +2541,7 @@ func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wa if wait { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(done)), uintptr(_p0), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetOverlappedResult.Addr(), uintptr(handle), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(done)), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -2494,7 +2549,7 @@ func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wa } func GetPriorityClass(process Handle) (ret uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetPriorityClass.Addr(), 1, uintptr(process), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetPriorityClass.Addr(), uintptr(process)) ret = uint32(r0) if ret == 0 { err = errnoErr(e1) @@ -2512,7 +2567,7 @@ func GetProcAddress(module Handle, procname string) (proc uintptr, err error) { } func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { - r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0) + r0, _, e1 := syscall.SyscallN(procGetProcAddress.Addr(), uintptr(module), uintptr(unsafe.Pointer(procname))) proc = uintptr(r0) if proc == 0 { err = errnoErr(e1) @@ -2521,7 +2576,7 @@ func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) { } func GetProcessId(process Handle) (id uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetProcessId.Addr(), 1, uintptr(process), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetProcessId.Addr(), uintptr(process)) id = uint32(r0) if id == 0 { err = errnoErr(e1) @@ -2530,7 +2585,7 @@ func GetProcessId(process Handle) (id uint32, err error) { } func getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetProcessPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetProcessPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2538,7 +2593,7 @@ func getProcessPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uin } func GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetProcessShutdownParameters.Addr(), 2, uintptr(unsafe.Pointer(level)), uintptr(unsafe.Pointer(flags)), 0) + r1, _, e1 := syscall.SyscallN(procGetProcessShutdownParameters.Addr(), uintptr(unsafe.Pointer(level)), uintptr(unsafe.Pointer(flags))) if r1 == 0 { err = errnoErr(e1) } @@ -2546,7 +2601,7 @@ func GetProcessShutdownParameters(level *uint32, flags *uint32) (err error) { } func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) + r1, _, e1 := syscall.SyscallN(procGetProcessTimes.Addr(), uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) if r1 == 0 { err = errnoErr(e1) } @@ -2554,12 +2609,12 @@ func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, } func GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) { - syscall.Syscall6(procGetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(unsafe.Pointer(lpMinimumWorkingSetSize)), uintptr(unsafe.Pointer(lpMaximumWorkingSetSize)), uintptr(unsafe.Pointer(flags)), 0, 0) + syscall.SyscallN(procGetProcessWorkingSetSizeEx.Addr(), uintptr(hProcess), uintptr(unsafe.Pointer(lpMinimumWorkingSetSize)), uintptr(unsafe.Pointer(lpMaximumWorkingSetSize)), uintptr(unsafe.Pointer(flags))) return } func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overlapped **Overlapped, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) + r1, _, e1 := syscall.SyscallN(procGetQueuedCompletionStatus.Addr(), uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout)) if r1 == 0 { err = errnoErr(e1) } @@ -2567,7 +2622,7 @@ func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uintptr, overl } func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) + r0, _, e1 := syscall.SyscallN(procGetShortPathNameW.Addr(), uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2576,12 +2631,12 @@ func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uin } func getStartupInfo(startupInfo *StartupInfo) { - syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0) + syscall.SyscallN(procGetStartupInfoW.Addr(), uintptr(unsafe.Pointer(startupInfo))) return } func GetStdHandle(stdhandle uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetStdHandle.Addr(), uintptr(stdhandle)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -2590,7 +2645,7 @@ func GetStdHandle(stdhandle uint32) (handle Handle, err error) { } func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetSystemDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + r0, _, e1 := syscall.SyscallN(procGetSystemDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) len = uint32(r0) if len == 0 { err = errnoErr(e1) @@ -2599,7 +2654,7 @@ func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { } func getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetSystemPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetSystemPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2607,17 +2662,17 @@ func getSystemPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint } func GetSystemTimeAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + syscall.SyscallN(procGetSystemTimeAsFileTime.Addr(), uintptr(unsafe.Pointer(time))) return } func GetSystemTimePreciseAsFileTime(time *Filetime) { - syscall.Syscall(procGetSystemTimePreciseAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0) + syscall.SyscallN(procGetSystemTimePreciseAsFileTime.Addr(), uintptr(unsafe.Pointer(time))) return } func getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetSystemWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + r0, _, e1 := syscall.SyscallN(procGetSystemWindowsDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) len = uint32(r0) if len == 0 { err = errnoErr(e1) @@ -2626,7 +2681,7 @@ func getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err erro } func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0) + r0, _, e1 := syscall.SyscallN(procGetTempPathW.Addr(), uintptr(buflen), uintptr(unsafe.Pointer(buf))) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2635,7 +2690,7 @@ func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) { } func getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetThreadPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetThreadPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2643,13 +2698,13 @@ func getThreadPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint } func getTickCount64() (ms uint64) { - r0, _, _ := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetTickCount64.Addr()) ms = uint64(r0) return } func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0) + r0, _, e1 := syscall.SyscallN(procGetTimeZoneInformation.Addr(), uintptr(unsafe.Pointer(tzi))) rc = uint32(r0) if rc == 0xffffffff { err = errnoErr(e1) @@ -2658,7 +2713,7 @@ func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) { } func getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetUserPreferredUILanguages.Addr(), 4, uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetUserPreferredUILanguages.Addr(), uintptr(flags), uintptr(unsafe.Pointer(numLanguages)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -2666,7 +2721,7 @@ func getUserPreferredUILanguages(flags uint32, numLanguages *uint32, buf *uint16 } func GetVersion() (ver uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0) + r0, _, e1 := syscall.SyscallN(procGetVersion.Addr()) ver = uint32(r0) if ver == 0 { err = errnoErr(e1) @@ -2675,7 +2730,7 @@ func GetVersion() (ver uint32, err error) { } func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetVolumeInformationByHandleW.Addr(), 8, uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + r1, _, e1 := syscall.SyscallN(procGetVolumeInformationByHandleW.Addr(), uintptr(file), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize)) if r1 == 0 { err = errnoErr(e1) } @@ -2683,7 +2738,7 @@ func GetVolumeInformationByHandle(file Handle, volumeNameBuffer *uint16, volumeN } func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize), 0) + r1, _, e1 := syscall.SyscallN(procGetVolumeInformationW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeNameBuffer)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeNameSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemNameBuffer)), uintptr(fileSystemNameSize)) if r1 == 0 { err = errnoErr(e1) } @@ -2691,7 +2746,7 @@ func GetVolumeInformation(rootPathName *uint16, volumeNameBuffer *uint16, volume } func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetVolumeNameForVolumeMountPointW.Addr(), 3, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) + r1, _, e1 := syscall.SyscallN(procGetVolumeNameForVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), uintptr(bufferlength)) if r1 == 0 { err = errnoErr(e1) } @@ -2699,7 +2754,7 @@ func GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint } func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetVolumePathNameW.Addr(), 3, uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) + r1, _, e1 := syscall.SyscallN(procGetVolumePathNameW.Addr(), uintptr(unsafe.Pointer(fileName)), uintptr(unsafe.Pointer(volumePathName)), uintptr(bufferLength)) if r1 == 0 { err = errnoErr(e1) } @@ -2707,7 +2762,7 @@ func GetVolumePathName(fileName *uint16, volumePathName *uint16, bufferLength ui } func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16, bufferLength uint32, returnLength *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetVolumePathNamesForVolumeNameW.Addr(), uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(volumePathNames)), uintptr(bufferLength), uintptr(unsafe.Pointer(returnLength))) if r1 == 0 { err = errnoErr(e1) } @@ -2715,7 +2770,7 @@ func GetVolumePathNamesForVolumeName(volumeName *uint16, volumePathNames *uint16 } func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetWindowsDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0) + r0, _, e1 := syscall.SyscallN(procGetWindowsDirectoryW.Addr(), uintptr(unsafe.Pointer(dir)), uintptr(dirLen)) len = uint32(r0) if len == 0 { err = errnoErr(e1) @@ -2724,7 +2779,7 @@ func getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { } func initializeProcThreadAttributeList(attrlist *ProcThreadAttributeList, attrcount uint32, flags uint32, size *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procInitializeProcThreadAttributeList.Addr(), 4, uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procInitializeProcThreadAttributeList.Addr(), uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size))) if r1 == 0 { err = errnoErr(e1) } @@ -2736,7 +2791,7 @@ func IsWow64Process(handle Handle, isWow64 *bool) (err error) { if *isWow64 { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procIsWow64Process.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(&_p0)), 0) + r1, _, e1 := syscall.SyscallN(procIsWow64Process.Addr(), uintptr(handle), uintptr(unsafe.Pointer(&_p0))) *isWow64 = _p0 != 0 if r1 == 0 { err = errnoErr(e1) @@ -2749,7 +2804,7 @@ func IsWow64Process2(handle Handle, processMachine *uint16, nativeMachine *uint1 if err != nil { return } - r1, _, e1 := syscall.Syscall(procIsWow64Process2.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(processMachine)), uintptr(unsafe.Pointer(nativeMachine))) + r1, _, e1 := syscall.SyscallN(procIsWow64Process2.Addr(), uintptr(handle), uintptr(unsafe.Pointer(processMachine)), uintptr(unsafe.Pointer(nativeMachine))) if r1 == 0 { err = errnoErr(e1) } @@ -2766,7 +2821,7 @@ func LoadLibraryEx(libname string, zero Handle, flags uintptr) (handle Handle, e } func _LoadLibraryEx(libname *uint16, zero Handle, flags uintptr) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryExW.Addr(), 3, uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) + r0, _, e1 := syscall.SyscallN(procLoadLibraryExW.Addr(), uintptr(unsafe.Pointer(libname)), uintptr(zero), uintptr(flags)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2784,7 +2839,7 @@ func LoadLibrary(libname string) (handle Handle, err error) { } func _LoadLibrary(libname *uint16) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0) + r0, _, e1 := syscall.SyscallN(procLoadLibraryW.Addr(), uintptr(unsafe.Pointer(libname))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2793,7 +2848,7 @@ func _LoadLibrary(libname *uint16) (handle Handle, err error) { } func LoadResource(module Handle, resInfo Handle) (resData Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0) + r0, _, e1 := syscall.SyscallN(procLoadResource.Addr(), uintptr(module), uintptr(resInfo)) resData = Handle(r0) if resData == 0 { err = errnoErr(e1) @@ -2802,7 +2857,7 @@ func LoadResource(module Handle, resInfo Handle) (resData Handle, err error) { } func LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) { - r0, _, e1 := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(length), 0) + r0, _, e1 := syscall.SyscallN(procLocalAlloc.Addr(), uintptr(flags), uintptr(length)) ptr = uintptr(r0) if ptr == 0 { err = errnoErr(e1) @@ -2811,7 +2866,7 @@ func LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) { } func LocalFree(hmem Handle) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0) + r0, _, e1 := syscall.SyscallN(procLocalFree.Addr(), uintptr(hmem)) handle = Handle(r0) if handle != 0 { err = errnoErr(e1) @@ -2820,7 +2875,7 @@ func LocalFree(hmem Handle) (handle Handle, err error) { } func LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) + r1, _, e1 := syscall.SyscallN(procLockFileEx.Addr(), uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -2828,7 +2883,7 @@ func LockFileEx(file Handle, flags uint32, reserved uint32, bytesLow uint32, byt } func LockResource(resData Handle) (addr uintptr, err error) { - r0, _, e1 := syscall.Syscall(procLockResource.Addr(), 1, uintptr(resData), 0, 0) + r0, _, e1 := syscall.SyscallN(procLockResource.Addr(), uintptr(resData)) addr = uintptr(r0) if addr == 0 { err = errnoErr(e1) @@ -2837,7 +2892,7 @@ func LockResource(resData Handle) (addr uintptr, err error) { } func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0) + r0, _, e1 := syscall.SyscallN(procMapViewOfFile.Addr(), uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length)) addr = uintptr(r0) if addr == 0 { err = errnoErr(e1) @@ -2846,7 +2901,7 @@ func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow ui } func Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procModule32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0) + r1, _, e1 := syscall.SyscallN(procModule32FirstW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2854,7 +2909,7 @@ func Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { } func Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procModule32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0) + r1, _, e1 := syscall.SyscallN(procModule32NextW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2862,7 +2917,7 @@ func Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) { } func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procMoveFileExW.Addr(), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -2870,7 +2925,7 @@ func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { } func MoveFile(from *uint16, to *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0) + r1, _, e1 := syscall.SyscallN(procMoveFileW.Addr(), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to))) if r1 == 0 { err = errnoErr(e1) } @@ -2878,7 +2933,7 @@ func MoveFile(from *uint16, to *uint16) (err error) { } func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { - r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) + r0, _, e1 := syscall.SyscallN(procMultiByteToWideChar.Addr(), uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) nwrite = int32(r0) if nwrite == 0 { err = errnoErr(e1) @@ -2891,7 +2946,7 @@ func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle H if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procOpenEventW.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2904,7 +2959,7 @@ func OpenMutex(desiredAccess uint32, inheritHandle bool, name *uint16) (handle H if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenMutexW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) + r0, _, e1 := syscall.SyscallN(procOpenMutexW.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name))) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2917,7 +2972,7 @@ func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) (ha if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(processId)) + r0, _, e1 := syscall.SyscallN(procOpenProcess.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(processId)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2930,7 +2985,7 @@ func OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (hand if inheritHandle { _p0 = 1 } - r0, _, e1 := syscall.Syscall(procOpenThread.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(threadId)) + r0, _, e1 := syscall.SyscallN(procOpenThread.Addr(), uintptr(desiredAccess), uintptr(_p0), uintptr(threadId)) handle = Handle(r0) if handle == 0 { err = errnoErr(e1) @@ -2939,7 +2994,7 @@ func OpenThread(desiredAccess uint32, inheritHandle bool, threadId uint32) (hand } func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0) + r1, _, e1 := syscall.SyscallN(procPostQueuedCompletionStatus.Addr(), uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -2947,7 +3002,7 @@ func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uintptr, overla } func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + r1, _, e1 := syscall.SyscallN(procProcess32FirstW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(procEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2955,7 +3010,7 @@ func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) { } func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0) + r1, _, e1 := syscall.SyscallN(procProcess32NextW.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(procEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -2963,7 +3018,7 @@ func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) { } func ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procProcessIdToSessionId.Addr(), 2, uintptr(pid), uintptr(unsafe.Pointer(sessionid)), 0) + r1, _, e1 := syscall.SyscallN(procProcessIdToSessionId.Addr(), uintptr(pid), uintptr(unsafe.Pointer(sessionid))) if r1 == 0 { err = errnoErr(e1) } @@ -2971,7 +3026,7 @@ func ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) { } func PulseEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0) + r1, _, e1 := syscall.SyscallN(procPulseEvent.Addr(), uintptr(event)) if r1 == 0 { err = errnoErr(e1) } @@ -2979,7 +3034,7 @@ func PulseEvent(event Handle) (err error) { } func PurgeComm(handle Handle, dwFlags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(dwFlags), 0) + r1, _, e1 := syscall.SyscallN(procPurgeComm.Addr(), uintptr(handle), uintptr(dwFlags)) if r1 == 0 { err = errnoErr(e1) } @@ -2987,7 +3042,7 @@ func PurgeComm(handle Handle, dwFlags uint32) (err error) { } func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procQueryDosDeviceW.Addr(), 3, uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) + r0, _, e1 := syscall.SyscallN(procQueryDosDeviceW.Addr(), uintptr(unsafe.Pointer(deviceName)), uintptr(unsafe.Pointer(targetPath)), uintptr(max)) n = uint32(r0) if n == 0 { err = errnoErr(e1) @@ -2996,7 +3051,7 @@ func QueryDosDevice(deviceName *uint16, targetPath *uint16, max uint32) (n uint3 } func QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryFullProcessImageNameW.Addr(), 4, uintptr(proc), uintptr(flags), uintptr(unsafe.Pointer(exeName)), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procQueryFullProcessImageNameW.Addr(), uintptr(proc), uintptr(flags), uintptr(unsafe.Pointer(exeName)), uintptr(unsafe.Pointer(size))) if r1 == 0 { err = errnoErr(e1) } @@ -3004,7 +3059,7 @@ func QueryFullProcessImageName(proc Handle, flags uint32, exeName *uint16, size } func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen)), 0) + r1, _, e1 := syscall.SyscallN(procQueryInformationJobObject.Addr(), uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen))) if r1 == 0 { err = errnoErr(e1) } @@ -3012,7 +3067,7 @@ func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobO } func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0) + r1, _, e1 := syscall.SyscallN(procReadConsoleW.Addr(), uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl))) if r1 == 0 { err = errnoErr(e1) } @@ -3024,7 +3079,7 @@ func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree if watchSubTree { _p0 = 1 } - r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0) + r1, _, e1 := syscall.SyscallN(procReadDirectoryChangesW.Addr(), uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) if r1 == 0 { err = errnoErr(e1) } @@ -3036,7 +3091,7 @@ func readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) ( if len(buf) > 0 { _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procReadFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3044,7 +3099,7 @@ func readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) ( } func ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesRead *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesRead)), 0) + r1, _, e1 := syscall.SyscallN(procReadProcessMemory.Addr(), uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesRead))) if r1 == 0 { err = errnoErr(e1) } @@ -3052,7 +3107,7 @@ func ReadProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size u } func ReleaseMutex(mutex Handle) (err error) { - r1, _, e1 := syscall.Syscall(procReleaseMutex.Addr(), 1, uintptr(mutex), 0, 0) + r1, _, e1 := syscall.SyscallN(procReleaseMutex.Addr(), uintptr(mutex)) if r1 == 0 { err = errnoErr(e1) } @@ -3060,7 +3115,7 @@ func ReleaseMutex(mutex Handle) (err error) { } func RemoveDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procRemoveDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -3068,7 +3123,7 @@ func RemoveDirectory(path *uint16) (err error) { } func RemoveDllDirectory(cookie uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procRemoveDllDirectory.Addr(), 1, uintptr(cookie), 0, 0) + r1, _, e1 := syscall.SyscallN(procRemoveDllDirectory.Addr(), uintptr(cookie)) if r1 == 0 { err = errnoErr(e1) } @@ -3076,7 +3131,7 @@ func RemoveDllDirectory(cookie uintptr) (err error) { } func ResetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0) + r1, _, e1 := syscall.SyscallN(procResetEvent.Addr(), uintptr(event)) if r1 == 0 { err = errnoErr(e1) } @@ -3084,7 +3139,7 @@ func ResetEvent(event Handle) (err error) { } func resizePseudoConsole(pconsole Handle, size uint32) (hr error) { - r0, _, _ := syscall.Syscall(procResizePseudoConsole.Addr(), 2, uintptr(pconsole), uintptr(size), 0) + r0, _, _ := syscall.SyscallN(procResizePseudoConsole.Addr(), uintptr(pconsole), uintptr(size)) if r0 != 0 { hr = syscall.Errno(r0) } @@ -3092,7 +3147,7 @@ func resizePseudoConsole(pconsole Handle, size uint32) (hr error) { } func ResumeThread(thread Handle) (ret uint32, err error) { - r0, _, e1 := syscall.Syscall(procResumeThread.Addr(), 1, uintptr(thread), 0, 0) + r0, _, e1 := syscall.SyscallN(procResumeThread.Addr(), uintptr(thread)) ret = uint32(r0) if ret == 0xffffffff { err = errnoErr(e1) @@ -3101,7 +3156,7 @@ func ResumeThread(thread Handle) (ret uint32, err error) { } func SetCommBreak(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetCommBreak.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -3109,7 +3164,7 @@ func SetCommBreak(handle Handle) (err error) { } func SetCommMask(handle Handle, dwEvtMask uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommMask.Addr(), 2, uintptr(handle), uintptr(dwEvtMask), 0) + r1, _, e1 := syscall.SyscallN(procSetCommMask.Addr(), uintptr(handle), uintptr(dwEvtMask)) if r1 == 0 { err = errnoErr(e1) } @@ -3117,7 +3172,7 @@ func SetCommMask(handle Handle, dwEvtMask uint32) (err error) { } func SetCommState(handle Handle, lpDCB *DCB) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(lpDCB)), 0) + r1, _, e1 := syscall.SyscallN(procSetCommState.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpDCB))) if r1 == 0 { err = errnoErr(e1) } @@ -3125,7 +3180,7 @@ func SetCommState(handle Handle, lpDCB *DCB) (err error) { } func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { - r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) + r1, _, e1 := syscall.SyscallN(procSetCommTimeouts.Addr(), uintptr(handle), uintptr(unsafe.Pointer(timeouts))) if r1 == 0 { err = errnoErr(e1) } @@ -3133,7 +3188,7 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { } func SetConsoleCP(cp uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleCP.Addr(), uintptr(cp)) if r1 == 0 { err = errnoErr(e1) } @@ -3141,7 +3196,7 @@ func SetConsoleCP(cp uint32) (err error) { } func setConsoleCursorPosition(console Handle, position uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleCursorPosition.Addr(), uintptr(console), uintptr(position)) if r1 == 0 { err = errnoErr(e1) } @@ -3149,7 +3204,7 @@ func setConsoleCursorPosition(console Handle, position uint32) (err error) { } func SetConsoleMode(console Handle, mode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleMode.Addr(), uintptr(console), uintptr(mode)) if r1 == 0 { err = errnoErr(e1) } @@ -3157,7 +3212,7 @@ func SetConsoleMode(console Handle, mode uint32) (err error) { } func SetConsoleOutputCP(cp uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetConsoleOutputCP.Addr(), uintptr(cp)) if r1 == 0 { err = errnoErr(e1) } @@ -3165,7 +3220,7 @@ func SetConsoleOutputCP(cp uint32) (err error) { } func SetCurrentDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetCurrentDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -3173,7 +3228,7 @@ func SetCurrentDirectory(path *uint16) (err error) { } func SetDefaultDllDirectories(directoryFlags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetDefaultDllDirectories.Addr(), 1, uintptr(directoryFlags), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetDefaultDllDirectories.Addr(), uintptr(directoryFlags)) if r1 == 0 { err = errnoErr(e1) } @@ -3190,7 +3245,7 @@ func SetDllDirectory(path string) (err error) { } func _SetDllDirectory(path *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetDllDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetDllDirectoryW.Addr(), uintptr(unsafe.Pointer(path))) if r1 == 0 { err = errnoErr(e1) } @@ -3198,7 +3253,7 @@ func _SetDllDirectory(path *uint16) (err error) { } func SetEndOfFile(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetEndOfFile.Addr(), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -3206,7 +3261,7 @@ func SetEndOfFile(handle Handle) (err error) { } func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) + r1, _, e1 := syscall.SyscallN(procSetEnvironmentVariableW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value))) if r1 == 0 { err = errnoErr(e1) } @@ -3214,13 +3269,13 @@ func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { } func SetErrorMode(mode uint32) (ret uint32) { - r0, _, _ := syscall.Syscall(procSetErrorMode.Addr(), 1, uintptr(mode), 0, 0) + r0, _, _ := syscall.SyscallN(procSetErrorMode.Addr(), uintptr(mode)) ret = uint32(r0) return } func SetEvent(event Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetEvent.Addr(), uintptr(event)) if r1 == 0 { err = errnoErr(e1) } @@ -3228,7 +3283,7 @@ func SetEvent(event Handle) (err error) { } func SetFileAttributes(name *uint16, attrs uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0) + r1, _, e1 := syscall.SyscallN(procSetFileAttributesW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(attrs)) if r1 == 0 { err = errnoErr(e1) } @@ -3236,7 +3291,7 @@ func SetFileAttributes(name *uint16, attrs uint32) (err error) { } func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procSetFileCompletionNotificationModes.Addr(), uintptr(handle), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3244,7 +3299,7 @@ func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) } func SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inBufferLen uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetFileInformationByHandle.Addr(), uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen)) if r1 == 0 { err = errnoErr(e1) } @@ -3252,7 +3307,7 @@ func SetFileInformationByHandle(handle Handle, class uint32, inBuffer *byte, inB } func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) { - r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetFilePointer.Addr(), uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence)) newlowoffset = uint32(r0) if newlowoffset == 0xffffffff { err = errnoErr(e1) @@ -3261,7 +3316,7 @@ func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence } func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetFileTime.Addr(), uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime))) if r1 == 0 { err = errnoErr(e1) } @@ -3269,7 +3324,7 @@ func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetim } func SetFileValidData(handle Handle, validDataLength int64) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + r1, _, e1 := syscall.SyscallN(procSetFileValidData.Addr(), uintptr(handle), uintptr(validDataLength)) if r1 == 0 { err = errnoErr(e1) } @@ -3277,7 +3332,7 @@ func SetFileValidData(handle Handle, validDataLength int64) (err error) { } func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags)) + r1, _, e1 := syscall.SyscallN(procSetHandleInformation.Addr(), uintptr(handle), uintptr(mask), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3285,7 +3340,7 @@ func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) } func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) { - r0, _, e1 := syscall.Syscall6(procSetInformationJobObject.Addr(), 4, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetInformationJobObject.Addr(), uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength)) ret = int(r0) if ret == 0 { err = errnoErr(e1) @@ -3294,7 +3349,7 @@ func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobOb } func SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetNamedPipeHandleState.Addr(), 4, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetNamedPipeHandleState.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout))) if r1 == 0 { err = errnoErr(e1) } @@ -3302,7 +3357,7 @@ func SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uin } func SetPriorityClass(process Handle, priorityClass uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetPriorityClass.Addr(), 2, uintptr(process), uintptr(priorityClass), 0) + r1, _, e1 := syscall.SyscallN(procSetPriorityClass.Addr(), uintptr(process), uintptr(priorityClass)) if r1 == 0 { err = errnoErr(e1) } @@ -3314,7 +3369,7 @@ func SetProcessPriorityBoost(process Handle, disable bool) (err error) { if disable { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procSetProcessPriorityBoost.Addr(), 2, uintptr(process), uintptr(_p0), 0) + r1, _, e1 := syscall.SyscallN(procSetProcessPriorityBoost.Addr(), uintptr(process), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -3322,7 +3377,7 @@ func SetProcessPriorityBoost(process Handle, disable bool) (err error) { } func SetProcessShutdownParameters(level uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetProcessShutdownParameters.Addr(), 2, uintptr(level), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procSetProcessShutdownParameters.Addr(), uintptr(level), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3330,7 +3385,7 @@ func SetProcessShutdownParameters(level uint32, flags uint32) (err error) { } func SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetProcessWorkingSetSizeEx.Addr(), 4, uintptr(hProcess), uintptr(dwMinimumWorkingSetSize), uintptr(dwMaximumWorkingSetSize), uintptr(flags), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetProcessWorkingSetSizeEx.Addr(), uintptr(hProcess), uintptr(dwMinimumWorkingSetSize), uintptr(dwMaximumWorkingSetSize), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3338,7 +3393,7 @@ func SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr } func SetStdHandle(stdhandle uint32, handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0) + r1, _, e1 := syscall.SyscallN(procSetStdHandle.Addr(), uintptr(stdhandle), uintptr(handle)) if r1 == 0 { err = errnoErr(e1) } @@ -3346,7 +3401,7 @@ func SetStdHandle(stdhandle uint32, handle Handle) (err error) { } func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeLabelW.Addr(), 2, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), 0) + r1, _, e1 := syscall.SyscallN(procSetVolumeLabelW.Addr(), uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName))) if r1 == 0 { err = errnoErr(e1) } @@ -3354,7 +3409,7 @@ func SetVolumeLabel(rootPathName *uint16, volumeName *uint16) (err error) { } func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procSetVolumeMountPointW.Addr(), 2, uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName)), 0) + r1, _, e1 := syscall.SyscallN(procSetVolumeMountPointW.Addr(), uintptr(unsafe.Pointer(volumeMountPoint)), uintptr(unsafe.Pointer(volumeName))) if r1 == 0 { err = errnoErr(e1) } @@ -3362,7 +3417,7 @@ func SetVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16) (err erro } func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) { - r1, _, e1 := syscall.Syscall(procSetupComm.Addr(), 3, uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue)) + r1, _, e1 := syscall.SyscallN(procSetupComm.Addr(), uintptr(handle), uintptr(dwInQueue), uintptr(dwOutQueue)) if r1 == 0 { err = errnoErr(e1) } @@ -3370,7 +3425,7 @@ func SetupComm(handle Handle, dwInQueue uint32, dwOutQueue uint32) (err error) { } func SizeofResource(module Handle, resInfo Handle) (size uint32, err error) { - r0, _, e1 := syscall.Syscall(procSizeofResource.Addr(), 2, uintptr(module), uintptr(resInfo), 0) + r0, _, e1 := syscall.SyscallN(procSizeofResource.Addr(), uintptr(module), uintptr(resInfo)) size = uint32(r0) if size == 0 { err = errnoErr(e1) @@ -3383,13 +3438,13 @@ func SleepEx(milliseconds uint32, alertable bool) (ret uint32) { if alertable { _p0 = 1 } - r0, _, _ := syscall.Syscall(procSleepEx.Addr(), 2, uintptr(milliseconds), uintptr(_p0), 0) + r0, _, _ := syscall.SyscallN(procSleepEx.Addr(), uintptr(milliseconds), uintptr(_p0)) ret = uint32(r0) return } func TerminateJobObject(job Handle, exitCode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procTerminateJobObject.Addr(), 2, uintptr(job), uintptr(exitCode), 0) + r1, _, e1 := syscall.SyscallN(procTerminateJobObject.Addr(), uintptr(job), uintptr(exitCode)) if r1 == 0 { err = errnoErr(e1) } @@ -3397,7 +3452,7 @@ func TerminateJobObject(job Handle, exitCode uint32) (err error) { } func TerminateProcess(handle Handle, exitcode uint32) (err error) { - r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0) + r1, _, e1 := syscall.SyscallN(procTerminateProcess.Addr(), uintptr(handle), uintptr(exitcode)) if r1 == 0 { err = errnoErr(e1) } @@ -3405,7 +3460,7 @@ func TerminateProcess(handle Handle, exitcode uint32) (err error) { } func Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procThread32First.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) + r1, _, e1 := syscall.SyscallN(procThread32First.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -3413,7 +3468,7 @@ func Thread32First(snapshot Handle, threadEntry *ThreadEntry32) (err error) { } func Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) { - r1, _, e1 := syscall.Syscall(procThread32Next.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry)), 0) + r1, _, e1 := syscall.SyscallN(procThread32Next.Addr(), uintptr(snapshot), uintptr(unsafe.Pointer(threadEntry))) if r1 == 0 { err = errnoErr(e1) } @@ -3421,7 +3476,7 @@ func Thread32Next(snapshot Handle, threadEntry *ThreadEntry32) (err error) { } func UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procUnlockFileEx.Addr(), uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3429,7 +3484,7 @@ func UnlockFileEx(file Handle, reserved uint32, bytesLow uint32, bytesHigh uint3 } func UnmapViewOfFile(addr uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0) + r1, _, e1 := syscall.SyscallN(procUnmapViewOfFile.Addr(), uintptr(addr)) if r1 == 0 { err = errnoErr(e1) } @@ -3437,7 +3492,7 @@ func UnmapViewOfFile(addr uintptr) (err error) { } func updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procUpdateProcThreadAttribute.Addr(), 7, uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procUpdateProcThreadAttribute.Addr(), uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize))) if r1 == 0 { err = errnoErr(e1) } @@ -3445,7 +3500,7 @@ func updateProcThreadAttribute(attrlist *ProcThreadAttributeList, flags uint32, } func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint32) (value uintptr, err error) { - r0, _, e1 := syscall.Syscall6(procVirtualAlloc.Addr(), 4, uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect), 0, 0) + r0, _, e1 := syscall.SyscallN(procVirtualAlloc.Addr(), uintptr(address), uintptr(size), uintptr(alloctype), uintptr(protect)) value = uintptr(r0) if value == 0 { err = errnoErr(e1) @@ -3454,7 +3509,7 @@ func VirtualAlloc(address uintptr, size uintptr, alloctype uint32, protect uint3 } func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualFree.Addr(), 3, uintptr(address), uintptr(size), uintptr(freetype)) + r1, _, e1 := syscall.SyscallN(procVirtualFree.Addr(), uintptr(address), uintptr(size), uintptr(freetype)) if r1 == 0 { err = errnoErr(e1) } @@ -3462,7 +3517,7 @@ func VirtualFree(address uintptr, size uintptr, freetype uint32) (err error) { } func VirtualLock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0) + r1, _, e1 := syscall.SyscallN(procVirtualLock.Addr(), uintptr(addr), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3470,7 +3525,7 @@ func VirtualLock(addr uintptr, length uintptr) (err error) { } func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualProtect.Addr(), 4, uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect)), 0, 0) + r1, _, e1 := syscall.SyscallN(procVirtualProtect.Addr(), uintptr(address), uintptr(size), uintptr(newprotect), uintptr(unsafe.Pointer(oldprotect))) if r1 == 0 { err = errnoErr(e1) } @@ -3478,7 +3533,7 @@ func VirtualProtect(address uintptr, size uintptr, newprotect uint32, oldprotect } func VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect uint32, oldProtect *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualProtectEx.Addr(), 5, uintptr(process), uintptr(address), uintptr(size), uintptr(newProtect), uintptr(unsafe.Pointer(oldProtect)), 0) + r1, _, e1 := syscall.SyscallN(procVirtualProtectEx.Addr(), uintptr(process), uintptr(address), uintptr(size), uintptr(newProtect), uintptr(unsafe.Pointer(oldProtect))) if r1 == 0 { err = errnoErr(e1) } @@ -3486,7 +3541,7 @@ func VirtualProtectEx(process Handle, address uintptr, size uintptr, newProtect } func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualQuery.Addr(), 3, uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) + r1, _, e1 := syscall.SyscallN(procVirtualQuery.Addr(), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3494,7 +3549,7 @@ func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintpt } func VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procVirtualQueryEx.Addr(), 4, uintptr(process), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length), 0, 0) + r1, _, e1 := syscall.SyscallN(procVirtualQueryEx.Addr(), uintptr(process), uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3502,7 +3557,7 @@ func VirtualQueryEx(process Handle, address uintptr, buffer *MemoryBasicInformat } func VirtualUnlock(addr uintptr, length uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0) + r1, _, e1 := syscall.SyscallN(procVirtualUnlock.Addr(), uintptr(addr), uintptr(length)) if r1 == 0 { err = errnoErr(e1) } @@ -3510,13 +3565,13 @@ func VirtualUnlock(addr uintptr, length uintptr) (err error) { } func WTSGetActiveConsoleSessionId() (sessionID uint32) { - r0, _, _ := syscall.Syscall(procWTSGetActiveConsoleSessionId.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procWTSGetActiveConsoleSessionId.Addr()) sessionID = uint32(r0) return } func WaitCommEvent(handle Handle, lpEvtMask *uint32, lpOverlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procWaitCommEvent.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped))) + r1, _, e1 := syscall.SyscallN(procWaitCommEvent.Addr(), uintptr(handle), uintptr(unsafe.Pointer(lpEvtMask)), uintptr(unsafe.Pointer(lpOverlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3528,7 +3583,7 @@ func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMil if waitAll { _p0 = 1 } - r0, _, e1 := syscall.Syscall6(procWaitForMultipleObjects.Addr(), 4, uintptr(count), uintptr(handles), uintptr(_p0), uintptr(waitMilliseconds), 0, 0) + r0, _, e1 := syscall.SyscallN(procWaitForMultipleObjects.Addr(), uintptr(count), uintptr(handles), uintptr(_p0), uintptr(waitMilliseconds)) event = uint32(r0) if event == 0xffffffff { err = errnoErr(e1) @@ -3537,7 +3592,7 @@ func waitForMultipleObjects(count uint32, handles uintptr, waitAll bool, waitMil } func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) { - r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0) + r0, _, e1 := syscall.SyscallN(procWaitForSingleObject.Addr(), uintptr(handle), uintptr(waitMilliseconds)) event = uint32(r0) if event == 0xffffffff { err = errnoErr(e1) @@ -3546,7 +3601,7 @@ func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, } func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) { - r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0) + r1, _, e1 := syscall.SyscallN(procWriteConsoleW.Addr(), uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved))) if r1 == 0 { err = errnoErr(e1) } @@ -3558,7 +3613,7 @@ func writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) if len(buf) > 0 { _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procWriteFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3566,7 +3621,7 @@ func writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) } func WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size uintptr, numberOfBytesWritten *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procWriteProcessMemory.Addr(), 5, uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesWritten)), 0) + r1, _, e1 := syscall.SyscallN(procWriteProcessMemory.Addr(), uintptr(process), uintptr(baseAddress), uintptr(unsafe.Pointer(buffer)), uintptr(size), uintptr(unsafe.Pointer(numberOfBytesWritten))) if r1 == 0 { err = errnoErr(e1) } @@ -3574,7 +3629,7 @@ func WriteProcessMemory(process Handle, baseAddress uintptr, buffer *byte, size } func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) { - r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0) + r1, _, e1 := syscall.SyscallN(procAcceptEx.Addr(), uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { err = errnoErr(e1) } @@ -3582,12 +3637,12 @@ func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32 } func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) { - syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0) + syscall.SyscallN(procGetAcceptExSockaddrs.Addr(), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen))) return } func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0) + r1, _, e1 := syscall.SyscallN(procTransmitFile.Addr(), uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -3595,7 +3650,7 @@ func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint } func NetApiBufferFree(buf *byte) (neterr error) { - r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0) + r0, _, _ := syscall.SyscallN(procNetApiBufferFree.Addr(), uintptr(unsafe.Pointer(buf))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3603,7 +3658,7 @@ func NetApiBufferFree(buf *byte) (neterr error) { } func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) { - r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) + r0, _, _ := syscall.SyscallN(procNetGetJoinInformation.Addr(), uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3611,7 +3666,7 @@ func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (nete } func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) { - r0, _, _ := syscall.Syscall9(procNetUserEnum.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle)), 0) + r0, _, _ := syscall.SyscallN(procNetUserEnum.Addr(), uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3619,7 +3674,7 @@ func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, pr } func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) { - r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0) + r0, _, _ := syscall.SyscallN(procNetUserGetInfo.Addr(), uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf))) if r0 != 0 { neterr = syscall.Errno(r0) } @@ -3627,7 +3682,7 @@ func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **by } func NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(attributes), uintptr(share), uintptr(disposition), uintptr(options), uintptr(eabuffer), uintptr(ealength), 0) + r0, _, _ := syscall.SyscallN(procNtCreateFile.Addr(), uintptr(unsafe.Pointer(handle)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(attributes), uintptr(share), uintptr(disposition), uintptr(options), uintptr(eabuffer), uintptr(ealength)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3635,7 +3690,7 @@ func NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO } func NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) { - r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0) + r0, _, _ := syscall.SyscallN(procNtCreateNamedPipeFile.Addr(), uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3643,7 +3698,7 @@ func NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, i } func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), uintptr(unsafe.Pointer(retLen)), 0) + r0, _, _ := syscall.SyscallN(procNtQueryInformationProcess.Addr(), uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), uintptr(unsafe.Pointer(retLen))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3651,7 +3706,7 @@ func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe } func NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen), uintptr(unsafe.Pointer(retLen)), 0, 0) + r0, _, _ := syscall.SyscallN(procNtQuerySystemInformation.Addr(), uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen), uintptr(unsafe.Pointer(retLen))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3659,7 +3714,7 @@ func NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInf } func NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), uintptr(class), 0) + r0, _, _ := syscall.SyscallN(procNtSetInformationFile.Addr(), uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), uintptr(class)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3667,7 +3722,7 @@ func NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, } func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procNtSetInformationProcess.Addr(), 4, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), 0, 0) + r0, _, _ := syscall.SyscallN(procNtSetInformationProcess.Addr(), uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3675,7 +3730,7 @@ func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.P } func NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) { - r0, _, _ := syscall.Syscall(procNtSetSystemInformation.Addr(), 3, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen)) + r0, _, _ := syscall.SyscallN(procNtSetSystemInformation.Addr(), uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen)) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3683,13 +3738,13 @@ func NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoL } func RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) { - r0, _, _ := syscall.Syscall(procRtlAddFunctionTable.Addr(), 3, uintptr(unsafe.Pointer(functionTable)), uintptr(entryCount), uintptr(baseAddress)) + r0, _, _ := syscall.SyscallN(procRtlAddFunctionTable.Addr(), uintptr(unsafe.Pointer(functionTable)), uintptr(entryCount), uintptr(baseAddress)) ret = r0 != 0 return } func RtlDefaultNpAcl(acl **ACL) (ntstatus error) { - r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(acl)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDefaultNpAcl.Addr(), uintptr(unsafe.Pointer(acl))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3697,13 +3752,13 @@ func RtlDefaultNpAcl(acl **ACL) (ntstatus error) { } func RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) { - r0, _, _ := syscall.Syscall(procRtlDeleteFunctionTable.Addr(), 1, uintptr(unsafe.Pointer(functionTable)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDeleteFunctionTable.Addr(), uintptr(unsafe.Pointer(functionTable))) ret = r0 != 0 return } func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3711,7 +3766,7 @@ func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFile } func RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) { - r0, _, _ := syscall.Syscall6(procRtlDosPathNameToRelativeNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDosPathNameToRelativeNtPathName_U_WithStatus.Addr(), uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3719,18 +3774,18 @@ func RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString } func RtlGetCurrentPeb() (peb *PEB) { - r0, _, _ := syscall.Syscall(procRtlGetCurrentPeb.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procRtlGetCurrentPeb.Addr()) peb = (*PEB)(unsafe.Pointer(r0)) return } func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { - syscall.Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber))) + syscall.SyscallN(procRtlGetNtVersionNumbers.Addr(), uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber))) return } func rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) { - r0, _, _ := syscall.Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlGetVersion.Addr(), uintptr(unsafe.Pointer(info))) if r0 != 0 { ntstatus = NTStatus(r0) } @@ -3738,23 +3793,23 @@ func rtlGetVersion(info *OsVersionInfoEx) (ntstatus error) { } func RtlInitString(destinationString *NTString, sourceString *byte) { - syscall.Syscall(procRtlInitString.Addr(), 2, uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString)), 0) + syscall.SyscallN(procRtlInitString.Addr(), uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString))) return } func RtlInitUnicodeString(destinationString *NTUnicodeString, sourceString *uint16) { - syscall.Syscall(procRtlInitUnicodeString.Addr(), 2, uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString)), 0) + syscall.SyscallN(procRtlInitUnicodeString.Addr(), uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString))) return } func rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) { - r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(ntstatus), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlNtStatusToDosErrorNoTeb.Addr(), uintptr(ntstatus)) ret = syscall.Errno(r0) return } func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) { - r0, _, _ := syscall.Syscall(procCLSIDFromString.Addr(), 2, uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid)), 0) + r0, _, _ := syscall.SyscallN(procCLSIDFromString.Addr(), uintptr(unsafe.Pointer(lpsz)), uintptr(unsafe.Pointer(pclsid))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3762,7 +3817,7 @@ func clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) { } func coCreateGuid(pguid *GUID) (ret error) { - r0, _, _ := syscall.Syscall(procCoCreateGuid.Addr(), 1, uintptr(unsafe.Pointer(pguid)), 0, 0) + r0, _, _ := syscall.SyscallN(procCoCreateGuid.Addr(), uintptr(unsafe.Pointer(pguid))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3770,7 +3825,7 @@ func coCreateGuid(pguid *GUID) (ret error) { } func CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable **uintptr) (ret error) { - r0, _, _ := syscall.Syscall6(procCoGetObject.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bindOpts)), uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(functionTable)), 0, 0) + r0, _, _ := syscall.SyscallN(procCoGetObject.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bindOpts)), uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(functionTable))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3778,7 +3833,7 @@ func CoGetObject(name *uint16, bindOpts *BIND_OPTS3, guid *GUID, functionTable * } func CoInitializeEx(reserved uintptr, coInit uint32) (ret error) { - r0, _, _ := syscall.Syscall(procCoInitializeEx.Addr(), 2, uintptr(reserved), uintptr(coInit), 0) + r0, _, _ := syscall.SyscallN(procCoInitializeEx.Addr(), uintptr(reserved), uintptr(coInit)) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3786,23 +3841,23 @@ func CoInitializeEx(reserved uintptr, coInit uint32) (ret error) { } func CoTaskMemFree(address unsafe.Pointer) { - syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(address), 0, 0) + syscall.SyscallN(procCoTaskMemFree.Addr(), uintptr(address)) return } func CoUninitialize() { - syscall.Syscall(procCoUninitialize.Addr(), 0, 0, 0, 0) + syscall.SyscallN(procCoUninitialize.Addr()) return } func stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) { - r0, _, _ := syscall.Syscall(procStringFromGUID2.Addr(), 3, uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax)) + r0, _, _ := syscall.SyscallN(procStringFromGUID2.Addr(), uintptr(unsafe.Pointer(rguid)), uintptr(unsafe.Pointer(lpsz)), uintptr(cchMax)) chars = int32(r0) return } func EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procEnumProcessModules.Addr(), 4, uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded)), 0, 0) + r1, _, e1 := syscall.SyscallN(procEnumProcessModules.Addr(), uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded))) if r1 == 0 { err = errnoErr(e1) } @@ -3810,7 +3865,7 @@ func EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uin } func EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *uint32, filterFlag uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procEnumProcessModulesEx.Addr(), 5, uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded)), uintptr(filterFlag), 0) + r1, _, e1 := syscall.SyscallN(procEnumProcessModulesEx.Addr(), uintptr(process), uintptr(unsafe.Pointer(module)), uintptr(cb), uintptr(unsafe.Pointer(cbNeeded)), uintptr(filterFlag)) if r1 == 0 { err = errnoErr(e1) } @@ -3818,7 +3873,7 @@ func EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *u } func enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(nSize), uintptr(unsafe.Pointer(bytesReturned))) + r1, _, e1 := syscall.SyscallN(procEnumProcesses.Addr(), uintptr(unsafe.Pointer(processIds)), uintptr(nSize), uintptr(unsafe.Pointer(bytesReturned))) if r1 == 0 { err = errnoErr(e1) } @@ -3826,7 +3881,7 @@ func enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err } func GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetModuleBaseNameW.Addr(), 4, uintptr(process), uintptr(module), uintptr(unsafe.Pointer(baseName)), uintptr(size), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetModuleBaseNameW.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(baseName)), uintptr(size)) if r1 == 0 { err = errnoErr(e1) } @@ -3834,7 +3889,7 @@ func GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uin } func GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetModuleFileNameExW.Addr(), 4, uintptr(process), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetModuleFileNameExW.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(filename)), uintptr(size)) if r1 == 0 { err = errnoErr(e1) } @@ -3842,7 +3897,7 @@ func GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size u } func GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetModuleInformation.Addr(), 4, uintptr(process), uintptr(module), uintptr(unsafe.Pointer(modinfo)), uintptr(cb), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetModuleInformation.Addr(), uintptr(process), uintptr(module), uintptr(unsafe.Pointer(modinfo)), uintptr(cb)) if r1 == 0 { err = errnoErr(e1) } @@ -3850,7 +3905,7 @@ func GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb } func QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) { - r1, _, e1 := syscall.Syscall(procQueryWorkingSetEx.Addr(), 3, uintptr(process), uintptr(pv), uintptr(cb)) + r1, _, e1 := syscall.SyscallN(procQueryWorkingSetEx.Addr(), uintptr(process), uintptr(pv), uintptr(cb)) if r1 == 0 { err = errnoErr(e1) } @@ -3862,7 +3917,7 @@ func SubscribeServiceChangeNotifications(service Handle, eventType uint32, callb if ret != nil { return } - r0, _, _ := syscall.Syscall6(procSubscribeServiceChangeNotifications.Addr(), 5, uintptr(service), uintptr(eventType), uintptr(callback), uintptr(callbackCtx), uintptr(unsafe.Pointer(subscription)), 0) + r0, _, _ := syscall.SyscallN(procSubscribeServiceChangeNotifications.Addr(), uintptr(service), uintptr(eventType), uintptr(callback), uintptr(callbackCtx), uintptr(unsafe.Pointer(subscription))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -3874,12 +3929,12 @@ func UnsubscribeServiceChangeNotifications(subscription uintptr) (err error) { if err != nil { return } - syscall.Syscall(procUnsubscribeServiceChangeNotifications.Addr(), 1, uintptr(subscription), 0, 0) + syscall.SyscallN(procUnsubscribeServiceChangeNotifications.Addr(), uintptr(subscription)) return } func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) + r1, _, e1 := syscall.SyscallN(procGetUserNameExW.Addr(), uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize))) if r1&0xff == 0 { err = errnoErr(e1) } @@ -3887,7 +3942,7 @@ func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err er } func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0) + r1, _, e1 := syscall.SyscallN(procTranslateNameW.Addr(), uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize))) if r1&0xff == 0 { err = errnoErr(e1) } @@ -3895,7 +3950,7 @@ func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint } func SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiBuildDriverInfoList.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) + r1, _, e1 := syscall.SyscallN(procSetupDiBuildDriverInfoList.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) if r1 == 0 { err = errnoErr(e1) } @@ -3903,7 +3958,7 @@ func SetupDiBuildDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa } func SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiCallClassInstaller.Addr(), 3, uintptr(installFunction), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiCallClassInstaller.Addr(), uintptr(installFunction), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3911,7 +3966,7 @@ func SetupDiCallClassInstaller(installFunction DI_FUNCTION, deviceInfoSet DevInf } func SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiCancelDriverInfoSearch.Addr(), 1, uintptr(deviceInfoSet), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiCancelDriverInfoSearch.Addr(), uintptr(deviceInfoSet)) if r1 == 0 { err = errnoErr(e1) } @@ -3919,7 +3974,7 @@ func SetupDiCancelDriverInfoSearch(deviceInfoSet DevInfo) (err error) { } func setupDiClassGuidsFromNameEx(className *uint16, classGuidList *GUID, classGuidListSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiClassGuidsFromNameExW.Addr(), 6, uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(classGuidList)), uintptr(classGuidListSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procSetupDiClassGuidsFromNameExW.Addr(), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(classGuidList)), uintptr(classGuidListSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) if r1 == 0 { err = errnoErr(e1) } @@ -3927,7 +3982,7 @@ func setupDiClassGuidsFromNameEx(className *uint16, classGuidList *GUID, classGu } func setupDiClassNameFromGuidEx(classGUID *GUID, className *uint16, classNameSize uint32, requiredSize *uint32, machineName *uint16, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiClassNameFromGuidExW.Addr(), 6, uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(className)), uintptr(classNameSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procSetupDiClassNameFromGuidExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(className)), uintptr(classNameSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) if r1 == 0 { err = errnoErr(e1) } @@ -3935,7 +3990,7 @@ func setupDiClassNameFromGuidEx(classGUID *GUID, className *uint16, classNameSiz } func setupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiCreateDeviceInfoListExW.Addr(), 4, uintptr(unsafe.Pointer(classGUID)), uintptr(hwndParent), uintptr(unsafe.Pointer(machineName)), uintptr(reserved), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetupDiCreateDeviceInfoListExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(hwndParent), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) handle = DevInfo(r0) if handle == DevInfo(InvalidHandle) { err = errnoErr(e1) @@ -3944,7 +3999,7 @@ func setupDiCreateDeviceInfoListEx(classGUID *GUID, hwndParent uintptr, machineN } func setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUID *GUID, DeviceDescription *uint16, hwndParent uintptr, CreationFlags DICD, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiCreateDeviceInfoW.Addr(), 7, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(DeviceName)), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(DeviceDescription)), uintptr(hwndParent), uintptr(CreationFlags), uintptr(unsafe.Pointer(deviceInfoData)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiCreateDeviceInfoW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(DeviceName)), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(DeviceDescription)), uintptr(hwndParent), uintptr(CreationFlags), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3952,7 +4007,7 @@ func setupDiCreateDeviceInfo(deviceInfoSet DevInfo, DeviceName *uint16, classGUI } func SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiDestroyDeviceInfoList.Addr(), 1, uintptr(deviceInfoSet), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiDestroyDeviceInfoList.Addr(), uintptr(deviceInfoSet)) if r1 == 0 { err = errnoErr(e1) } @@ -3960,7 +4015,7 @@ func SetupDiDestroyDeviceInfoList(deviceInfoSet DevInfo) (err error) { } func SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiDestroyDriverInfoList.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) + r1, _, e1 := syscall.SyscallN(procSetupDiDestroyDriverInfoList.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType)) if r1 == 0 { err = errnoErr(e1) } @@ -3968,7 +4023,7 @@ func SetupDiDestroyDriverInfoList(deviceInfoSet DevInfo, deviceInfoData *DevInfo } func setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiEnumDeviceInfo.Addr(), 3, uintptr(deviceInfoSet), uintptr(memberIndex), uintptr(unsafe.Pointer(deviceInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiEnumDeviceInfo.Addr(), uintptr(deviceInfoSet), uintptr(memberIndex), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3976,7 +4031,7 @@ func setupDiEnumDeviceInfo(deviceInfoSet DevInfo, memberIndex uint32, deviceInfo } func setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverType SPDIT, memberIndex uint32, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiEnumDriverInfoW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType), uintptr(memberIndex), uintptr(unsafe.Pointer(driverInfoData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiEnumDriverInfoW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(driverType), uintptr(memberIndex), uintptr(unsafe.Pointer(driverInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -3984,7 +4039,7 @@ func setupDiEnumDriverInfo(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, d } func setupDiGetClassDevsEx(classGUID *GUID, Enumerator *uint16, hwndParent uintptr, Flags DIGCF, deviceInfoSet DevInfo, machineName *uint16, reserved uintptr) (handle DevInfo, err error) { - r0, _, e1 := syscall.Syscall9(procSetupDiGetClassDevsExW.Addr(), 7, uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(machineName)), uintptr(reserved), 0, 0) + r0, _, e1 := syscall.SyscallN(procSetupDiGetClassDevsExW.Addr(), uintptr(unsafe.Pointer(classGUID)), uintptr(unsafe.Pointer(Enumerator)), uintptr(hwndParent), uintptr(Flags), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(machineName)), uintptr(reserved)) handle = DevInfo(r0) if handle == DevInfo(InvalidHandle) { err = errnoErr(e1) @@ -3993,7 +4048,7 @@ func setupDiGetClassDevsEx(classGUID *GUID, Enumerator *uint16, hwndParent uintp } func SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetClassInstallParamsW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), uintptr(unsafe.Pointer(requiredSize)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetClassInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), uintptr(unsafe.Pointer(requiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4001,7 +4056,7 @@ func SetupDiGetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfo } func setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailData *DevInfoListDetailData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetDeviceInfoListDetailW.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoSetDetailData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInfoListDetailW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoSetDetailData))) if r1 == 0 { err = errnoErr(e1) } @@ -4009,7 +4064,7 @@ func setupDiGetDeviceInfoListDetail(deviceInfoSet DevInfo, deviceInfoSetDetailDa } func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetDeviceInstallParamsW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) if r1 == 0 { err = errnoErr(e1) } @@ -4017,7 +4072,7 @@ func setupDiGetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInf } func setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, instanceId *uint16, instanceIdSize uint32, instanceIdRequiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetDeviceInstanceIdW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(instanceId)), uintptr(instanceIdSize), uintptr(unsafe.Pointer(instanceIdRequiredSize)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceInstanceIdW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(instanceId)), uintptr(instanceIdSize), uintptr(unsafe.Pointer(instanceIdRequiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4025,7 +4080,7 @@ func setupDiGetDeviceInstanceId(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa } func setupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, propertyKey *DEVPROPKEY, propertyType *DEVPROPTYPE, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiGetDevicePropertyW.Addr(), 8, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(propertyKey)), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(flags), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDevicePropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(propertyKey)), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), uintptr(flags)) if r1 == 0 { err = errnoErr(e1) } @@ -4033,7 +4088,7 @@ func setupDiGetDeviceProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyRegDataType *uint32, propertyBuffer *byte, propertyBufferSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procSetupDiGetDeviceRegistryPropertyW.Addr(), 7, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyRegDataType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDeviceRegistryPropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyRegDataType)), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), uintptr(unsafe.Pointer(requiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4041,7 +4096,7 @@ func setupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *Dev } func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetDriverInfoDetailW.Addr(), 6, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData)), uintptr(unsafe.Pointer(driverInfoDetailData)), uintptr(driverInfoDetailDataSize), uintptr(unsafe.Pointer(requiredSize))) + r1, _, e1 := syscall.SyscallN(procSetupDiGetDriverInfoDetailW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData)), uintptr(unsafe.Pointer(driverInfoDetailData)), uintptr(driverInfoDetailDataSize), uintptr(unsafe.Pointer(requiredSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4049,7 +4104,7 @@ func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa } func setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDevice.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiGetSelectedDevice.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4057,7 +4112,7 @@ func setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiGetSelectedDriverW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiGetSelectedDriverW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4065,7 +4120,7 @@ func setupDiGetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Scope DICS_FLAG, HwProfile uint32, KeyType DIREG, samDesired uint32) (key Handle, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiOpenDevRegKey.Addr(), 6, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(Scope), uintptr(HwProfile), uintptr(KeyType), uintptr(samDesired)) + r0, _, e1 := syscall.SyscallN(procSetupDiOpenDevRegKey.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(Scope), uintptr(HwProfile), uintptr(KeyType), uintptr(samDesired)) key = Handle(r0) if key == InvalidHandle { err = errnoErr(e1) @@ -4074,7 +4129,7 @@ func SetupDiOpenDevRegKey(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, Sc } func SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, classInstallParams *ClassInstallHeader, classInstallParamsSize uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiSetClassInstallParamsW.Addr(), 4, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize), 0, 0) + r1, _, e1 := syscall.SyscallN(procSetupDiSetClassInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(classInstallParams)), uintptr(classInstallParamsSize)) if r1 == 0 { err = errnoErr(e1) } @@ -4082,7 +4137,7 @@ func SetupDiSetClassInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfo } func SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, deviceInstallParams *DevInstallParams) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetDeviceInstallParamsW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) + r1, _, e1 := syscall.SyscallN(procSetupDiSetDeviceInstallParamsW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(deviceInstallParams))) if r1 == 0 { err = errnoErr(e1) } @@ -4090,7 +4145,7 @@ func SetupDiSetDeviceInstallParams(deviceInfoSet DevInfo, deviceInfoData *DevInf } func setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP, propertyBuffer *byte, propertyBufferSize uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiSetDeviceRegistryPropertyW.Addr(), 5, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiSetDeviceRegistryPropertyW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(property), uintptr(unsafe.Pointer(propertyBuffer)), uintptr(propertyBufferSize)) if r1 == 0 { err = errnoErr(e1) } @@ -4098,7 +4153,7 @@ func setupDiSetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *Dev } func SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDevice.Addr(), 2, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), 0) + r1, _, e1 := syscall.SyscallN(procSetupDiSetSelectedDevice.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4106,7 +4161,7 @@ func SetupDiSetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiSetSelectedDriverW.Addr(), 3, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) + r1, _, e1 := syscall.SyscallN(procSetupDiSetSelectedDriverW.Addr(), uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData))) if r1 == 0 { err = errnoErr(e1) } @@ -4114,7 +4169,7 @@ func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData } func setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procSetupUninstallOEMInfW.Addr(), 3, uintptr(unsafe.Pointer(infFileName)), uintptr(flags), uintptr(reserved)) + r1, _, e1 := syscall.SyscallN(procSetupUninstallOEMInfW.Addr(), uintptr(unsafe.Pointer(infFileName)), uintptr(flags), uintptr(reserved)) if r1 == 0 { err = errnoErr(e1) } @@ -4122,7 +4177,7 @@ func setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (er } func commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) { - r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) + r0, _, e1 := syscall.SyscallN(procCommandLineToArgvW.Addr(), uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc))) argv = (**uint16)(unsafe.Pointer(r0)) if argv == nil { err = errnoErr(e1) @@ -4131,7 +4186,7 @@ func commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) { } func shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) { - r0, _, _ := syscall.Syscall6(procSHGetKnownFolderPath.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(token), uintptr(unsafe.Pointer(path)), 0, 0) + r0, _, _ := syscall.SyscallN(procSHGetKnownFolderPath.Addr(), uintptr(unsafe.Pointer(id)), uintptr(flags), uintptr(token), uintptr(unsafe.Pointer(path))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -4139,7 +4194,7 @@ func shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **u } func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) { - r1, _, e1 := syscall.Syscall6(procShellExecuteW.Addr(), 6, uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) + r1, _, e1 := syscall.SyscallN(procShellExecuteW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(verb)), uintptr(unsafe.Pointer(file)), uintptr(unsafe.Pointer(args)), uintptr(unsafe.Pointer(cwd)), uintptr(showCmd)) if r1 <= 32 { err = errnoErr(e1) } @@ -4147,12 +4202,12 @@ func ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *ui } func EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) { - syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(hwnd), uintptr(enumFunc), uintptr(param)) + syscall.SyscallN(procEnumChildWindows.Addr(), uintptr(hwnd), uintptr(enumFunc), uintptr(param)) return } func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) { - r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(param), 0) + r1, _, e1 := syscall.SyscallN(procEnumWindows.Addr(), uintptr(enumFunc), uintptr(param)) if r1 == 0 { err = errnoErr(e1) } @@ -4160,7 +4215,7 @@ func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) { } func ExitWindowsEx(flags uint32, reason uint32) (err error) { - r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0) + r1, _, e1 := syscall.SyscallN(procExitWindowsEx.Addr(), uintptr(flags), uintptr(reason)) if r1 == 0 { err = errnoErr(e1) } @@ -4168,7 +4223,7 @@ func ExitWindowsEx(flags uint32, reason uint32) (err error) { } func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) { - r0, _, e1 := syscall.Syscall(procGetClassNameW.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount)) + r0, _, e1 := syscall.SyscallN(procGetClassNameW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount)) copied = int32(r0) if copied == 0 { err = errnoErr(e1) @@ -4177,19 +4232,19 @@ func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, e } func GetDesktopWindow() (hwnd HWND) { - r0, _, _ := syscall.Syscall(procGetDesktopWindow.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetDesktopWindow.Addr()) hwnd = HWND(r0) return } func GetForegroundWindow() (hwnd HWND) { - r0, _, _ := syscall.Syscall(procGetForegroundWindow.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetForegroundWindow.Addr()) hwnd = HWND(r0) return } func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { - r1, _, e1 := syscall.Syscall(procGetGUIThreadInfo.Addr(), 2, uintptr(thread), uintptr(unsafe.Pointer(info)), 0) + r1, _, e1 := syscall.SyscallN(procGetGUIThreadInfo.Addr(), uintptr(thread), uintptr(unsafe.Pointer(info))) if r1 == 0 { err = errnoErr(e1) } @@ -4197,19 +4252,19 @@ func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) { } func GetKeyboardLayout(tid uint32) (hkl Handle) { - r0, _, _ := syscall.Syscall(procGetKeyboardLayout.Addr(), 1, uintptr(tid), 0, 0) + r0, _, _ := syscall.SyscallN(procGetKeyboardLayout.Addr(), uintptr(tid)) hkl = Handle(r0) return } func GetShellWindow() (shellWindow HWND) { - r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0) + r0, _, _ := syscall.SyscallN(procGetShellWindow.Addr()) shellWindow = HWND(r0) return } func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetWindowThreadProcessId.Addr(), 2, uintptr(hwnd), uintptr(unsafe.Pointer(pid)), 0) + r0, _, e1 := syscall.SyscallN(procGetWindowThreadProcessId.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(pid))) tid = uint32(r0) if tid == 0 { err = errnoErr(e1) @@ -4218,25 +4273,25 @@ func GetWindowThreadProcessId(hwnd HWND, pid *uint32) (tid uint32, err error) { } func IsWindow(hwnd HWND) (isWindow bool) { - r0, _, _ := syscall.Syscall(procIsWindow.Addr(), 1, uintptr(hwnd), 0, 0) + r0, _, _ := syscall.SyscallN(procIsWindow.Addr(), uintptr(hwnd)) isWindow = r0 != 0 return } func IsWindowUnicode(hwnd HWND) (isUnicode bool) { - r0, _, _ := syscall.Syscall(procIsWindowUnicode.Addr(), 1, uintptr(hwnd), 0, 0) + r0, _, _ := syscall.SyscallN(procIsWindowUnicode.Addr(), uintptr(hwnd)) isUnicode = r0 != 0 return } func IsWindowVisible(hwnd HWND) (isVisible bool) { - r0, _, _ := syscall.Syscall(procIsWindowVisible.Addr(), 1, uintptr(hwnd), 0, 0) + r0, _, _ := syscall.SyscallN(procIsWindowVisible.Addr(), uintptr(hwnd)) isVisible = r0 != 0 return } func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) { - r0, _, e1 := syscall.Syscall(procLoadKeyboardLayoutW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(flags), 0) + r0, _, e1 := syscall.SyscallN(procLoadKeyboardLayoutW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags)) hkl = Handle(r0) if hkl == 0 { err = errnoErr(e1) @@ -4245,7 +4300,7 @@ func LoadKeyboardLayout(name *uint16, flags uint32) (hkl Handle, err error) { } func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) { - r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0) + r0, _, e1 := syscall.SyscallN(procMessageBoxW.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype)) ret = int32(r0) if ret == 0 { err = errnoErr(e1) @@ -4254,13 +4309,13 @@ func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret i } func ToUnicodeEx(vkey uint32, scancode uint32, keystate *byte, pwszBuff *uint16, cchBuff int32, flags uint32, hkl Handle) (ret int32) { - r0, _, _ := syscall.Syscall9(procToUnicodeEx.Addr(), 7, uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl), 0, 0) + r0, _, _ := syscall.SyscallN(procToUnicodeEx.Addr(), uintptr(vkey), uintptr(scancode), uintptr(unsafe.Pointer(keystate)), uintptr(unsafe.Pointer(pwszBuff)), uintptr(cchBuff), uintptr(flags), uintptr(hkl)) ret = int32(r0) return } func UnloadKeyboardLayout(hkl Handle) (err error) { - r1, _, e1 := syscall.Syscall(procUnloadKeyboardLayout.Addr(), 1, uintptr(hkl), 0, 0) + r1, _, e1 := syscall.SyscallN(procUnloadKeyboardLayout.Addr(), uintptr(hkl)) if r1 == 0 { err = errnoErr(e1) } @@ -4272,7 +4327,7 @@ func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) ( if inheritExisting { _p0 = 1 } - r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) + r1, _, e1 := syscall.SyscallN(procCreateEnvironmentBlock.Addr(), uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) if r1 == 0 { err = errnoErr(e1) } @@ -4280,7 +4335,7 @@ func CreateEnvironmentBlock(block **uint16, token Token, inheritExisting bool) ( } func DestroyEnvironmentBlock(block *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0) + r1, _, e1 := syscall.SyscallN(procDestroyEnvironmentBlock.Addr(), uintptr(unsafe.Pointer(block))) if r1 == 0 { err = errnoErr(e1) } @@ -4288,7 +4343,7 @@ func DestroyEnvironmentBlock(block *uint16) (err error) { } func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) + r1, _, e1 := syscall.SyscallN(procGetUserProfileDirectoryW.Addr(), uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen))) if r1 == 0 { err = errnoErr(e1) } @@ -4305,7 +4360,7 @@ func GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32 } func _GetFileVersionInfoSize(filename *uint16, zeroHandle *Handle) (bufSize uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetFileVersionInfoSizeW.Addr(), 2, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zeroHandle)), 0) + r0, _, e1 := syscall.SyscallN(procGetFileVersionInfoSizeW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zeroHandle))) bufSize = uint32(r0) if bufSize == 0 { err = errnoErr(e1) @@ -4323,7 +4378,7 @@ func GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer u } func _GetFileVersionInfo(filename *uint16, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileVersionInfoW.Addr(), 4, uintptr(unsafe.Pointer(filename)), uintptr(handle), uintptr(bufSize), uintptr(buffer), 0, 0) + r1, _, e1 := syscall.SyscallN(procGetFileVersionInfoW.Addr(), uintptr(unsafe.Pointer(filename)), uintptr(handle), uintptr(bufSize), uintptr(buffer)) if r1 == 0 { err = errnoErr(e1) } @@ -4340,7 +4395,7 @@ func VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer } func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procVerQueryValueW.Addr(), 4, uintptr(block), uintptr(unsafe.Pointer(subBlock)), uintptr(pointerToBufferPointer), uintptr(unsafe.Pointer(bufSize)), 0, 0) + r1, _, e1 := syscall.SyscallN(procVerQueryValueW.Addr(), uintptr(block), uintptr(unsafe.Pointer(subBlock)), uintptr(pointerToBufferPointer), uintptr(unsafe.Pointer(bufSize))) if r1 == 0 { err = errnoErr(e1) } @@ -4348,7 +4403,7 @@ func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPoint } func TimeBeginPeriod(period uint32) (err error) { - r1, _, e1 := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0) + r1, _, e1 := syscall.SyscallN(proctimeBeginPeriod.Addr(), uintptr(period)) if r1 != 0 { err = errnoErr(e1) } @@ -4356,7 +4411,7 @@ func TimeBeginPeriod(period uint32) (err error) { } func TimeEndPeriod(period uint32) (err error) { - r1, _, e1 := syscall.Syscall(proctimeEndPeriod.Addr(), 1, uintptr(period), 0, 0) + r1, _, e1 := syscall.SyscallN(proctimeEndPeriod.Addr(), uintptr(period)) if r1 != 0 { err = errnoErr(e1) } @@ -4364,7 +4419,7 @@ func TimeEndPeriod(period uint32) (err error) { } func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) { - r0, _, _ := syscall.Syscall(procWinVerifyTrustEx.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data))) + r0, _, _ := syscall.SyscallN(procWinVerifyTrustEx.Addr(), uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data))) if r0 != 0 { ret = syscall.Errno(r0) } @@ -4372,12 +4427,12 @@ func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) } func FreeAddrInfoW(addrinfo *AddrinfoW) { - syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0) + syscall.SyscallN(procFreeAddrInfoW.Addr(), uintptr(unsafe.Pointer(addrinfo))) return } func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) { - r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0) + r0, _, _ := syscall.SyscallN(procGetAddrInfoW.Addr(), uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result))) if r0 != 0 { sockerr = syscall.Errno(r0) } @@ -4385,7 +4440,7 @@ func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, resul } func WSACleanup() (err error) { - r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0) + r1, _, e1 := syscall.SyscallN(procWSACleanup.Addr()) if r1 == socket_error { err = errnoErr(e1) } @@ -4393,7 +4448,7 @@ func WSACleanup() (err error) { } func WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) { - r1, _, e1 := syscall.Syscall(procWSADuplicateSocketW.Addr(), 3, uintptr(s), uintptr(processID), uintptr(unsafe.Pointer(info))) + r1, _, e1 := syscall.SyscallN(procWSADuplicateSocketW.Addr(), uintptr(s), uintptr(processID), uintptr(unsafe.Pointer(info))) if r1 != 0 { err = errnoErr(e1) } @@ -4401,7 +4456,7 @@ func WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err } func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) { - r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) + r0, _, e1 := syscall.SyscallN(procWSAEnumProtocolsW.Addr(), uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength))) n = int32(r0) if n == -1 { err = errnoErr(e1) @@ -4414,7 +4469,7 @@ func WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, f if wait { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0) + r1, _, e1 := syscall.SyscallN(procWSAGetOverlappedResult.Addr(), uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags))) if r1 == 0 { err = errnoErr(e1) } @@ -4422,7 +4477,7 @@ func WSAGetOverlappedResult(h Handle, o *Overlapped, bytes *uint32, wait bool, f } func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) + r1, _, e1 := syscall.SyscallN(procWSAIoctl.Addr(), uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine)) if r1 == socket_error { err = errnoErr(e1) } @@ -4430,7 +4485,7 @@ func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbo } func WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) (err error) { - r1, _, e1 := syscall.Syscall(procWSALookupServiceBeginW.Addr(), 3, uintptr(unsafe.Pointer(querySet)), uintptr(flags), uintptr(unsafe.Pointer(handle))) + r1, _, e1 := syscall.SyscallN(procWSALookupServiceBeginW.Addr(), uintptr(unsafe.Pointer(querySet)), uintptr(flags), uintptr(unsafe.Pointer(handle))) if r1 == socket_error { err = errnoErr(e1) } @@ -4438,7 +4493,7 @@ func WSALookupServiceBegin(querySet *WSAQUERYSET, flags uint32, handle *Handle) } func WSALookupServiceEnd(handle Handle) (err error) { - r1, _, e1 := syscall.Syscall(procWSALookupServiceEnd.Addr(), 1, uintptr(handle), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSALookupServiceEnd.Addr(), uintptr(handle)) if r1 == socket_error { err = errnoErr(e1) } @@ -4446,7 +4501,7 @@ func WSALookupServiceEnd(handle Handle) (err error) { } func WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WSAQUERYSET) (err error) { - r1, _, e1 := syscall.Syscall6(procWSALookupServiceNextW.Addr(), 4, uintptr(handle), uintptr(flags), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(querySet)), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSALookupServiceNextW.Addr(), uintptr(handle), uintptr(flags), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(querySet))) if r1 == socket_error { err = errnoErr(e1) } @@ -4454,7 +4509,7 @@ func WSALookupServiceNext(handle Handle, flags uint32, size *int32, querySet *WS } func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSARecv.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4462,7 +4517,7 @@ func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32 } func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + r1, _, e1 := syscall.SyscallN(procWSARecvFrom.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4470,7 +4525,7 @@ func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *ui } func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0) + r1, _, e1 := syscall.SyscallN(procWSASend.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4478,7 +4533,7 @@ func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, } func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) { - r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) + r1, _, e1 := syscall.SyscallN(procWSASendTo.Addr(), uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) if r1 == socket_error { err = errnoErr(e1) } @@ -4486,7 +4541,7 @@ func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32 } func WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protoInfo)), uintptr(group), uintptr(flags)) + r0, _, e1 := syscall.SyscallN(procWSASocketW.Addr(), uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protoInfo)), uintptr(group), uintptr(flags)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -4495,7 +4550,7 @@ func WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, } func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { - r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0) + r0, _, _ := syscall.SyscallN(procWSAStartup.Addr(), uintptr(verreq), uintptr(unsafe.Pointer(data))) if r0 != 0 { sockerr = syscall.Errno(r0) } @@ -4503,7 +4558,7 @@ func WSAStartup(verreq uint32, data *WSAData) (sockerr error) { } func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + r1, _, e1 := syscall.SyscallN(procbind.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4511,7 +4566,7 @@ func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) { } func Closesocket(s Handle) (err error) { - r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0) + r1, _, e1 := syscall.SyscallN(procclosesocket.Addr(), uintptr(s)) if r1 == socket_error { err = errnoErr(e1) } @@ -4519,7 +4574,7 @@ func Closesocket(s Handle) (err error) { } func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + r1, _, e1 := syscall.SyscallN(procconnect.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4536,7 +4591,7 @@ func GetHostByName(name string) (h *Hostent, err error) { } func _GetHostByName(name *byte) (h *Hostent, err error) { - r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procgethostbyname.Addr(), uintptr(unsafe.Pointer(name))) h = (*Hostent)(unsafe.Pointer(r0)) if h == nil { err = errnoErr(e1) @@ -4545,7 +4600,7 @@ func _GetHostByName(name *byte) (h *Hostent, err error) { } func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + r1, _, e1 := syscall.SyscallN(procgetpeername.Addr(), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) if r1 == socket_error { err = errnoErr(e1) } @@ -4562,7 +4617,7 @@ func GetProtoByName(name string) (p *Protoent, err error) { } func _GetProtoByName(name *byte) (p *Protoent, err error) { - r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0) + r0, _, e1 := syscall.SyscallN(procgetprotobyname.Addr(), uintptr(unsafe.Pointer(name))) p = (*Protoent)(unsafe.Pointer(r0)) if p == nil { err = errnoErr(e1) @@ -4585,7 +4640,7 @@ func GetServByName(name string, proto string) (s *Servent, err error) { } func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { - r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0) + r0, _, e1 := syscall.SyscallN(procgetservbyname.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto))) s = (*Servent)(unsafe.Pointer(r0)) if s == nil { err = errnoErr(e1) @@ -4594,7 +4649,7 @@ func _GetServByName(name *byte, proto *byte) (s *Servent, err error) { } func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) + r1, _, e1 := syscall.SyscallN(procgetsockname.Addr(), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) if r1 == socket_error { err = errnoErr(e1) } @@ -4602,7 +4657,7 @@ func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) { } func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) { - r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0) + r1, _, e1 := syscall.SyscallN(procgetsockopt.Addr(), uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen))) if r1 == socket_error { err = errnoErr(e1) } @@ -4610,7 +4665,7 @@ func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int3 } func listen(s Handle, backlog int32) (err error) { - r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0) + r1, _, e1 := syscall.SyscallN(proclisten.Addr(), uintptr(s), uintptr(backlog)) if r1 == socket_error { err = errnoErr(e1) } @@ -4618,7 +4673,7 @@ func listen(s Handle, backlog int32) (err error) { } func Ntohs(netshort uint16) (u uint16) { - r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0) + r0, _, _ := syscall.SyscallN(procntohs.Addr(), uintptr(netshort)) u = uint16(r0) return } @@ -4628,7 +4683,7 @@ func recvfrom(s Handle, buf []byte, flags int32, from *RawSockaddrAny, fromlen * if len(buf) > 0 { _p0 = &buf[0] } - r0, _, e1 := syscall.Syscall6(procrecvfrom.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) + r0, _, e1 := syscall.SyscallN(procrecvfrom.Addr(), uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) n = int32(r0) if n == -1 { err = errnoErr(e1) @@ -4641,7 +4696,7 @@ func sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) ( if len(buf) > 0 { _p0 = &buf[0] } - r1, _, e1 := syscall.Syscall6(procsendto.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(tolen)) + r1, _, e1 := syscall.SyscallN(procsendto.Addr(), uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(tolen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4649,7 +4704,7 @@ func sendto(s Handle, buf []byte, flags int32, to unsafe.Pointer, tolen int32) ( } func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) { - r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0) + r1, _, e1 := syscall.SyscallN(procsetsockopt.Addr(), uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen)) if r1 == socket_error { err = errnoErr(e1) } @@ -4657,7 +4712,7 @@ func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32 } func shutdown(s Handle, how int32) (err error) { - r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0) + r1, _, e1 := syscall.SyscallN(procshutdown.Addr(), uintptr(s), uintptr(how)) if r1 == socket_error { err = errnoErr(e1) } @@ -4665,7 +4720,7 @@ func shutdown(s Handle, how int32) (err error) { } func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { - r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol)) + r0, _, e1 := syscall.SyscallN(procsocket.Addr(), uintptr(af), uintptr(typ), uintptr(protocol)) handle = Handle(r0) if handle == InvalidHandle { err = errnoErr(e1) @@ -4674,7 +4729,7 @@ func socket(af int32, typ int32, protocol int32) (handle Handle, err error) { } func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procWTSEnumerateSessionsW.Addr(), 5, uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count)), 0) + r1, _, e1 := syscall.SyscallN(procWTSEnumerateSessionsW.Addr(), uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count))) if r1 == 0 { err = errnoErr(e1) } @@ -4682,12 +4737,12 @@ func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessio } func WTSFreeMemory(ptr uintptr) { - syscall.Syscall(procWTSFreeMemory.Addr(), 1, uintptr(ptr), 0, 0) + syscall.SyscallN(procWTSFreeMemory.Addr(), uintptr(ptr)) return } func WTSQueryUserToken(session uint32, token *Token) (err error) { - r1, _, e1 := syscall.Syscall(procWTSQueryUserToken.Addr(), 2, uintptr(session), uintptr(unsafe.Pointer(token)), 0) + r1, _, e1 := syscall.SyscallN(procWTSQueryUserToken.Addr(), uintptr(session), uintptr(unsafe.Pointer(token))) if r1 == 0 { err = errnoErr(e1) } diff --git a/vendor/golang.org/x/term/term_windows.go b/vendor/golang.org/x/term/term_windows.go index df6bf948..0ddd81c0 100644 --- a/vendor/golang.org/x/term/term_windows.go +++ b/vendor/golang.org/x/term/term_windows.go @@ -20,12 +20,14 @@ func isTerminal(fd int) bool { return err == nil } +// This is intended to be used on a console input handle. +// See https://learn.microsoft.com/en-us/windows/console/setconsolemode func makeRaw(fd int) (*State, error) { var st uint32 if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { return nil, err } - raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT) + raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT) raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { return nil, err diff --git a/vendor/golang.org/x/term/terminal.go b/vendor/golang.org/x/term/terminal.go index 13e9a64a..9255449b 100644 --- a/vendor/golang.org/x/term/terminal.go +++ b/vendor/golang.org/x/term/terminal.go @@ -146,6 +146,7 @@ const ( keyCtrlD = 4 keyCtrlU = 21 keyEnter = '\r' + keyLF = '\n' keyEscape = 27 keyBackspace = 127 keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota @@ -412,7 +413,7 @@ func (t *Terminal) eraseNPreviousChars(n int) { } } -// countToLeftWord returns then number of characters from the cursor to the +// countToLeftWord returns the number of characters from the cursor to the // start of the previous word. func (t *Terminal) countToLeftWord() int { if t.pos == 0 { @@ -437,7 +438,7 @@ func (t *Terminal) countToLeftWord() int { return t.pos - pos } -// countToRightWord returns then number of characters from the cursor to the +// countToRightWord returns the number of characters from the cursor to the // start of the next word. func (t *Terminal) countToRightWord() int { pos := t.pos @@ -477,7 +478,7 @@ func visualLength(runes []rune) int { return length } -// histroryAt unlocks the terminal and relocks it while calling History.At. +// historyAt unlocks the terminal and relocks it while calling History.At. func (t *Terminal) historyAt(idx int) (string, bool) { t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer. defer t.lock.Lock() // panic in At (or Len) protection. @@ -497,7 +498,7 @@ func (t *Terminal) historyAdd(entry string) { // handleKey processes the given key and, optionally, returns a line of text // that the user has entered. func (t *Terminal) handleKey(key rune) (line string, ok bool) { - if t.pasteActive && key != keyEnter { + if t.pasteActive && key != keyEnter && key != keyLF { t.addKeyToLine(key) return } @@ -567,7 +568,7 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) { t.setLine(runes, len(runes)) } } - case keyEnter: + case keyEnter, keyLF: t.moveCursorToPos(len(t.line)) t.queue([]rune("\r\n")) line = string(t.line) @@ -812,6 +813,10 @@ func (t *Terminal) readLine() (line string, err error) { if !t.pasteActive { lineIsPasted = false } + // If we have CR, consume LF if present (CRLF sequence) to avoid returning an extra empty line. + if key == keyEnter && len(rest) > 0 && rest[0] == keyLF { + rest = rest[1:] + } line, lineOk = t.handleKey(key) } if len(rest) > 0 { diff --git a/vendor/gopkg.in/yaml.v3/LICENSE b/vendor/gopkg.in/yaml.v3/LICENSE deleted file mode 100644 index 2683e4bb..00000000 --- a/vendor/gopkg.in/yaml.v3/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ - -This project is covered by two different licenses: MIT and Apache. - -#### MIT License #### - -The following files were ported to Go from C files of libyaml, and thus -are still covered by their original MIT license, with the additional -copyright staring in 2011 when the project was ported over: - - apic.go emitterc.go parserc.go readerc.go scannerc.go - writerc.go yamlh.go yamlprivateh.go - -Copyright (c) 2006-2010 Kirill Simonov -Copyright (c) 2006-2011 Kirill Simonov - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -### Apache License ### - -All the remaining project files are covered by the Apache license: - -Copyright (c) 2011-2019 Canonical Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/gopkg.in/yaml.v3/NOTICE b/vendor/gopkg.in/yaml.v3/NOTICE deleted file mode 100644 index 866d74a7..00000000 --- a/vendor/gopkg.in/yaml.v3/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2011-2016 Canonical Ltd. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/gopkg.in/yaml.v3/README.md b/vendor/gopkg.in/yaml.v3/README.md deleted file mode 100644 index 08eb1bab..00000000 --- a/vendor/gopkg.in/yaml.v3/README.md +++ /dev/null @@ -1,150 +0,0 @@ -# YAML support for the Go language - -Introduction ------------- - -The yaml package enables Go programs to comfortably encode and decode YAML -values. It was developed within [Canonical](https://www.canonical.com) as -part of the [juju](https://juju.ubuntu.com) project, and is based on a -pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) -C library to parse and generate YAML data quickly and reliably. - -Compatibility -------------- - -The yaml package supports most of YAML 1.2, but preserves some behavior -from 1.1 for backwards compatibility. - -Specifically, as of v3 of the yaml package: - - - YAML 1.1 bools (_yes/no, on/off_) are supported as long as they are being - decoded into a typed bool value. Otherwise they behave as a string. Booleans - in YAML 1.2 are _true/false_ only. - - Octals encode and decode as _0777_ per YAML 1.1, rather than _0o777_ - as specified in YAML 1.2, because most parsers still use the old format. - Octals in the _0o777_ format are supported though, so new files work. - - Does not support base-60 floats. These are gone from YAML 1.2, and were - actually never supported by this package as it's clearly a poor choice. - -and offers backwards -compatibility with YAML 1.1 in some cases. -1.2, including support for -anchors, tags, map merging, etc. Multi-document unmarshalling is not yet -implemented, and base-60 floats from YAML 1.1 are purposefully not -supported since they're a poor design and are gone in YAML 1.2. - -Installation and usage ----------------------- - -The import path for the package is *gopkg.in/yaml.v3*. - -To install it, run: - - go get gopkg.in/yaml.v3 - -API documentation ------------------ - -If opened in a browser, the import path itself leads to the API documentation: - - - [https://gopkg.in/yaml.v3](https://gopkg.in/yaml.v3) - -API stability -------------- - -The package API for yaml v3 will remain stable as described in [gopkg.in](https://gopkg.in). - - -License -------- - -The yaml package is licensed under the MIT and Apache License 2.0 licenses. -Please see the LICENSE file for details. - - -Example -------- - -```Go -package main - -import ( - "fmt" - "log" - - "gopkg.in/yaml.v3" -) - -var data = ` -a: Easy! -b: - c: 2 - d: [3, 4] -` - -// Note: struct fields must be public in order for unmarshal to -// correctly populate the data. -type T struct { - A string - B struct { - RenamedC int `yaml:"c"` - D []int `yaml:",flow"` - } -} - -func main() { - t := T{} - - err := yaml.Unmarshal([]byte(data), &t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t:\n%v\n\n", t) - - d, err := yaml.Marshal(&t) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- t dump:\n%s\n\n", string(d)) - - m := make(map[interface{}]interface{}) - - err = yaml.Unmarshal([]byte(data), &m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m:\n%v\n\n", m) - - d, err = yaml.Marshal(&m) - if err != nil { - log.Fatalf("error: %v", err) - } - fmt.Printf("--- m dump:\n%s\n\n", string(d)) -} -``` - -This example will generate the following output: - -``` ---- t: -{Easy! {2 [3 4]}} - ---- t dump: -a: Easy! -b: - c: 2 - d: [3, 4] - - ---- m: -map[a:Easy! b:map[c:2 d:[3 4]]] - ---- m dump: -a: Easy! -b: - c: 2 - d: - - 3 - - 4 -``` - diff --git a/vendor/gopkg.in/yaml.v3/apic.go b/vendor/gopkg.in/yaml.v3/apic.go deleted file mode 100644 index ae7d049f..00000000 --- a/vendor/gopkg.in/yaml.v3/apic.go +++ /dev/null @@ -1,747 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -import ( - "io" -) - -func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) { - //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens)) - - // Check if we can move the queue at the beginning of the buffer. - if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) { - if parser.tokens_head != len(parser.tokens) { - copy(parser.tokens, parser.tokens[parser.tokens_head:]) - } - parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head] - parser.tokens_head = 0 - } - parser.tokens = append(parser.tokens, *token) - if pos < 0 { - return - } - copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:]) - parser.tokens[parser.tokens_head+pos] = *token -} - -// Create a new parser object. -func yaml_parser_initialize(parser *yaml_parser_t) bool { - *parser = yaml_parser_t{ - raw_buffer: make([]byte, 0, input_raw_buffer_size), - buffer: make([]byte, 0, input_buffer_size), - } - return true -} - -// Destroy a parser object. -func yaml_parser_delete(parser *yaml_parser_t) { - *parser = yaml_parser_t{} -} - -// String read handler. -func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { - if parser.input_pos == len(parser.input) { - return 0, io.EOF - } - n = copy(buffer, parser.input[parser.input_pos:]) - parser.input_pos += n - return n, nil -} - -// Reader read handler. -func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { - return parser.input_reader.Read(buffer) -} - -// Set a string input. -func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) { - if parser.read_handler != nil { - panic("must set the input source only once") - } - parser.read_handler = yaml_string_read_handler - parser.input = input - parser.input_pos = 0 -} - -// Set a file input. -func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) { - if parser.read_handler != nil { - panic("must set the input source only once") - } - parser.read_handler = yaml_reader_read_handler - parser.input_reader = r -} - -// Set the source encoding. -func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) { - if parser.encoding != yaml_ANY_ENCODING { - panic("must set the encoding only once") - } - parser.encoding = encoding -} - -// Create a new emitter object. -func yaml_emitter_initialize(emitter *yaml_emitter_t) { - *emitter = yaml_emitter_t{ - buffer: make([]byte, output_buffer_size), - raw_buffer: make([]byte, 0, output_raw_buffer_size), - states: make([]yaml_emitter_state_t, 0, initial_stack_size), - events: make([]yaml_event_t, 0, initial_queue_size), - best_width: -1, - } -} - -// Destroy an emitter object. -func yaml_emitter_delete(emitter *yaml_emitter_t) { - *emitter = yaml_emitter_t{} -} - -// String write handler. -func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error { - *emitter.output_buffer = append(*emitter.output_buffer, buffer...) - return nil -} - -// yaml_writer_write_handler uses emitter.output_writer to write the -// emitted text. -func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error { - _, err := emitter.output_writer.Write(buffer) - return err -} - -// Set a string output. -func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) { - if emitter.write_handler != nil { - panic("must set the output target only once") - } - emitter.write_handler = yaml_string_write_handler - emitter.output_buffer = output_buffer -} - -// Set a file output. -func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) { - if emitter.write_handler != nil { - panic("must set the output target only once") - } - emitter.write_handler = yaml_writer_write_handler - emitter.output_writer = w -} - -// Set the output encoding. -func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) { - if emitter.encoding != yaml_ANY_ENCODING { - panic("must set the output encoding only once") - } - emitter.encoding = encoding -} - -// Set the canonical output style. -func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) { - emitter.canonical = canonical -} - -// Set the indentation increment. -func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) { - if indent < 2 || indent > 9 { - indent = 2 - } - emitter.best_indent = indent -} - -// Set the preferred line width. -func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) { - if width < 0 { - width = -1 - } - emitter.best_width = width -} - -// Set if unescaped non-ASCII characters are allowed. -func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) { - emitter.unicode = unicode -} - -// Set the preferred line break character. -func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) { - emitter.line_break = line_break -} - -///* -// * Destroy a token object. -// */ -// -//YAML_DECLARE(void) -//yaml_token_delete(yaml_token_t *token) -//{ -// assert(token); // Non-NULL token object expected. -// -// switch (token.type) -// { -// case YAML_TAG_DIRECTIVE_TOKEN: -// yaml_free(token.data.tag_directive.handle); -// yaml_free(token.data.tag_directive.prefix); -// break; -// -// case YAML_ALIAS_TOKEN: -// yaml_free(token.data.alias.value); -// break; -// -// case YAML_ANCHOR_TOKEN: -// yaml_free(token.data.anchor.value); -// break; -// -// case YAML_TAG_TOKEN: -// yaml_free(token.data.tag.handle); -// yaml_free(token.data.tag.suffix); -// break; -// -// case YAML_SCALAR_TOKEN: -// yaml_free(token.data.scalar.value); -// break; -// -// default: -// break; -// } -// -// memset(token, 0, sizeof(yaml_token_t)); -//} -// -///* -// * Check if a string is a valid UTF-8 sequence. -// * -// * Check 'reader.c' for more details on UTF-8 encoding. -// */ -// -//static int -//yaml_check_utf8(yaml_char_t *start, size_t length) -//{ -// yaml_char_t *end = start+length; -// yaml_char_t *pointer = start; -// -// while (pointer < end) { -// unsigned char octet; -// unsigned int width; -// unsigned int value; -// size_t k; -// -// octet = pointer[0]; -// width = (octet & 0x80) == 0x00 ? 1 : -// (octet & 0xE0) == 0xC0 ? 2 : -// (octet & 0xF0) == 0xE0 ? 3 : -// (octet & 0xF8) == 0xF0 ? 4 : 0; -// value = (octet & 0x80) == 0x00 ? octet & 0x7F : -// (octet & 0xE0) == 0xC0 ? octet & 0x1F : -// (octet & 0xF0) == 0xE0 ? octet & 0x0F : -// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; -// if (!width) return 0; -// if (pointer+width > end) return 0; -// for (k = 1; k < width; k ++) { -// octet = pointer[k]; -// if ((octet & 0xC0) != 0x80) return 0; -// value = (value << 6) + (octet & 0x3F); -// } -// if (!((width == 1) || -// (width == 2 && value >= 0x80) || -// (width == 3 && value >= 0x800) || -// (width == 4 && value >= 0x10000))) return 0; -// -// pointer += width; -// } -// -// return 1; -//} -// - -// Create STREAM-START. -func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) { - *event = yaml_event_t{ - typ: yaml_STREAM_START_EVENT, - encoding: encoding, - } -} - -// Create STREAM-END. -func yaml_stream_end_event_initialize(event *yaml_event_t) { - *event = yaml_event_t{ - typ: yaml_STREAM_END_EVENT, - } -} - -// Create DOCUMENT-START. -func yaml_document_start_event_initialize( - event *yaml_event_t, - version_directive *yaml_version_directive_t, - tag_directives []yaml_tag_directive_t, - implicit bool, -) { - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - version_directive: version_directive, - tag_directives: tag_directives, - implicit: implicit, - } -} - -// Create DOCUMENT-END. -func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) { - *event = yaml_event_t{ - typ: yaml_DOCUMENT_END_EVENT, - implicit: implicit, - } -} - -// Create ALIAS. -func yaml_alias_event_initialize(event *yaml_event_t, anchor []byte) bool { - *event = yaml_event_t{ - typ: yaml_ALIAS_EVENT, - anchor: anchor, - } - return true -} - -// Create SCALAR. -func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool { - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - anchor: anchor, - tag: tag, - value: value, - implicit: plain_implicit, - quoted_implicit: quoted_implicit, - style: yaml_style_t(style), - } - return true -} - -// Create SEQUENCE-START. -func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool { - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(style), - } - return true -} - -// Create SEQUENCE-END. -func yaml_sequence_end_event_initialize(event *yaml_event_t) bool { - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - } - return true -} - -// Create MAPPING-START. -func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) { - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(style), - } -} - -// Create MAPPING-END. -func yaml_mapping_end_event_initialize(event *yaml_event_t) { - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - } -} - -// Destroy an event object. -func yaml_event_delete(event *yaml_event_t) { - *event = yaml_event_t{} -} - -///* -// * Create a document object. -// */ -// -//YAML_DECLARE(int) -//yaml_document_initialize(document *yaml_document_t, -// version_directive *yaml_version_directive_t, -// tag_directives_start *yaml_tag_directive_t, -// tag_directives_end *yaml_tag_directive_t, -// start_implicit int, end_implicit int) -//{ -// struct { -// error yaml_error_type_t -// } context -// struct { -// start *yaml_node_t -// end *yaml_node_t -// top *yaml_node_t -// } nodes = { NULL, NULL, NULL } -// version_directive_copy *yaml_version_directive_t = NULL -// struct { -// start *yaml_tag_directive_t -// end *yaml_tag_directive_t -// top *yaml_tag_directive_t -// } tag_directives_copy = { NULL, NULL, NULL } -// value yaml_tag_directive_t = { NULL, NULL } -// mark yaml_mark_t = { 0, 0, 0 } -// -// assert(document) // Non-NULL document object is expected. -// assert((tag_directives_start && tag_directives_end) || -// (tag_directives_start == tag_directives_end)) -// // Valid tag directives are expected. -// -// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error -// -// if (version_directive) { -// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)) -// if (!version_directive_copy) goto error -// version_directive_copy.major = version_directive.major -// version_directive_copy.minor = version_directive.minor -// } -// -// if (tag_directives_start != tag_directives_end) { -// tag_directive *yaml_tag_directive_t -// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) -// goto error -// for (tag_directive = tag_directives_start -// tag_directive != tag_directives_end; tag_directive ++) { -// assert(tag_directive.handle) -// assert(tag_directive.prefix) -// if (!yaml_check_utf8(tag_directive.handle, -// strlen((char *)tag_directive.handle))) -// goto error -// if (!yaml_check_utf8(tag_directive.prefix, -// strlen((char *)tag_directive.prefix))) -// goto error -// value.handle = yaml_strdup(tag_directive.handle) -// value.prefix = yaml_strdup(tag_directive.prefix) -// if (!value.handle || !value.prefix) goto error -// if (!PUSH(&context, tag_directives_copy, value)) -// goto error -// value.handle = NULL -// value.prefix = NULL -// } -// } -// -// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, -// tag_directives_copy.start, tag_directives_copy.top, -// start_implicit, end_implicit, mark, mark) -// -// return 1 -// -//error: -// STACK_DEL(&context, nodes) -// yaml_free(version_directive_copy) -// while (!STACK_EMPTY(&context, tag_directives_copy)) { -// value yaml_tag_directive_t = POP(&context, tag_directives_copy) -// yaml_free(value.handle) -// yaml_free(value.prefix) -// } -// STACK_DEL(&context, tag_directives_copy) -// yaml_free(value.handle) -// yaml_free(value.prefix) -// -// return 0 -//} -// -///* -// * Destroy a document object. -// */ -// -//YAML_DECLARE(void) -//yaml_document_delete(document *yaml_document_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// tag_directive *yaml_tag_directive_t -// -// context.error = YAML_NO_ERROR // Eliminate a compiler warning. -// -// assert(document) // Non-NULL document object is expected. -// -// while (!STACK_EMPTY(&context, document.nodes)) { -// node yaml_node_t = POP(&context, document.nodes) -// yaml_free(node.tag) -// switch (node.type) { -// case YAML_SCALAR_NODE: -// yaml_free(node.data.scalar.value) -// break -// case YAML_SEQUENCE_NODE: -// STACK_DEL(&context, node.data.sequence.items) -// break -// case YAML_MAPPING_NODE: -// STACK_DEL(&context, node.data.mapping.pairs) -// break -// default: -// assert(0) // Should not happen. -// } -// } -// STACK_DEL(&context, document.nodes) -// -// yaml_free(document.version_directive) -// for (tag_directive = document.tag_directives.start -// tag_directive != document.tag_directives.end -// tag_directive++) { -// yaml_free(tag_directive.handle) -// yaml_free(tag_directive.prefix) -// } -// yaml_free(document.tag_directives.start) -// -// memset(document, 0, sizeof(yaml_document_t)) -//} -// -///** -// * Get a document node. -// */ -// -//YAML_DECLARE(yaml_node_t *) -//yaml_document_get_node(document *yaml_document_t, index int) -//{ -// assert(document) // Non-NULL document object is expected. -// -// if (index > 0 && document.nodes.start + index <= document.nodes.top) { -// return document.nodes.start + index - 1 -// } -// return NULL -//} -// -///** -// * Get the root object. -// */ -// -//YAML_DECLARE(yaml_node_t *) -//yaml_document_get_root_node(document *yaml_document_t) -//{ -// assert(document) // Non-NULL document object is expected. -// -// if (document.nodes.top != document.nodes.start) { -// return document.nodes.start -// } -// return NULL -//} -// -///* -// * Add a scalar node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_scalar(document *yaml_document_t, -// tag *yaml_char_t, value *yaml_char_t, length int, -// style yaml_scalar_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// value_copy *yaml_char_t = NULL -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// assert(value) // Non-NULL value is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (length < 0) { -// length = strlen((char *)value) -// } -// -// if (!yaml_check_utf8(value, length)) goto error -// value_copy = yaml_malloc(length+1) -// if (!value_copy) goto error -// memcpy(value_copy, value, length) -// value_copy[length] = '\0' -// -// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// yaml_free(tag_copy) -// yaml_free(value_copy) -// -// return 0 -//} -// -///* -// * Add a sequence node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_sequence(document *yaml_document_t, -// tag *yaml_char_t, style yaml_sequence_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// struct { -// start *yaml_node_item_t -// end *yaml_node_item_t -// top *yaml_node_item_t -// } items = { NULL, NULL, NULL } -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error -// -// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, -// style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// STACK_DEL(&context, items) -// yaml_free(tag_copy) -// -// return 0 -//} -// -///* -// * Add a mapping node to a document. -// */ -// -//YAML_DECLARE(int) -//yaml_document_add_mapping(document *yaml_document_t, -// tag *yaml_char_t, style yaml_mapping_style_t) -//{ -// struct { -// error yaml_error_type_t -// } context -// mark yaml_mark_t = { 0, 0, 0 } -// tag_copy *yaml_char_t = NULL -// struct { -// start *yaml_node_pair_t -// end *yaml_node_pair_t -// top *yaml_node_pair_t -// } pairs = { NULL, NULL, NULL } -// node yaml_node_t -// -// assert(document) // Non-NULL document object is expected. -// -// if (!tag) { -// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG -// } -// -// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error -// tag_copy = yaml_strdup(tag) -// if (!tag_copy) goto error -// -// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error -// -// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, -// style, mark, mark) -// if (!PUSH(&context, document.nodes, node)) goto error -// -// return document.nodes.top - document.nodes.start -// -//error: -// STACK_DEL(&context, pairs) -// yaml_free(tag_copy) -// -// return 0 -//} -// -///* -// * Append an item to a sequence node. -// */ -// -//YAML_DECLARE(int) -//yaml_document_append_sequence_item(document *yaml_document_t, -// sequence int, item int) -//{ -// struct { -// error yaml_error_type_t -// } context -// -// assert(document) // Non-NULL document is required. -// assert(sequence > 0 -// && document.nodes.start + sequence <= document.nodes.top) -// // Valid sequence id is required. -// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE) -// // A sequence node is required. -// assert(item > 0 && document.nodes.start + item <= document.nodes.top) -// // Valid item id is required. -// -// if (!PUSH(&context, -// document.nodes.start[sequence-1].data.sequence.items, item)) -// return 0 -// -// return 1 -//} -// -///* -// * Append a pair of a key and a value to a mapping node. -// */ -// -//YAML_DECLARE(int) -//yaml_document_append_mapping_pair(document *yaml_document_t, -// mapping int, key int, value int) -//{ -// struct { -// error yaml_error_type_t -// } context -// -// pair yaml_node_pair_t -// -// assert(document) // Non-NULL document is required. -// assert(mapping > 0 -// && document.nodes.start + mapping <= document.nodes.top) -// // Valid mapping id is required. -// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE) -// // A mapping node is required. -// assert(key > 0 && document.nodes.start + key <= document.nodes.top) -// // Valid key id is required. -// assert(value > 0 && document.nodes.start + value <= document.nodes.top) -// // Valid value id is required. -// -// pair.key = key -// pair.value = value -// -// if (!PUSH(&context, -// document.nodes.start[mapping-1].data.mapping.pairs, pair)) -// return 0 -// -// return 1 -//} -// -// diff --git a/vendor/gopkg.in/yaml.v3/decode.go b/vendor/gopkg.in/yaml.v3/decode.go deleted file mode 100644 index 0173b698..00000000 --- a/vendor/gopkg.in/yaml.v3/decode.go +++ /dev/null @@ -1,1000 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package yaml - -import ( - "encoding" - "encoding/base64" - "fmt" - "io" - "math" - "reflect" - "strconv" - "time" -) - -// ---------------------------------------------------------------------------- -// Parser, produces a node tree out of a libyaml event stream. - -type parser struct { - parser yaml_parser_t - event yaml_event_t - doc *Node - anchors map[string]*Node - doneInit bool - textless bool -} - -func newParser(b []byte) *parser { - p := parser{} - if !yaml_parser_initialize(&p.parser) { - panic("failed to initialize YAML emitter") - } - if len(b) == 0 { - b = []byte{'\n'} - } - yaml_parser_set_input_string(&p.parser, b) - return &p -} - -func newParserFromReader(r io.Reader) *parser { - p := parser{} - if !yaml_parser_initialize(&p.parser) { - panic("failed to initialize YAML emitter") - } - yaml_parser_set_input_reader(&p.parser, r) - return &p -} - -func (p *parser) init() { - if p.doneInit { - return - } - p.anchors = make(map[string]*Node) - p.expect(yaml_STREAM_START_EVENT) - p.doneInit = true -} - -func (p *parser) destroy() { - if p.event.typ != yaml_NO_EVENT { - yaml_event_delete(&p.event) - } - yaml_parser_delete(&p.parser) -} - -// expect consumes an event from the event stream and -// checks that it's of the expected type. -func (p *parser) expect(e yaml_event_type_t) { - if p.event.typ == yaml_NO_EVENT { - if !yaml_parser_parse(&p.parser, &p.event) { - p.fail() - } - } - if p.event.typ == yaml_STREAM_END_EVENT { - failf("attempted to go past the end of stream; corrupted value?") - } - if p.event.typ != e { - p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ) - p.fail() - } - yaml_event_delete(&p.event) - p.event.typ = yaml_NO_EVENT -} - -// peek peeks at the next event in the event stream, -// puts the results into p.event and returns the event type. -func (p *parser) peek() yaml_event_type_t { - if p.event.typ != yaml_NO_EVENT { - return p.event.typ - } - // It's curious choice from the underlying API to generally return a - // positive result on success, but on this case return true in an error - // scenario. This was the source of bugs in the past (issue #666). - if !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR { - p.fail() - } - return p.event.typ -} - -func (p *parser) fail() { - var where string - var line int - if p.parser.context_mark.line != 0 { - line = p.parser.context_mark.line - // Scanner errors don't iterate line before returning error - if p.parser.error == yaml_SCANNER_ERROR { - line++ - } - } else if p.parser.problem_mark.line != 0 { - line = p.parser.problem_mark.line - // Scanner errors don't iterate line before returning error - if p.parser.error == yaml_SCANNER_ERROR { - line++ - } - } - if line != 0 { - where = "line " + strconv.Itoa(line) + ": " - } - var msg string - if len(p.parser.problem) > 0 { - msg = p.parser.problem - } else { - msg = "unknown problem parsing YAML content" - } - failf("%s%s", where, msg) -} - -func (p *parser) anchor(n *Node, anchor []byte) { - if anchor != nil { - n.Anchor = string(anchor) - p.anchors[n.Anchor] = n - } -} - -func (p *parser) parse() *Node { - p.init() - switch p.peek() { - case yaml_SCALAR_EVENT: - return p.scalar() - case yaml_ALIAS_EVENT: - return p.alias() - case yaml_MAPPING_START_EVENT: - return p.mapping() - case yaml_SEQUENCE_START_EVENT: - return p.sequence() - case yaml_DOCUMENT_START_EVENT: - return p.document() - case yaml_STREAM_END_EVENT: - // Happens when attempting to decode an empty buffer. - return nil - case yaml_TAIL_COMMENT_EVENT: - panic("internal error: unexpected tail comment event (please report)") - default: - panic("internal error: attempted to parse unknown event (please report): " + p.event.typ.String()) - } -} - -func (p *parser) node(kind Kind, defaultTag, tag, value string) *Node { - var style Style - if tag != "" && tag != "!" { - tag = shortTag(tag) - style = TaggedStyle - } else if defaultTag != "" { - tag = defaultTag - } else if kind == ScalarNode { - tag, _ = resolve("", value) - } - n := &Node{ - Kind: kind, - Tag: tag, - Value: value, - Style: style, - } - if !p.textless { - n.Line = p.event.start_mark.line + 1 - n.Column = p.event.start_mark.column + 1 - n.HeadComment = string(p.event.head_comment) - n.LineComment = string(p.event.line_comment) - n.FootComment = string(p.event.foot_comment) - } - return n -} - -func (p *parser) parseChild(parent *Node) *Node { - child := p.parse() - parent.Content = append(parent.Content, child) - return child -} - -func (p *parser) document() *Node { - n := p.node(DocumentNode, "", "", "") - p.doc = n - p.expect(yaml_DOCUMENT_START_EVENT) - p.parseChild(n) - if p.peek() == yaml_DOCUMENT_END_EVENT { - n.FootComment = string(p.event.foot_comment) - } - p.expect(yaml_DOCUMENT_END_EVENT) - return n -} - -func (p *parser) alias() *Node { - n := p.node(AliasNode, "", "", string(p.event.anchor)) - n.Alias = p.anchors[n.Value] - if n.Alias == nil { - failf("unknown anchor '%s' referenced", n.Value) - } - p.expect(yaml_ALIAS_EVENT) - return n -} - -func (p *parser) scalar() *Node { - var parsedStyle = p.event.scalar_style() - var nodeStyle Style - switch { - case parsedStyle&yaml_DOUBLE_QUOTED_SCALAR_STYLE != 0: - nodeStyle = DoubleQuotedStyle - case parsedStyle&yaml_SINGLE_QUOTED_SCALAR_STYLE != 0: - nodeStyle = SingleQuotedStyle - case parsedStyle&yaml_LITERAL_SCALAR_STYLE != 0: - nodeStyle = LiteralStyle - case parsedStyle&yaml_FOLDED_SCALAR_STYLE != 0: - nodeStyle = FoldedStyle - } - var nodeValue = string(p.event.value) - var nodeTag = string(p.event.tag) - var defaultTag string - if nodeStyle == 0 { - if nodeValue == "<<" { - defaultTag = mergeTag - } - } else { - defaultTag = strTag - } - n := p.node(ScalarNode, defaultTag, nodeTag, nodeValue) - n.Style |= nodeStyle - p.anchor(n, p.event.anchor) - p.expect(yaml_SCALAR_EVENT) - return n -} - -func (p *parser) sequence() *Node { - n := p.node(SequenceNode, seqTag, string(p.event.tag), "") - if p.event.sequence_style()&yaml_FLOW_SEQUENCE_STYLE != 0 { - n.Style |= FlowStyle - } - p.anchor(n, p.event.anchor) - p.expect(yaml_SEQUENCE_START_EVENT) - for p.peek() != yaml_SEQUENCE_END_EVENT { - p.parseChild(n) - } - n.LineComment = string(p.event.line_comment) - n.FootComment = string(p.event.foot_comment) - p.expect(yaml_SEQUENCE_END_EVENT) - return n -} - -func (p *parser) mapping() *Node { - n := p.node(MappingNode, mapTag, string(p.event.tag), "") - block := true - if p.event.mapping_style()&yaml_FLOW_MAPPING_STYLE != 0 { - block = false - n.Style |= FlowStyle - } - p.anchor(n, p.event.anchor) - p.expect(yaml_MAPPING_START_EVENT) - for p.peek() != yaml_MAPPING_END_EVENT { - k := p.parseChild(n) - if block && k.FootComment != "" { - // Must be a foot comment for the prior value when being dedented. - if len(n.Content) > 2 { - n.Content[len(n.Content)-3].FootComment = k.FootComment - k.FootComment = "" - } - } - v := p.parseChild(n) - if k.FootComment == "" && v.FootComment != "" { - k.FootComment = v.FootComment - v.FootComment = "" - } - if p.peek() == yaml_TAIL_COMMENT_EVENT { - if k.FootComment == "" { - k.FootComment = string(p.event.foot_comment) - } - p.expect(yaml_TAIL_COMMENT_EVENT) - } - } - n.LineComment = string(p.event.line_comment) - n.FootComment = string(p.event.foot_comment) - if n.Style&FlowStyle == 0 && n.FootComment != "" && len(n.Content) > 1 { - n.Content[len(n.Content)-2].FootComment = n.FootComment - n.FootComment = "" - } - p.expect(yaml_MAPPING_END_EVENT) - return n -} - -// ---------------------------------------------------------------------------- -// Decoder, unmarshals a node into a provided value. - -type decoder struct { - doc *Node - aliases map[*Node]bool - terrors []string - - stringMapType reflect.Type - generalMapType reflect.Type - - knownFields bool - uniqueKeys bool - decodeCount int - aliasCount int - aliasDepth int - - mergedFields map[interface{}]bool -} - -var ( - nodeType = reflect.TypeOf(Node{}) - durationType = reflect.TypeOf(time.Duration(0)) - stringMapType = reflect.TypeOf(map[string]interface{}{}) - generalMapType = reflect.TypeOf(map[interface{}]interface{}{}) - ifaceType = generalMapType.Elem() - timeType = reflect.TypeOf(time.Time{}) - ptrTimeType = reflect.TypeOf(&time.Time{}) -) - -func newDecoder() *decoder { - d := &decoder{ - stringMapType: stringMapType, - generalMapType: generalMapType, - uniqueKeys: true, - } - d.aliases = make(map[*Node]bool) - return d -} - -func (d *decoder) terror(n *Node, tag string, out reflect.Value) { - if n.Tag != "" { - tag = n.Tag - } - value := n.Value - if tag != seqTag && tag != mapTag { - if len(value) > 10 { - value = " `" + value[:7] + "...`" - } else { - value = " `" + value + "`" - } - } - d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.Line, shortTag(tag), value, out.Type())) -} - -func (d *decoder) callUnmarshaler(n *Node, u Unmarshaler) (good bool) { - err := u.UnmarshalYAML(n) - if e, ok := err.(*TypeError); ok { - d.terrors = append(d.terrors, e.Errors...) - return false - } - if err != nil { - fail(err) - } - return true -} - -func (d *decoder) callObsoleteUnmarshaler(n *Node, u obsoleteUnmarshaler) (good bool) { - terrlen := len(d.terrors) - err := u.UnmarshalYAML(func(v interface{}) (err error) { - defer handleErr(&err) - d.unmarshal(n, reflect.ValueOf(v)) - if len(d.terrors) > terrlen { - issues := d.terrors[terrlen:] - d.terrors = d.terrors[:terrlen] - return &TypeError{issues} - } - return nil - }) - if e, ok := err.(*TypeError); ok { - d.terrors = append(d.terrors, e.Errors...) - return false - } - if err != nil { - fail(err) - } - return true -} - -// d.prepare initializes and dereferences pointers and calls UnmarshalYAML -// if a value is found to implement it. -// It returns the initialized and dereferenced out value, whether -// unmarshalling was already done by UnmarshalYAML, and if so whether -// its types unmarshalled appropriately. -// -// If n holds a null value, prepare returns before doing anything. -func (d *decoder) prepare(n *Node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { - if n.ShortTag() == nullTag { - return out, false, false - } - again := true - for again { - again = false - if out.Kind() == reflect.Ptr { - if out.IsNil() { - out.Set(reflect.New(out.Type().Elem())) - } - out = out.Elem() - again = true - } - if out.CanAddr() { - outi := out.Addr().Interface() - if u, ok := outi.(Unmarshaler); ok { - good = d.callUnmarshaler(n, u) - return out, true, good - } - if u, ok := outi.(obsoleteUnmarshaler); ok { - good = d.callObsoleteUnmarshaler(n, u) - return out, true, good - } - } - } - return out, false, false -} - -func (d *decoder) fieldByIndex(n *Node, v reflect.Value, index []int) (field reflect.Value) { - if n.ShortTag() == nullTag { - return reflect.Value{} - } - for _, num := range index { - for { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() - continue - } - break - } - v = v.Field(num) - } - return v -} - -const ( - // 400,000 decode operations is ~500kb of dense object declarations, or - // ~5kb of dense object declarations with 10000% alias expansion - alias_ratio_range_low = 400000 - - // 4,000,000 decode operations is ~5MB of dense object declarations, or - // ~4.5MB of dense object declarations with 10% alias expansion - alias_ratio_range_high = 4000000 - - // alias_ratio_range is the range over which we scale allowed alias ratios - alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low) -) - -func allowedAliasRatio(decodeCount int) float64 { - switch { - case decodeCount <= alias_ratio_range_low: - // allow 99% to come from alias expansion for small-to-medium documents - return 0.99 - case decodeCount >= alias_ratio_range_high: - // allow 10% to come from alias expansion for very large documents - return 0.10 - default: - // scale smoothly from 99% down to 10% over the range. - // this maps to 396,000 - 400,000 allowed alias-driven decodes over the range. - // 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps). - return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range) - } -} - -func (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) { - d.decodeCount++ - if d.aliasDepth > 0 { - d.aliasCount++ - } - if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) { - failf("document contains excessive aliasing") - } - if out.Type() == nodeType { - out.Set(reflect.ValueOf(n).Elem()) - return true - } - switch n.Kind { - case DocumentNode: - return d.document(n, out) - case AliasNode: - return d.alias(n, out) - } - out, unmarshaled, good := d.prepare(n, out) - if unmarshaled { - return good - } - switch n.Kind { - case ScalarNode: - good = d.scalar(n, out) - case MappingNode: - good = d.mapping(n, out) - case SequenceNode: - good = d.sequence(n, out) - case 0: - if n.IsZero() { - return d.null(out) - } - fallthrough - default: - failf("cannot decode node with unknown kind %d", n.Kind) - } - return good -} - -func (d *decoder) document(n *Node, out reflect.Value) (good bool) { - if len(n.Content) == 1 { - d.doc = n - d.unmarshal(n.Content[0], out) - return true - } - return false -} - -func (d *decoder) alias(n *Node, out reflect.Value) (good bool) { - if d.aliases[n] { - // TODO this could actually be allowed in some circumstances. - failf("anchor '%s' value contains itself", n.Value) - } - d.aliases[n] = true - d.aliasDepth++ - good = d.unmarshal(n.Alias, out) - d.aliasDepth-- - delete(d.aliases, n) - return good -} - -var zeroValue reflect.Value - -func resetMap(out reflect.Value) { - for _, k := range out.MapKeys() { - out.SetMapIndex(k, zeroValue) - } -} - -func (d *decoder) null(out reflect.Value) bool { - if out.CanAddr() { - switch out.Kind() { - case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - out.Set(reflect.Zero(out.Type())) - return true - } - } - return false -} - -func (d *decoder) scalar(n *Node, out reflect.Value) bool { - var tag string - var resolved interface{} - if n.indicatedString() { - tag = strTag - resolved = n.Value - } else { - tag, resolved = resolve(n.Tag, n.Value) - if tag == binaryTag { - data, err := base64.StdEncoding.DecodeString(resolved.(string)) - if err != nil { - failf("!!binary value contains invalid base64 data") - } - resolved = string(data) - } - } - if resolved == nil { - return d.null(out) - } - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { - // We've resolved to exactly the type we want, so use that. - out.Set(resolvedv) - return true - } - // Perhaps we can use the value as a TextUnmarshaler to - // set its value. - if out.CanAddr() { - u, ok := out.Addr().Interface().(encoding.TextUnmarshaler) - if ok { - var text []byte - if tag == binaryTag { - text = []byte(resolved.(string)) - } else { - // We let any value be unmarshaled into TextUnmarshaler. - // That might be more lax than we'd like, but the - // TextUnmarshaler itself should bowl out any dubious values. - text = []byte(n.Value) - } - err := u.UnmarshalText(text) - if err != nil { - fail(err) - } - return true - } - } - switch out.Kind() { - case reflect.String: - if tag == binaryTag { - out.SetString(resolved.(string)) - return true - } - out.SetString(n.Value) - return true - case reflect.Interface: - out.Set(reflect.ValueOf(resolved)) - return true - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - // This used to work in v2, but it's very unfriendly. - isDuration := out.Type() == durationType - - switch resolved := resolved.(type) { - case int: - if !isDuration && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case int64: - if !isDuration && !out.OverflowInt(resolved) { - out.SetInt(resolved) - return true - } - case uint64: - if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case float64: - if !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { - out.SetInt(int64(resolved)) - return true - } - case string: - if out.Type() == durationType { - d, err := time.ParseDuration(resolved) - if err == nil { - out.SetInt(int64(d)) - return true - } - } - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - switch resolved := resolved.(type) { - case int: - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case int64: - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case uint64: - if !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - case float64: - if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { - out.SetUint(uint64(resolved)) - return true - } - } - case reflect.Bool: - switch resolved := resolved.(type) { - case bool: - out.SetBool(resolved) - return true - case string: - // This offers some compatibility with the 1.1 spec (https://yaml.org/type/bool.html). - // It only works if explicitly attempting to unmarshal into a typed bool value. - switch resolved { - case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON": - out.SetBool(true) - return true - case "n", "N", "no", "No", "NO", "off", "Off", "OFF": - out.SetBool(false) - return true - } - } - case reflect.Float32, reflect.Float64: - switch resolved := resolved.(type) { - case int: - out.SetFloat(float64(resolved)) - return true - case int64: - out.SetFloat(float64(resolved)) - return true - case uint64: - out.SetFloat(float64(resolved)) - return true - case float64: - out.SetFloat(resolved) - return true - } - case reflect.Struct: - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { - out.Set(resolvedv) - return true - } - case reflect.Ptr: - panic("yaml internal error: please report the issue") - } - d.terror(n, tag, out) - return false -} - -func settableValueOf(i interface{}) reflect.Value { - v := reflect.ValueOf(i) - sv := reflect.New(v.Type()).Elem() - sv.Set(v) - return sv -} - -func (d *decoder) sequence(n *Node, out reflect.Value) (good bool) { - l := len(n.Content) - - var iface reflect.Value - switch out.Kind() { - case reflect.Slice: - out.Set(reflect.MakeSlice(out.Type(), l, l)) - case reflect.Array: - if l != out.Len() { - failf("invalid array: want %d elements but got %d", out.Len(), l) - } - case reflect.Interface: - // No type hints. Will have to use a generic sequence. - iface = out - out = settableValueOf(make([]interface{}, l)) - default: - d.terror(n, seqTag, out) - return false - } - et := out.Type().Elem() - - j := 0 - for i := 0; i < l; i++ { - e := reflect.New(et).Elem() - if ok := d.unmarshal(n.Content[i], e); ok { - out.Index(j).Set(e) - j++ - } - } - if out.Kind() != reflect.Array { - out.Set(out.Slice(0, j)) - } - if iface.IsValid() { - iface.Set(out) - } - return true -} - -func (d *decoder) mapping(n *Node, out reflect.Value) (good bool) { - l := len(n.Content) - if d.uniqueKeys { - nerrs := len(d.terrors) - for i := 0; i < l; i += 2 { - ni := n.Content[i] - for j := i + 2; j < l; j += 2 { - nj := n.Content[j] - if ni.Kind == nj.Kind && ni.Value == nj.Value { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: mapping key %#v already defined at line %d", nj.Line, nj.Value, ni.Line)) - } - } - } - if len(d.terrors) > nerrs { - return false - } - } - switch out.Kind() { - case reflect.Struct: - return d.mappingStruct(n, out) - case reflect.Map: - // okay - case reflect.Interface: - iface := out - if isStringMap(n) { - out = reflect.MakeMap(d.stringMapType) - } else { - out = reflect.MakeMap(d.generalMapType) - } - iface.Set(out) - default: - d.terror(n, mapTag, out) - return false - } - - outt := out.Type() - kt := outt.Key() - et := outt.Elem() - - stringMapType := d.stringMapType - generalMapType := d.generalMapType - if outt.Elem() == ifaceType { - if outt.Key().Kind() == reflect.String { - d.stringMapType = outt - } else if outt.Key() == ifaceType { - d.generalMapType = outt - } - } - - mergedFields := d.mergedFields - d.mergedFields = nil - - var mergeNode *Node - - mapIsNew := false - if out.IsNil() { - out.Set(reflect.MakeMap(outt)) - mapIsNew = true - } - for i := 0; i < l; i += 2 { - if isMerge(n.Content[i]) { - mergeNode = n.Content[i+1] - continue - } - k := reflect.New(kt).Elem() - if d.unmarshal(n.Content[i], k) { - if mergedFields != nil { - ki := k.Interface() - if mergedFields[ki] { - continue - } - mergedFields[ki] = true - } - kkind := k.Kind() - if kkind == reflect.Interface { - kkind = k.Elem().Kind() - } - if kkind == reflect.Map || kkind == reflect.Slice { - failf("invalid map key: %#v", k.Interface()) - } - e := reflect.New(et).Elem() - if d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) { - out.SetMapIndex(k, e) - } - } - } - - d.mergedFields = mergedFields - if mergeNode != nil { - d.merge(n, mergeNode, out) - } - - d.stringMapType = stringMapType - d.generalMapType = generalMapType - return true -} - -func isStringMap(n *Node) bool { - if n.Kind != MappingNode { - return false - } - l := len(n.Content) - for i := 0; i < l; i += 2 { - shortTag := n.Content[i].ShortTag() - if shortTag != strTag && shortTag != mergeTag { - return false - } - } - return true -} - -func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) { - sinfo, err := getStructInfo(out.Type()) - if err != nil { - panic(err) - } - - var inlineMap reflect.Value - var elemType reflect.Type - if sinfo.InlineMap != -1 { - inlineMap = out.Field(sinfo.InlineMap) - elemType = inlineMap.Type().Elem() - } - - for _, index := range sinfo.InlineUnmarshalers { - field := d.fieldByIndex(n, out, index) - d.prepare(n, field) - } - - mergedFields := d.mergedFields - d.mergedFields = nil - var mergeNode *Node - var doneFields []bool - if d.uniqueKeys { - doneFields = make([]bool, len(sinfo.FieldsList)) - } - name := settableValueOf("") - l := len(n.Content) - for i := 0; i < l; i += 2 { - ni := n.Content[i] - if isMerge(ni) { - mergeNode = n.Content[i+1] - continue - } - if !d.unmarshal(ni, name) { - continue - } - sname := name.String() - if mergedFields != nil { - if mergedFields[sname] { - continue - } - mergedFields[sname] = true - } - if info, ok := sinfo.FieldsMap[sname]; ok { - if d.uniqueKeys { - if doneFields[info.Id] { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.Line, name.String(), out.Type())) - continue - } - doneFields[info.Id] = true - } - var field reflect.Value - if info.Inline == nil { - field = out.Field(info.Num) - } else { - field = d.fieldByIndex(n, out, info.Inline) - } - d.unmarshal(n.Content[i+1], field) - } else if sinfo.InlineMap != -1 { - if inlineMap.IsNil() { - inlineMap.Set(reflect.MakeMap(inlineMap.Type())) - } - value := reflect.New(elemType).Elem() - d.unmarshal(n.Content[i+1], value) - inlineMap.SetMapIndex(name, value) - } else if d.knownFields { - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type())) - } - } - - d.mergedFields = mergedFields - if mergeNode != nil { - d.merge(n, mergeNode, out) - } - return true -} - -func failWantMap() { - failf("map merge requires map or sequence of maps as the value") -} - -func (d *decoder) merge(parent *Node, merge *Node, out reflect.Value) { - mergedFields := d.mergedFields - if mergedFields == nil { - d.mergedFields = make(map[interface{}]bool) - for i := 0; i < len(parent.Content); i += 2 { - k := reflect.New(ifaceType).Elem() - if d.unmarshal(parent.Content[i], k) { - d.mergedFields[k.Interface()] = true - } - } - } - - switch merge.Kind { - case MappingNode: - d.unmarshal(merge, out) - case AliasNode: - if merge.Alias != nil && merge.Alias.Kind != MappingNode { - failWantMap() - } - d.unmarshal(merge, out) - case SequenceNode: - for i := 0; i < len(merge.Content); i++ { - ni := merge.Content[i] - if ni.Kind == AliasNode { - if ni.Alias != nil && ni.Alias.Kind != MappingNode { - failWantMap() - } - } else if ni.Kind != MappingNode { - failWantMap() - } - d.unmarshal(ni, out) - } - default: - failWantMap() - } - - d.mergedFields = mergedFields -} - -func isMerge(n *Node) bool { - return n.Kind == ScalarNode && n.Value == "<<" && (n.Tag == "" || n.Tag == "!" || shortTag(n.Tag) == mergeTag) -} diff --git a/vendor/gopkg.in/yaml.v3/emitterc.go b/vendor/gopkg.in/yaml.v3/emitterc.go deleted file mode 100644 index 0f47c9ca..00000000 --- a/vendor/gopkg.in/yaml.v3/emitterc.go +++ /dev/null @@ -1,2020 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -import ( - "bytes" - "fmt" -) - -// Flush the buffer if needed. -func flush(emitter *yaml_emitter_t) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) { - return yaml_emitter_flush(emitter) - } - return true -} - -// Put a character to the output buffer. -func put(emitter *yaml_emitter_t, value byte) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - emitter.buffer[emitter.buffer_pos] = value - emitter.buffer_pos++ - emitter.column++ - return true -} - -// Put a line break to the output buffer. -func put_break(emitter *yaml_emitter_t) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - switch emitter.line_break { - case yaml_CR_BREAK: - emitter.buffer[emitter.buffer_pos] = '\r' - emitter.buffer_pos += 1 - case yaml_LN_BREAK: - emitter.buffer[emitter.buffer_pos] = '\n' - emitter.buffer_pos += 1 - case yaml_CRLN_BREAK: - emitter.buffer[emitter.buffer_pos+0] = '\r' - emitter.buffer[emitter.buffer_pos+1] = '\n' - emitter.buffer_pos += 2 - default: - panic("unknown line break setting") - } - if emitter.column == 0 { - emitter.space_above = true - } - emitter.column = 0 - emitter.line++ - // [Go] Do this here and below and drop from everywhere else (see commented lines). - emitter.indention = true - return true -} - -// Copy a character from a string into buffer. -func write(emitter *yaml_emitter_t, s []byte, i *int) bool { - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { - return false - } - p := emitter.buffer_pos - w := width(s[*i]) - switch w { - case 4: - emitter.buffer[p+3] = s[*i+3] - fallthrough - case 3: - emitter.buffer[p+2] = s[*i+2] - fallthrough - case 2: - emitter.buffer[p+1] = s[*i+1] - fallthrough - case 1: - emitter.buffer[p+0] = s[*i+0] - default: - panic("unknown character width") - } - emitter.column++ - emitter.buffer_pos += w - *i += w - return true -} - -// Write a whole string into buffer. -func write_all(emitter *yaml_emitter_t, s []byte) bool { - for i := 0; i < len(s); { - if !write(emitter, s, &i) { - return false - } - } - return true -} - -// Copy a line break character from a string into buffer. -func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { - if s[*i] == '\n' { - if !put_break(emitter) { - return false - } - *i++ - } else { - if !write(emitter, s, i) { - return false - } - if emitter.column == 0 { - emitter.space_above = true - } - emitter.column = 0 - emitter.line++ - // [Go] Do this here and above and drop from everywhere else (see commented lines). - emitter.indention = true - } - return true -} - -// Set an emitter error and return false. -func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { - emitter.error = yaml_EMITTER_ERROR - emitter.problem = problem - return false -} - -// Emit an event. -func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { - emitter.events = append(emitter.events, *event) - for !yaml_emitter_need_more_events(emitter) { - event := &emitter.events[emitter.events_head] - if !yaml_emitter_analyze_event(emitter, event) { - return false - } - if !yaml_emitter_state_machine(emitter, event) { - return false - } - yaml_event_delete(event) - emitter.events_head++ - } - return true -} - -// Check if we need to accumulate more events before emitting. -// -// We accumulate extra -// - 1 event for DOCUMENT-START -// - 2 events for SEQUENCE-START -// - 3 events for MAPPING-START -// -func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { - if emitter.events_head == len(emitter.events) { - return true - } - var accumulate int - switch emitter.events[emitter.events_head].typ { - case yaml_DOCUMENT_START_EVENT: - accumulate = 1 - break - case yaml_SEQUENCE_START_EVENT: - accumulate = 2 - break - case yaml_MAPPING_START_EVENT: - accumulate = 3 - break - default: - return false - } - if len(emitter.events)-emitter.events_head > accumulate { - return false - } - var level int - for i := emitter.events_head; i < len(emitter.events); i++ { - switch emitter.events[i].typ { - case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: - level++ - case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: - level-- - } - if level == 0 { - return false - } - } - return true -} - -// Append a directive to the directives stack. -func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { - for i := 0; i < len(emitter.tag_directives); i++ { - if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { - if allow_duplicates { - return true - } - return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") - } - } - - // [Go] Do we actually need to copy this given garbage collection - // and the lack of deallocating destructors? - tag_copy := yaml_tag_directive_t{ - handle: make([]byte, len(value.handle)), - prefix: make([]byte, len(value.prefix)), - } - copy(tag_copy.handle, value.handle) - copy(tag_copy.prefix, value.prefix) - emitter.tag_directives = append(emitter.tag_directives, tag_copy) - return true -} - -// Increase the indentation level. -func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { - emitter.indents = append(emitter.indents, emitter.indent) - if emitter.indent < 0 { - if flow { - emitter.indent = emitter.best_indent - } else { - emitter.indent = 0 - } - } else if !indentless { - // [Go] This was changed so that indentations are more regular. - if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE { - // The first indent inside a sequence will just skip the "- " indicator. - emitter.indent += 2 - } else { - // Everything else aligns to the chosen indentation. - emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent) - } - } - return true -} - -// State dispatcher. -func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { - switch emitter.state { - default: - case yaml_EMIT_STREAM_START_STATE: - return yaml_emitter_emit_stream_start(emitter, event) - - case yaml_EMIT_FIRST_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, true) - - case yaml_EMIT_DOCUMENT_START_STATE: - return yaml_emitter_emit_document_start(emitter, event, false) - - case yaml_EMIT_DOCUMENT_CONTENT_STATE: - return yaml_emitter_emit_document_content(emitter, event) - - case yaml_EMIT_DOCUMENT_END_STATE: - return yaml_emitter_emit_document_end(emitter, event) - - case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, true, false) - - case yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, false, true) - - case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_flow_sequence_item(emitter, event, false, false) - - case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, true, false) - - case yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, false, true) - - case yaml_EMIT_FLOW_MAPPING_KEY_STATE: - return yaml_emitter_emit_flow_mapping_key(emitter, event, false, false) - - case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, true) - - case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: - return yaml_emitter_emit_flow_mapping_value(emitter, event, false) - - case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, true) - - case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: - return yaml_emitter_emit_block_sequence_item(emitter, event, false) - - case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, true) - - case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: - return yaml_emitter_emit_block_mapping_key(emitter, event, false) - - case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, true) - - case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: - return yaml_emitter_emit_block_mapping_value(emitter, event, false) - - case yaml_EMIT_END_STATE: - return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") - } - panic("invalid emitter state") -} - -// Expect STREAM-START. -func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if event.typ != yaml_STREAM_START_EVENT { - return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") - } - if emitter.encoding == yaml_ANY_ENCODING { - emitter.encoding = event.encoding - if emitter.encoding == yaml_ANY_ENCODING { - emitter.encoding = yaml_UTF8_ENCODING - } - } - if emitter.best_indent < 2 || emitter.best_indent > 9 { - emitter.best_indent = 2 - } - if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { - emitter.best_width = 80 - } - if emitter.best_width < 0 { - emitter.best_width = 1<<31 - 1 - } - if emitter.line_break == yaml_ANY_BREAK { - emitter.line_break = yaml_LN_BREAK - } - - emitter.indent = -1 - emitter.line = 0 - emitter.column = 0 - emitter.whitespace = true - emitter.indention = true - emitter.space_above = true - emitter.foot_indent = -1 - - if emitter.encoding != yaml_UTF8_ENCODING { - if !yaml_emitter_write_bom(emitter) { - return false - } - } - emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE - return true -} - -// Expect DOCUMENT-START or STREAM-END. -func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - - if event.typ == yaml_DOCUMENT_START_EVENT { - - if event.version_directive != nil { - if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { - return false - } - } - - for i := 0; i < len(event.tag_directives); i++ { - tag_directive := &event.tag_directives[i] - if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { - return false - } - if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { - return false - } - } - - for i := 0; i < len(default_tag_directives); i++ { - tag_directive := &default_tag_directives[i] - if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { - return false - } - } - - implicit := event.implicit - if !first || emitter.canonical { - implicit = false - } - - if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if event.version_directive != nil { - implicit = false - if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if len(event.tag_directives) > 0 { - implicit = false - for i := 0; i < len(event.tag_directives); i++ { - tag_directive := &event.tag_directives[i] - if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { - return false - } - if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { - return false - } - if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - } - - if yaml_emitter_check_empty_document(emitter) { - implicit = false - } - if !implicit { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { - return false - } - if emitter.canonical || true { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - } - - if len(emitter.head_comment) > 0 { - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if !put_break(emitter) { - return false - } - } - - emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE - return true - } - - if event.typ == yaml_STREAM_END_EVENT { - if emitter.open_ended { - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_flush(emitter) { - return false - } - emitter.state = yaml_EMIT_END_STATE - return true - } - - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") -} - -// Expect the root node. -func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { - emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) - - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if !yaml_emitter_emit_node(emitter, event, true, false, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect DOCUMENT-END. -func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if event.typ != yaml_DOCUMENT_END_EVENT { - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") - } - // [Go] Force document foot separation. - emitter.foot_indent = 0 - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - emitter.foot_indent = -1 - if !yaml_emitter_write_indent(emitter) { - return false - } - if !event.implicit { - // [Go] Allocate the slice elsewhere. - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_flush(emitter) { - return false - } - emitter.state = yaml_EMIT_DOCUMENT_START_STATE - emitter.tag_directives = emitter.tag_directives[:0] - return true -} - -// Expect a flow item node. -func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool { - if first { - if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - emitter.flow_level++ - } - - if event.typ == yaml_SEQUENCE_END_EVENT { - if emitter.canonical && !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - emitter.flow_level-- - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - if emitter.column == 0 || emitter.canonical && !first { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - - return true - } - - if !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if emitter.column == 0 { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE) - } else { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) - } - if !yaml_emitter_emit_node(emitter, event, false, true, false, false) { - return false - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect a flow key node. -func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool { - if first { - if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - emitter.flow_level++ - } - - if event.typ == yaml_MAPPING_END_EVENT { - if (emitter.canonical || len(emitter.head_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0) && !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - if !yaml_emitter_process_head_comment(emitter) { - return false - } - emitter.flow_level-- - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - if emitter.canonical && !first { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - - if !first && !trail { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - - if !yaml_emitter_process_head_comment(emitter) { - return false - } - - if emitter.column == 0 { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - - if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, true) - } - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a flow value node. -func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { - if simple { - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { - return false - } - } else { - if emitter.canonical || emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { - return false - } - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE) - } else { - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) - } - if !yaml_emitter_emit_node(emitter, event, false, false, true, false) { - return false - } - if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 { - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { - return false - } - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect a block item node. -func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_increase_indent(emitter, false, false) { - return false - } - } - if event.typ == yaml_SEQUENCE_END_EVENT { - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) - if !yaml_emitter_emit_node(emitter, event, false, true, false, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -// Expect a block key node. -func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { - if first { - if !yaml_emitter_increase_indent(emitter, false, false) { - return false - } - } - if !yaml_emitter_process_head_comment(emitter) { - return false - } - if event.typ == yaml_MAPPING_END_EVENT { - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if len(emitter.line_comment) > 0 { - // [Go] A line comment was provided for the key. That's unusual as the - // scanner associates line comments with the value. Either way, - // save the line comment and render it appropriately later. - emitter.key_line_comment = emitter.line_comment - emitter.line_comment = nil - } - if yaml_emitter_check_simple_key(emitter) { - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, true) - } - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { - return false - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) - return yaml_emitter_emit_node(emitter, event, false, false, true, false) -} - -// Expect a block value node. -func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { - if simple { - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { - return false - } - } else { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { - return false - } - } - if len(emitter.key_line_comment) > 0 { - // [Go] Line comments are generally associated with the value, but when there's - // no value on the same line as a mapping key they end up attached to the - // key itself. - if event.typ == yaml_SCALAR_EVENT { - if len(emitter.line_comment) == 0 { - // A scalar is coming and it has no line comments by itself yet, - // so just let it handle the line comment as usual. If it has a - // line comment, we can't have both so the one from the key is lost. - emitter.line_comment = emitter.key_line_comment - emitter.key_line_comment = nil - } - } else if event.sequence_style() != yaml_FLOW_SEQUENCE_STYLE && (event.typ == yaml_MAPPING_START_EVENT || event.typ == yaml_SEQUENCE_START_EVENT) { - // An indented block follows, so write the comment right now. - emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment - if !yaml_emitter_process_line_comment(emitter) { - return false - } - emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment - } - } - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) - if !yaml_emitter_emit_node(emitter, event, false, false, true, false) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - if !yaml_emitter_process_foot_comment(emitter) { - return false - } - return true -} - -func yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { - return event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0 -} - -// Expect a node. -func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, - root bool, sequence bool, mapping bool, simple_key bool) bool { - - emitter.root_context = root - emitter.sequence_context = sequence - emitter.mapping_context = mapping - emitter.simple_key_context = simple_key - - switch event.typ { - case yaml_ALIAS_EVENT: - return yaml_emitter_emit_alias(emitter, event) - case yaml_SCALAR_EVENT: - return yaml_emitter_emit_scalar(emitter, event) - case yaml_SEQUENCE_START_EVENT: - return yaml_emitter_emit_sequence_start(emitter, event) - case yaml_MAPPING_START_EVENT: - return yaml_emitter_emit_mapping_start(emitter, event) - default: - return yaml_emitter_set_emitter_error(emitter, - fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ)) - } -} - -// Expect ALIAS. -func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true -} - -// Expect SCALAR. -func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_select_scalar_style(emitter, event) { - return false - } - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if !yaml_emitter_increase_indent(emitter, true, false) { - return false - } - if !yaml_emitter_process_scalar(emitter) { - return false - } - emitter.indent = emitter.indents[len(emitter.indents)-1] - emitter.indents = emitter.indents[:len(emitter.indents)-1] - emitter.state = emitter.states[len(emitter.states)-1] - emitter.states = emitter.states[:len(emitter.states)-1] - return true -} - -// Expect SEQUENCE-START. -func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || - yaml_emitter_check_empty_sequence(emitter) { - emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE - } else { - emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE - } - return true -} - -// Expect MAPPING-START. -func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { - if !yaml_emitter_process_anchor(emitter) { - return false - } - if !yaml_emitter_process_tag(emitter) { - return false - } - if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || - yaml_emitter_check_empty_mapping(emitter) { - emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE - } else { - emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE - } - return true -} - -// Check if the document content is an empty scalar. -func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { - return false // [Go] Huh? -} - -// Check if the next events represent an empty sequence. -func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { - if len(emitter.events)-emitter.events_head < 2 { - return false - } - return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && - emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT -} - -// Check if the next events represent an empty mapping. -func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { - if len(emitter.events)-emitter.events_head < 2 { - return false - } - return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && - emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT -} - -// Check if the next node can be expressed as a simple key. -func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { - length := 0 - switch emitter.events[emitter.events_head].typ { - case yaml_ALIAS_EVENT: - length += len(emitter.anchor_data.anchor) - case yaml_SCALAR_EVENT: - if emitter.scalar_data.multiline { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) + - len(emitter.scalar_data.value) - case yaml_SEQUENCE_START_EVENT: - if !yaml_emitter_check_empty_sequence(emitter) { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) - case yaml_MAPPING_START_EVENT: - if !yaml_emitter_check_empty_mapping(emitter) { - return false - } - length += len(emitter.anchor_data.anchor) + - len(emitter.tag_data.handle) + - len(emitter.tag_data.suffix) - default: - return false - } - return length <= 128 -} - -// Determine an acceptable scalar style. -func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { - - no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 - if no_tag && !event.implicit && !event.quoted_implicit { - return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") - } - - style := event.scalar_style() - if style == yaml_ANY_SCALAR_STYLE { - style = yaml_PLAIN_SCALAR_STYLE - } - if emitter.canonical { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - if emitter.simple_key_context && emitter.scalar_data.multiline { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - - if style == yaml_PLAIN_SCALAR_STYLE { - if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || - emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - if no_tag && !event.implicit { - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - } - } - if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { - if !emitter.scalar_data.single_quoted_allowed { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - } - if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { - if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - } - - if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { - emitter.tag_data.handle = []byte{'!'} - } - emitter.scalar_data.style = style - return true -} - -// Write an anchor. -func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { - if emitter.anchor_data.anchor == nil { - return true - } - c := []byte{'&'} - if emitter.anchor_data.alias { - c[0] = '*' - } - if !yaml_emitter_write_indicator(emitter, c, true, false, false) { - return false - } - return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) -} - -// Write a tag. -func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { - if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { - return true - } - if len(emitter.tag_data.handle) > 0 { - if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { - return false - } - if len(emitter.tag_data.suffix) > 0 { - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { - return false - } - } - } else { - // [Go] Allocate these slices elsewhere. - if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { - return false - } - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { - return false - } - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { - return false - } - } - return true -} - -// Write a scalar. -func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { - switch emitter.scalar_data.style { - case yaml_PLAIN_SCALAR_STYLE: - return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_SINGLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_DOUBLE_QUOTED_SCALAR_STYLE: - return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) - - case yaml_LITERAL_SCALAR_STYLE: - return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) - - case yaml_FOLDED_SCALAR_STYLE: - return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) - } - panic("unknown scalar style") -} - -// Write a head comment. -func yaml_emitter_process_head_comment(emitter *yaml_emitter_t) bool { - if len(emitter.tail_comment) > 0 { - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_comment(emitter, emitter.tail_comment) { - return false - } - emitter.tail_comment = emitter.tail_comment[:0] - emitter.foot_indent = emitter.indent - if emitter.foot_indent < 0 { - emitter.foot_indent = 0 - } - } - - if len(emitter.head_comment) == 0 { - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_comment(emitter, emitter.head_comment) { - return false - } - emitter.head_comment = emitter.head_comment[:0] - return true -} - -// Write an line comment. -func yaml_emitter_process_line_comment(emitter *yaml_emitter_t) bool { - if len(emitter.line_comment) == 0 { - return true - } - if !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !yaml_emitter_write_comment(emitter, emitter.line_comment) { - return false - } - emitter.line_comment = emitter.line_comment[:0] - return true -} - -// Write a foot comment. -func yaml_emitter_process_foot_comment(emitter *yaml_emitter_t) bool { - if len(emitter.foot_comment) == 0 { - return true - } - if !yaml_emitter_write_indent(emitter) { - return false - } - if !yaml_emitter_write_comment(emitter, emitter.foot_comment) { - return false - } - emitter.foot_comment = emitter.foot_comment[:0] - emitter.foot_indent = emitter.indent - if emitter.foot_indent < 0 { - emitter.foot_indent = 0 - } - return true -} - -// Check if a %YAML directive is valid. -func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { - if version_directive.major != 1 || version_directive.minor != 1 { - return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") - } - return true -} - -// Check if a %TAG directive is valid. -func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { - handle := tag_directive.handle - prefix := tag_directive.prefix - if len(handle) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") - } - if handle[0] != '!' { - return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") - } - if handle[len(handle)-1] != '!' { - return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") - } - for i := 1; i < len(handle)-1; i += width(handle[i]) { - if !is_alpha(handle, i) { - return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") - } - } - if len(prefix) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") - } - return true -} - -// Check if an anchor is valid. -func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { - if len(anchor) == 0 { - problem := "anchor value must not be empty" - if alias { - problem = "alias value must not be empty" - } - return yaml_emitter_set_emitter_error(emitter, problem) - } - for i := 0; i < len(anchor); i += width(anchor[i]) { - if !is_alpha(anchor, i) { - problem := "anchor value must contain alphanumerical characters only" - if alias { - problem = "alias value must contain alphanumerical characters only" - } - return yaml_emitter_set_emitter_error(emitter, problem) - } - } - emitter.anchor_data.anchor = anchor - emitter.anchor_data.alias = alias - return true -} - -// Check if a tag is valid. -func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { - if len(tag) == 0 { - return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") - } - for i := 0; i < len(emitter.tag_directives); i++ { - tag_directive := &emitter.tag_directives[i] - if bytes.HasPrefix(tag, tag_directive.prefix) { - emitter.tag_data.handle = tag_directive.handle - emitter.tag_data.suffix = tag[len(tag_directive.prefix):] - return true - } - } - emitter.tag_data.suffix = tag - return true -} - -// Check if a scalar is valid. -func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { - var ( - block_indicators = false - flow_indicators = false - line_breaks = false - special_characters = false - tab_characters = false - - leading_space = false - leading_break = false - trailing_space = false - trailing_break = false - break_space = false - space_break = false - - preceded_by_whitespace = false - followed_by_whitespace = false - previous_space = false - previous_break = false - ) - - emitter.scalar_data.value = value - - if len(value) == 0 { - emitter.scalar_data.multiline = false - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = true - emitter.scalar_data.single_quoted_allowed = true - emitter.scalar_data.block_allowed = false - return true - } - - if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { - block_indicators = true - flow_indicators = true - } - - preceded_by_whitespace = true - for i, w := 0, 0; i < len(value); i += w { - w = width(value[i]) - followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) - - if i == 0 { - switch value[i] { - case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': - flow_indicators = true - block_indicators = true - case '?', ':': - flow_indicators = true - if followed_by_whitespace { - block_indicators = true - } - case '-': - if followed_by_whitespace { - flow_indicators = true - block_indicators = true - } - } - } else { - switch value[i] { - case ',', '?', '[', ']', '{', '}': - flow_indicators = true - case ':': - flow_indicators = true - if followed_by_whitespace { - block_indicators = true - } - case '#': - if preceded_by_whitespace { - flow_indicators = true - block_indicators = true - } - } - } - - if value[i] == '\t' { - tab_characters = true - } else if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { - special_characters = true - } - if is_space(value, i) { - if i == 0 { - leading_space = true - } - if i+width(value[i]) == len(value) { - trailing_space = true - } - if previous_break { - break_space = true - } - previous_space = true - previous_break = false - } else if is_break(value, i) { - line_breaks = true - if i == 0 { - leading_break = true - } - if i+width(value[i]) == len(value) { - trailing_break = true - } - if previous_space { - space_break = true - } - previous_space = false - previous_break = true - } else { - previous_space = false - previous_break = false - } - - // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. - preceded_by_whitespace = is_blankz(value, i) - } - - emitter.scalar_data.multiline = line_breaks - emitter.scalar_data.flow_plain_allowed = true - emitter.scalar_data.block_plain_allowed = true - emitter.scalar_data.single_quoted_allowed = true - emitter.scalar_data.block_allowed = true - - if leading_space || leading_break || trailing_space || trailing_break { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - } - if trailing_space { - emitter.scalar_data.block_allowed = false - } - if break_space { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - emitter.scalar_data.single_quoted_allowed = false - } - if space_break || tab_characters || special_characters { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - emitter.scalar_data.single_quoted_allowed = false - } - if space_break || special_characters { - emitter.scalar_data.block_allowed = false - } - if line_breaks { - emitter.scalar_data.flow_plain_allowed = false - emitter.scalar_data.block_plain_allowed = false - } - if flow_indicators { - emitter.scalar_data.flow_plain_allowed = false - } - if block_indicators { - emitter.scalar_data.block_plain_allowed = false - } - return true -} - -// Check if the event data is valid. -func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { - - emitter.anchor_data.anchor = nil - emitter.tag_data.handle = nil - emitter.tag_data.suffix = nil - emitter.scalar_data.value = nil - - if len(event.head_comment) > 0 { - emitter.head_comment = event.head_comment - } - if len(event.line_comment) > 0 { - emitter.line_comment = event.line_comment - } - if len(event.foot_comment) > 0 { - emitter.foot_comment = event.foot_comment - } - if len(event.tail_comment) > 0 { - emitter.tail_comment = event.tail_comment - } - - switch event.typ { - case yaml_ALIAS_EVENT: - if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { - return false - } - - case yaml_SCALAR_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - if !yaml_emitter_analyze_scalar(emitter, event.value) { - return false - } - - case yaml_SEQUENCE_START_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - - case yaml_MAPPING_START_EVENT: - if len(event.anchor) > 0 { - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { - return false - } - } - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { - if !yaml_emitter_analyze_tag(emitter, event.tag) { - return false - } - } - } - return true -} - -// Write the BOM character. -func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { - if !flush(emitter) { - return false - } - pos := emitter.buffer_pos - emitter.buffer[pos+0] = '\xEF' - emitter.buffer[pos+1] = '\xBB' - emitter.buffer[pos+2] = '\xBF' - emitter.buffer_pos += 3 - return true -} - -func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { - indent := emitter.indent - if indent < 0 { - indent = 0 - } - if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { - if !put_break(emitter) { - return false - } - } - if emitter.foot_indent == indent { - if !put_break(emitter) { - return false - } - } - for emitter.column < indent { - if !put(emitter, ' ') { - return false - } - } - emitter.whitespace = true - //emitter.indention = true - emitter.space_above = false - emitter.foot_indent = -1 - return true -} - -func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { - if need_whitespace && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !write_all(emitter, indicator) { - return false - } - emitter.whitespace = is_whitespace - emitter.indention = (emitter.indention && is_indention) - emitter.open_ended = false - return true -} - -func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { - if !write_all(emitter, value) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { - if !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - if !write_all(emitter, value) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { - if need_whitespace && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - for i := 0; i < len(value); { - var must_write bool - switch value[i] { - case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': - must_write = true - default: - must_write = is_alpha(value, i) - } - if must_write { - if !write(emitter, value, &i) { - return false - } - } else { - w := width(value[i]) - for k := 0; k < w; k++ { - octet := value[i] - i++ - if !put(emitter, '%') { - return false - } - - c := octet >> 4 - if c < 10 { - c += '0' - } else { - c += 'A' - 10 - } - if !put(emitter, c) { - return false - } - - c = octet & 0x0f - if c < 10 { - c += '0' - } else { - c += 'A' - 10 - } - if !put(emitter, c) { - return false - } - } - } - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - if len(value) > 0 && !emitter.whitespace { - if !put(emitter, ' ') { - return false - } - } - - spaces := false - breaks := false - for i := 0; i < len(value); { - if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - spaces = true - } else if is_break(value, i) { - if !breaks && value[i] == '\n' { - if !put_break(emitter) { - return false - } - } - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - spaces = false - breaks = false - } - } - - if len(value) > 0 { - emitter.whitespace = false - } - emitter.indention = false - if emitter.root_context { - emitter.open_ended = true - } - - return true -} - -func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { - return false - } - - spaces := false - breaks := false - for i := 0; i < len(value); { - if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - spaces = true - } else if is_break(value, i) { - if !breaks && value[i] == '\n' { - if !put_break(emitter) { - return false - } - } - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if value[i] == '\'' { - if !put(emitter, '\'') { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - spaces = false - breaks = false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { - spaces := false - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { - return false - } - - for i := 0; i < len(value); { - if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || - is_bom(value, i) || is_break(value, i) || - value[i] == '"' || value[i] == '\\' { - - octet := value[i] - - var w int - var v rune - switch { - case octet&0x80 == 0x00: - w, v = 1, rune(octet&0x7F) - case octet&0xE0 == 0xC0: - w, v = 2, rune(octet&0x1F) - case octet&0xF0 == 0xE0: - w, v = 3, rune(octet&0x0F) - case octet&0xF8 == 0xF0: - w, v = 4, rune(octet&0x07) - } - for k := 1; k < w; k++ { - octet = value[i+k] - v = (v << 6) + (rune(octet) & 0x3F) - } - i += w - - if !put(emitter, '\\') { - return false - } - - var ok bool - switch v { - case 0x00: - ok = put(emitter, '0') - case 0x07: - ok = put(emitter, 'a') - case 0x08: - ok = put(emitter, 'b') - case 0x09: - ok = put(emitter, 't') - case 0x0A: - ok = put(emitter, 'n') - case 0x0b: - ok = put(emitter, 'v') - case 0x0c: - ok = put(emitter, 'f') - case 0x0d: - ok = put(emitter, 'r') - case 0x1b: - ok = put(emitter, 'e') - case 0x22: - ok = put(emitter, '"') - case 0x5c: - ok = put(emitter, '\\') - case 0x85: - ok = put(emitter, 'N') - case 0xA0: - ok = put(emitter, '_') - case 0x2028: - ok = put(emitter, 'L') - case 0x2029: - ok = put(emitter, 'P') - default: - if v <= 0xFF { - ok = put(emitter, 'x') - w = 2 - } else if v <= 0xFFFF { - ok = put(emitter, 'u') - w = 4 - } else { - ok = put(emitter, 'U') - w = 8 - } - for k := (w - 1) * 4; ok && k >= 0; k -= 4 { - digit := byte((v >> uint(k)) & 0x0F) - if digit < 10 { - ok = put(emitter, digit+'0') - } else { - ok = put(emitter, digit+'A'-10) - } - } - } - if !ok { - return false - } - spaces = false - } else if is_space(value, i) { - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { - if !yaml_emitter_write_indent(emitter) { - return false - } - if is_space(value, i+1) { - if !put(emitter, '\\') { - return false - } - } - i += width(value[i]) - } else if !write(emitter, value, &i) { - return false - } - spaces = true - } else { - if !write(emitter, value, &i) { - return false - } - spaces = false - } - } - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { - return false - } - emitter.whitespace = false - emitter.indention = false - return true -} - -func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { - if is_space(value, 0) || is_break(value, 0) { - indent_hint := []byte{'0' + byte(emitter.best_indent)} - if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { - return false - } - } - - emitter.open_ended = false - - var chomp_hint [1]byte - if len(value) == 0 { - chomp_hint[0] = '-' - } else { - i := len(value) - 1 - for value[i]&0xC0 == 0x80 { - i-- - } - if !is_break(value, i) { - chomp_hint[0] = '-' - } else if i == 0 { - chomp_hint[0] = '+' - emitter.open_ended = true - } else { - i-- - for value[i]&0xC0 == 0x80 { - i-- - } - if is_break(value, i) { - chomp_hint[0] = '+' - emitter.open_ended = true - } - } - } - if chomp_hint[0] != 0 { - if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { - return false - } - } - return true -} - -func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { - if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { - return false - } - if !yaml_emitter_write_block_scalar_hints(emitter, value) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - //emitter.indention = true - emitter.whitespace = true - breaks := true - for i := 0; i < len(value); { - if is_break(value, i) { - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - } - if !write(emitter, value, &i) { - return false - } - emitter.indention = false - breaks = false - } - } - - return true -} - -func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { - return false - } - if !yaml_emitter_write_block_scalar_hints(emitter, value) { - return false - } - if !yaml_emitter_process_line_comment(emitter) { - return false - } - - //emitter.indention = true - emitter.whitespace = true - - breaks := true - leading_spaces := true - for i := 0; i < len(value); { - if is_break(value, i) { - if !breaks && !leading_spaces && value[i] == '\n' { - k := 0 - for is_break(value, k) { - k += width(value[k]) - } - if !is_blankz(value, k) { - if !put_break(emitter) { - return false - } - } - } - if !write_break(emitter, value, &i) { - return false - } - //emitter.indention = true - breaks = true - } else { - if breaks { - if !yaml_emitter_write_indent(emitter) { - return false - } - leading_spaces = is_blank(value, i) - } - if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { - if !yaml_emitter_write_indent(emitter) { - return false - } - i += width(value[i]) - } else { - if !write(emitter, value, &i) { - return false - } - } - emitter.indention = false - breaks = false - } - } - return true -} - -func yaml_emitter_write_comment(emitter *yaml_emitter_t, comment []byte) bool { - breaks := false - pound := false - for i := 0; i < len(comment); { - if is_break(comment, i) { - if !write_break(emitter, comment, &i) { - return false - } - //emitter.indention = true - breaks = true - pound = false - } else { - if breaks && !yaml_emitter_write_indent(emitter) { - return false - } - if !pound { - if comment[i] != '#' && (!put(emitter, '#') || !put(emitter, ' ')) { - return false - } - pound = true - } - if !write(emitter, comment, &i) { - return false - } - emitter.indention = false - breaks = false - } - } - if !breaks && !put_break(emitter) { - return false - } - - emitter.whitespace = true - //emitter.indention = true - return true -} diff --git a/vendor/gopkg.in/yaml.v3/encode.go b/vendor/gopkg.in/yaml.v3/encode.go deleted file mode 100644 index de9e72a3..00000000 --- a/vendor/gopkg.in/yaml.v3/encode.go +++ /dev/null @@ -1,577 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package yaml - -import ( - "encoding" - "fmt" - "io" - "reflect" - "regexp" - "sort" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -type encoder struct { - emitter yaml_emitter_t - event yaml_event_t - out []byte - flow bool - indent int - doneInit bool -} - -func newEncoder() *encoder { - e := &encoder{} - yaml_emitter_initialize(&e.emitter) - yaml_emitter_set_output_string(&e.emitter, &e.out) - yaml_emitter_set_unicode(&e.emitter, true) - return e -} - -func newEncoderWithWriter(w io.Writer) *encoder { - e := &encoder{} - yaml_emitter_initialize(&e.emitter) - yaml_emitter_set_output_writer(&e.emitter, w) - yaml_emitter_set_unicode(&e.emitter, true) - return e -} - -func (e *encoder) init() { - if e.doneInit { - return - } - if e.indent == 0 { - e.indent = 4 - } - e.emitter.best_indent = e.indent - yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING) - e.emit() - e.doneInit = true -} - -func (e *encoder) finish() { - e.emitter.open_ended = false - yaml_stream_end_event_initialize(&e.event) - e.emit() -} - -func (e *encoder) destroy() { - yaml_emitter_delete(&e.emitter) -} - -func (e *encoder) emit() { - // This will internally delete the e.event value. - e.must(yaml_emitter_emit(&e.emitter, &e.event)) -} - -func (e *encoder) must(ok bool) { - if !ok { - msg := e.emitter.problem - if msg == "" { - msg = "unknown problem generating YAML content" - } - failf("%s", msg) - } -} - -func (e *encoder) marshalDoc(tag string, in reflect.Value) { - e.init() - var node *Node - if in.IsValid() { - node, _ = in.Interface().(*Node) - } - if node != nil && node.Kind == DocumentNode { - e.nodev(in) - } else { - yaml_document_start_event_initialize(&e.event, nil, nil, true) - e.emit() - e.marshal(tag, in) - yaml_document_end_event_initialize(&e.event, true) - e.emit() - } -} - -func (e *encoder) marshal(tag string, in reflect.Value) { - tag = shortTag(tag) - if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() { - e.nilv() - return - } - iface := in.Interface() - switch value := iface.(type) { - case *Node: - e.nodev(in) - return - case Node: - if !in.CanAddr() { - var n = reflect.New(in.Type()).Elem() - n.Set(in) - in = n - } - e.nodev(in.Addr()) - return - case time.Time: - e.timev(tag, in) - return - case *time.Time: - e.timev(tag, in.Elem()) - return - case time.Duration: - e.stringv(tag, reflect.ValueOf(value.String())) - return - case Marshaler: - v, err := value.MarshalYAML() - if err != nil { - fail(err) - } - if v == nil { - e.nilv() - return - } - e.marshal(tag, reflect.ValueOf(v)) - return - case encoding.TextMarshaler: - text, err := value.MarshalText() - if err != nil { - fail(err) - } - in = reflect.ValueOf(string(text)) - case nil: - e.nilv() - return - } - switch in.Kind() { - case reflect.Interface: - e.marshal(tag, in.Elem()) - case reflect.Map: - e.mapv(tag, in) - case reflect.Ptr: - e.marshal(tag, in.Elem()) - case reflect.Struct: - e.structv(tag, in) - case reflect.Slice, reflect.Array: - e.slicev(tag, in) - case reflect.String: - e.stringv(tag, in) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - e.intv(tag, in) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - e.uintv(tag, in) - case reflect.Float32, reflect.Float64: - e.floatv(tag, in) - case reflect.Bool: - e.boolv(tag, in) - default: - panic("cannot marshal type: " + in.Type().String()) - } -} - -func (e *encoder) mapv(tag string, in reflect.Value) { - e.mappingv(tag, func() { - keys := keyList(in.MapKeys()) - sort.Sort(keys) - for _, k := range keys { - e.marshal("", k) - e.marshal("", in.MapIndex(k)) - } - }) -} - -func (e *encoder) fieldByIndex(v reflect.Value, index []int) (field reflect.Value) { - for _, num := range index { - for { - if v.Kind() == reflect.Ptr { - if v.IsNil() { - return reflect.Value{} - } - v = v.Elem() - continue - } - break - } - v = v.Field(num) - } - return v -} - -func (e *encoder) structv(tag string, in reflect.Value) { - sinfo, err := getStructInfo(in.Type()) - if err != nil { - panic(err) - } - e.mappingv(tag, func() { - for _, info := range sinfo.FieldsList { - var value reflect.Value - if info.Inline == nil { - value = in.Field(info.Num) - } else { - value = e.fieldByIndex(in, info.Inline) - if !value.IsValid() { - continue - } - } - if info.OmitEmpty && isZero(value) { - continue - } - e.marshal("", reflect.ValueOf(info.Key)) - e.flow = info.Flow - e.marshal("", value) - } - if sinfo.InlineMap >= 0 { - m := in.Field(sinfo.InlineMap) - if m.Len() > 0 { - e.flow = false - keys := keyList(m.MapKeys()) - sort.Sort(keys) - for _, k := range keys { - if _, found := sinfo.FieldsMap[k.String()]; found { - panic(fmt.Sprintf("cannot have key %q in inlined map: conflicts with struct field", k.String())) - } - e.marshal("", k) - e.flow = false - e.marshal("", m.MapIndex(k)) - } - } - } - }) -} - -func (e *encoder) mappingv(tag string, f func()) { - implicit := tag == "" - style := yaml_BLOCK_MAPPING_STYLE - if e.flow { - e.flow = false - style = yaml_FLOW_MAPPING_STYLE - } - yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style) - e.emit() - f() - yaml_mapping_end_event_initialize(&e.event) - e.emit() -} - -func (e *encoder) slicev(tag string, in reflect.Value) { - implicit := tag == "" - style := yaml_BLOCK_SEQUENCE_STYLE - if e.flow { - e.flow = false - style = yaml_FLOW_SEQUENCE_STYLE - } - e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) - e.emit() - n := in.Len() - for i := 0; i < n; i++ { - e.marshal("", in.Index(i)) - } - e.must(yaml_sequence_end_event_initialize(&e.event)) - e.emit() -} - -// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1. -// -// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported -// in YAML 1.2 and by this package, but these should be marshalled quoted for -// the time being for compatibility with other parsers. -func isBase60Float(s string) (result bool) { - // Fast path. - if s == "" { - return false - } - c := s[0] - if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 { - return false - } - // Do the full match. - return base60float.MatchString(s) -} - -// From http://yaml.org/type/float.html, except the regular expression there -// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix. -var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`) - -// isOldBool returns whether s is bool notation as defined in YAML 1.1. -// -// We continue to force strings that YAML 1.1 would interpret as booleans to be -// rendered as quotes strings so that the marshalled output valid for YAML 1.1 -// parsing. -func isOldBool(s string) (result bool) { - switch s { - case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON", - "n", "N", "no", "No", "NO", "off", "Off", "OFF": - return true - default: - return false - } -} - -func (e *encoder) stringv(tag string, in reflect.Value) { - var style yaml_scalar_style_t - s := in.String() - canUsePlain := true - switch { - case !utf8.ValidString(s): - if tag == binaryTag { - failf("explicitly tagged !!binary data must be base64-encoded") - } - if tag != "" { - failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag)) - } - // It can't be encoded directly as YAML so use a binary tag - // and encode it as base64. - tag = binaryTag - s = encodeBase64(s) - case tag == "": - // Check to see if it would resolve to a specific - // tag when encoded unquoted. If it doesn't, - // there's no need to quote it. - rtag, _ := resolve("", s) - canUsePlain = rtag == strTag && !(isBase60Float(s) || isOldBool(s)) - } - // Note: it's possible for user code to emit invalid YAML - // if they explicitly specify a tag and a string containing - // text that's incompatible with that tag. - switch { - case strings.Contains(s, "\n"): - if e.flow { - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } else { - style = yaml_LITERAL_SCALAR_STYLE - } - case canUsePlain: - style = yaml_PLAIN_SCALAR_STYLE - default: - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - e.emitScalar(s, "", tag, style, nil, nil, nil, nil) -} - -func (e *encoder) boolv(tag string, in reflect.Value) { - var s string - if in.Bool() { - s = "true" - } else { - s = "false" - } - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) intv(tag string, in reflect.Value) { - s := strconv.FormatInt(in.Int(), 10) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) uintv(tag string, in reflect.Value) { - s := strconv.FormatUint(in.Uint(), 10) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) timev(tag string, in reflect.Value) { - t := in.Interface().(time.Time) - s := t.Format(time.RFC3339Nano) - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) floatv(tag string, in reflect.Value) { - // Issue #352: When formatting, use the precision of the underlying value - precision := 64 - if in.Kind() == reflect.Float32 { - precision = 32 - } - - s := strconv.FormatFloat(in.Float(), 'g', -1, precision) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) nilv() { - e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil) -} - -func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t, head, line, foot, tail []byte) { - // TODO Kill this function. Replace all initialize calls by their underlining Go literals. - implicit := tag == "" - if !implicit { - tag = longTag(tag) - } - e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style)) - e.event.head_comment = head - e.event.line_comment = line - e.event.foot_comment = foot - e.event.tail_comment = tail - e.emit() -} - -func (e *encoder) nodev(in reflect.Value) { - e.node(in.Interface().(*Node), "") -} - -func (e *encoder) node(node *Node, tail string) { - // Zero nodes behave as nil. - if node.Kind == 0 && node.IsZero() { - e.nilv() - return - } - - // If the tag was not explicitly requested, and dropping it won't change the - // implicit tag of the value, don't include it in the presentation. - var tag = node.Tag - var stag = shortTag(tag) - var forceQuoting bool - if tag != "" && node.Style&TaggedStyle == 0 { - if node.Kind == ScalarNode { - if stag == strTag && node.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0 { - tag = "" - } else { - rtag, _ := resolve("", node.Value) - if rtag == stag { - tag = "" - } else if stag == strTag { - tag = "" - forceQuoting = true - } - } - } else { - var rtag string - switch node.Kind { - case MappingNode: - rtag = mapTag - case SequenceNode: - rtag = seqTag - } - if rtag == stag { - tag = "" - } - } - } - - switch node.Kind { - case DocumentNode: - yaml_document_start_event_initialize(&e.event, nil, nil, true) - e.event.head_comment = []byte(node.HeadComment) - e.emit() - for _, node := range node.Content { - e.node(node, "") - } - yaml_document_end_event_initialize(&e.event, true) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case SequenceNode: - style := yaml_BLOCK_SEQUENCE_STYLE - if node.Style&FlowStyle != 0 { - style = yaml_FLOW_SEQUENCE_STYLE - } - e.must(yaml_sequence_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style)) - e.event.head_comment = []byte(node.HeadComment) - e.emit() - for _, node := range node.Content { - e.node(node, "") - } - e.must(yaml_sequence_end_event_initialize(&e.event)) - e.event.line_comment = []byte(node.LineComment) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case MappingNode: - style := yaml_BLOCK_MAPPING_STYLE - if node.Style&FlowStyle != 0 { - style = yaml_FLOW_MAPPING_STYLE - } - yaml_mapping_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == "", style) - e.event.tail_comment = []byte(tail) - e.event.head_comment = []byte(node.HeadComment) - e.emit() - - // The tail logic below moves the foot comment of prior keys to the following key, - // since the value for each key may be a nested structure and the foot needs to be - // processed only the entirety of the value is streamed. The last tail is processed - // with the mapping end event. - var tail string - for i := 0; i+1 < len(node.Content); i += 2 { - k := node.Content[i] - foot := k.FootComment - if foot != "" { - kopy := *k - kopy.FootComment = "" - k = &kopy - } - e.node(k, tail) - tail = foot - - v := node.Content[i+1] - e.node(v, "") - } - - yaml_mapping_end_event_initialize(&e.event) - e.event.tail_comment = []byte(tail) - e.event.line_comment = []byte(node.LineComment) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case AliasNode: - yaml_alias_event_initialize(&e.event, []byte(node.Value)) - e.event.head_comment = []byte(node.HeadComment) - e.event.line_comment = []byte(node.LineComment) - e.event.foot_comment = []byte(node.FootComment) - e.emit() - - case ScalarNode: - value := node.Value - if !utf8.ValidString(value) { - if stag == binaryTag { - failf("explicitly tagged !!binary data must be base64-encoded") - } - if stag != "" { - failf("cannot marshal invalid UTF-8 data as %s", stag) - } - // It can't be encoded directly as YAML so use a binary tag - // and encode it as base64. - tag = binaryTag - value = encodeBase64(value) - } - - style := yaml_PLAIN_SCALAR_STYLE - switch { - case node.Style&DoubleQuotedStyle != 0: - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - case node.Style&SingleQuotedStyle != 0: - style = yaml_SINGLE_QUOTED_SCALAR_STYLE - case node.Style&LiteralStyle != 0: - style = yaml_LITERAL_SCALAR_STYLE - case node.Style&FoldedStyle != 0: - style = yaml_FOLDED_SCALAR_STYLE - case strings.Contains(value, "\n"): - style = yaml_LITERAL_SCALAR_STYLE - case forceQuoting: - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - - e.emitScalar(value, node.Anchor, tag, style, []byte(node.HeadComment), []byte(node.LineComment), []byte(node.FootComment), []byte(tail)) - default: - failf("cannot encode node with unknown kind %d", node.Kind) - } -} diff --git a/vendor/gopkg.in/yaml.v3/parserc.go b/vendor/gopkg.in/yaml.v3/parserc.go deleted file mode 100644 index 268558a0..00000000 --- a/vendor/gopkg.in/yaml.v3/parserc.go +++ /dev/null @@ -1,1258 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -import ( - "bytes" -) - -// The parser implements the following grammar: -// -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END -// implicit_document ::= block_node DOCUMENT-END* -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// block_node_or_indentless_sequence ::= -// ALIAS -// | properties (block_content | indentless_block_sequence)? -// | block_content -// | indentless_block_sequence -// block_node ::= ALIAS -// | properties block_content? -// | block_content -// flow_node ::= ALIAS -// | properties flow_content? -// | flow_content -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// block_content ::= block_collection | flow_collection | SCALAR -// flow_content ::= flow_collection | SCALAR -// block_collection ::= block_sequence | block_mapping -// flow_collection ::= flow_sequence | flow_mapping -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ -// block_mapping ::= BLOCK-MAPPING_START -// ((KEY block_node_or_indentless_sequence?)? -// (VALUE block_node_or_indentless_sequence?)?)* -// BLOCK-END -// flow_sequence ::= FLOW-SEQUENCE-START -// (flow_sequence_entry FLOW-ENTRY)* -// flow_sequence_entry? -// FLOW-SEQUENCE-END -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// flow_mapping ::= FLOW-MAPPING-START -// (flow_mapping_entry FLOW-ENTRY)* -// flow_mapping_entry? -// FLOW-MAPPING-END -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - -// Peek the next token in the token queue. -func peek_token(parser *yaml_parser_t) *yaml_token_t { - if parser.token_available || yaml_parser_fetch_more_tokens(parser) { - token := &parser.tokens[parser.tokens_head] - yaml_parser_unfold_comments(parser, token) - return token - } - return nil -} - -// yaml_parser_unfold_comments walks through the comments queue and joins all -// comments behind the position of the provided token into the respective -// top-level comment slices in the parser. -func yaml_parser_unfold_comments(parser *yaml_parser_t, token *yaml_token_t) { - for parser.comments_head < len(parser.comments) && token.start_mark.index >= parser.comments[parser.comments_head].token_mark.index { - comment := &parser.comments[parser.comments_head] - if len(comment.head) > 0 { - if token.typ == yaml_BLOCK_END_TOKEN { - // No heads on ends, so keep comment.head for a follow up token. - break - } - if len(parser.head_comment) > 0 { - parser.head_comment = append(parser.head_comment, '\n') - } - parser.head_comment = append(parser.head_comment, comment.head...) - } - if len(comment.foot) > 0 { - if len(parser.foot_comment) > 0 { - parser.foot_comment = append(parser.foot_comment, '\n') - } - parser.foot_comment = append(parser.foot_comment, comment.foot...) - } - if len(comment.line) > 0 { - if len(parser.line_comment) > 0 { - parser.line_comment = append(parser.line_comment, '\n') - } - parser.line_comment = append(parser.line_comment, comment.line...) - } - *comment = yaml_comment_t{} - parser.comments_head++ - } -} - -// Remove the next token from the queue (must be called after peek_token). -func skip_token(parser *yaml_parser_t) { - parser.token_available = false - parser.tokens_parsed++ - parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN - parser.tokens_head++ -} - -// Get the next event. -func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { - // Erase the event object. - *event = yaml_event_t{} - - // No events after the end of the stream or error. - if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { - return true - } - - // Generate the next event. - return yaml_parser_state_machine(parser, event) -} - -// Set parser error. -func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { - parser.error = yaml_PARSER_ERROR - parser.problem = problem - parser.problem_mark = problem_mark - return false -} - -func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { - parser.error = yaml_PARSER_ERROR - parser.context = context - parser.context_mark = context_mark - parser.problem = problem - parser.problem_mark = problem_mark - return false -} - -// State dispatcher. -func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { - //trace("yaml_parser_state_machine", "state:", parser.state.String()) - - switch parser.state { - case yaml_PARSE_STREAM_START_STATE: - return yaml_parser_parse_stream_start(parser, event) - - case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, true) - - case yaml_PARSE_DOCUMENT_START_STATE: - return yaml_parser_parse_document_start(parser, event, false) - - case yaml_PARSE_DOCUMENT_CONTENT_STATE: - return yaml_parser_parse_document_content(parser, event) - - case yaml_PARSE_DOCUMENT_END_STATE: - return yaml_parser_parse_document_end(parser, event) - - case yaml_PARSE_BLOCK_NODE_STATE: - return yaml_parser_parse_node(parser, event, true, false) - - case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return yaml_parser_parse_node(parser, event, true, true) - - case yaml_PARSE_FLOW_NODE_STATE: - return yaml_parser_parse_node(parser, event, false, false) - - case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, true) - - case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_block_sequence_entry(parser, event, false) - - case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_indentless_sequence_entry(parser, event) - - case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, true) - - case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: - return yaml_parser_parse_block_mapping_key(parser, event, false) - - case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: - return yaml_parser_parse_block_mapping_value(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, true) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return yaml_parser_parse_flow_sequence_entry(parser, event, false) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) - - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) - - case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, true) - - case yaml_PARSE_FLOW_MAPPING_KEY_STATE: - return yaml_parser_parse_flow_mapping_key(parser, event, false) - - case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, false) - - case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return yaml_parser_parse_flow_mapping_value(parser, event, true) - - default: - panic("invalid parser state") - } -} - -// Parse the production: -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END -// ************ -func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_STREAM_START_TOKEN { - return yaml_parser_set_parser_error(parser, "did not find expected ", token.start_mark) - } - parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE - *event = yaml_event_t{ - typ: yaml_STREAM_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - encoding: token.encoding, - } - skip_token(parser) - return true -} - -// Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// * -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// ************************* -func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { - - token := peek_token(parser) - if token == nil { - return false - } - - // Parse extra document end indicators. - if !implicit { - for token.typ == yaml_DOCUMENT_END_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } - - if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && - token.typ != yaml_TAG_DIRECTIVE_TOKEN && - token.typ != yaml_DOCUMENT_START_TOKEN && - token.typ != yaml_STREAM_END_TOKEN { - // Parse an implicit document. - if !yaml_parser_process_directives(parser, nil, nil) { - return false - } - parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) - parser.state = yaml_PARSE_BLOCK_NODE_STATE - - var head_comment []byte - if len(parser.head_comment) > 0 { - // [Go] Scan the header comment backwards, and if an empty line is found, break - // the header so the part before the last empty line goes into the - // document header, while the bottom of it goes into a follow up event. - for i := len(parser.head_comment) - 1; i > 0; i-- { - if parser.head_comment[i] == '\n' { - if i == len(parser.head_comment)-1 { - head_comment = parser.head_comment[:i] - parser.head_comment = parser.head_comment[i+1:] - break - } else if parser.head_comment[i-1] == '\n' { - head_comment = parser.head_comment[:i-1] - parser.head_comment = parser.head_comment[i+1:] - break - } - } - } - } - - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - - head_comment: head_comment, - } - - } else if token.typ != yaml_STREAM_END_TOKEN { - // Parse an explicit document. - var version_directive *yaml_version_directive_t - var tag_directives []yaml_tag_directive_t - start_mark := token.start_mark - if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { - return false - } - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_DOCUMENT_START_TOKEN { - yaml_parser_set_parser_error(parser, - "did not find expected ", token.start_mark) - return false - } - parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) - parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE - end_mark := token.end_mark - - *event = yaml_event_t{ - typ: yaml_DOCUMENT_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - version_directive: version_directive, - tag_directives: tag_directives, - implicit: false, - } - skip_token(parser) - - } else { - // Parse the stream end. - parser.state = yaml_PARSE_END_STATE - *event = yaml_event_t{ - typ: yaml_STREAM_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - skip_token(parser) - } - - return true -} - -// Parse the productions: -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// *********** -// -func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || - token.typ == yaml_TAG_DIRECTIVE_TOKEN || - token.typ == yaml_DOCUMENT_START_TOKEN || - token.typ == yaml_DOCUMENT_END_TOKEN || - token.typ == yaml_STREAM_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - return yaml_parser_process_empty_scalar(parser, event, - token.start_mark) - } - return yaml_parser_parse_node(parser, event, true, false) -} - -// Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// ************* -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// -func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - start_mark := token.start_mark - end_mark := token.start_mark - - implicit := true - if token.typ == yaml_DOCUMENT_END_TOKEN { - end_mark = token.end_mark - skip_token(parser) - implicit = false - } - - parser.tag_directives = parser.tag_directives[:0] - - parser.state = yaml_PARSE_DOCUMENT_START_STATE - *event = yaml_event_t{ - typ: yaml_DOCUMENT_END_EVENT, - start_mark: start_mark, - end_mark: end_mark, - implicit: implicit, - } - yaml_parser_set_event_comments(parser, event) - if len(event.head_comment) > 0 && len(event.foot_comment) == 0 { - event.foot_comment = event.head_comment - event.head_comment = nil - } - return true -} - -func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) { - event.head_comment = parser.head_comment - event.line_comment = parser.line_comment - event.foot_comment = parser.foot_comment - parser.head_comment = nil - parser.line_comment = nil - parser.foot_comment = nil - parser.tail_comment = nil - parser.stem_comment = nil -} - -// Parse the productions: -// block_node_or_indentless_sequence ::= -// ALIAS -// ***** -// | properties (block_content | indentless_block_sequence)? -// ********** * -// | block_content | indentless_block_sequence -// * -// block_node ::= ALIAS -// ***** -// | properties block_content? -// ********** * -// | block_content -// * -// flow_node ::= ALIAS -// ***** -// | properties flow_content? -// ********** * -// | flow_content -// * -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// ************************* -// block_content ::= block_collection | flow_collection | SCALAR -// ****** -// flow_content ::= flow_collection | SCALAR -// ****** -func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { - //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_ALIAS_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - *event = yaml_event_t{ - typ: yaml_ALIAS_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - anchor: token.value, - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true - } - - start_mark := token.start_mark - end_mark := token.start_mark - - var tag_token bool - var tag_handle, tag_suffix, anchor []byte - var tag_mark yaml_mark_t - if token.typ == yaml_ANCHOR_TOKEN { - anchor = token.value - start_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_TAG_TOKEN { - tag_token = true - tag_handle = token.value - tag_suffix = token.suffix - tag_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } else if token.typ == yaml_TAG_TOKEN { - tag_token = true - tag_handle = token.value - tag_suffix = token.suffix - start_mark = token.start_mark - tag_mark = token.start_mark - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_ANCHOR_TOKEN { - anchor = token.value - end_mark = token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - } - - var tag []byte - if tag_token { - if len(tag_handle) == 0 { - tag = tag_suffix - tag_suffix = nil - } else { - for i := range parser.tag_directives { - if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { - tag = append([]byte(nil), parser.tag_directives[i].prefix...) - tag = append(tag, tag_suffix...) - break - } - } - if len(tag) == 0 { - yaml_parser_set_parser_error_context(parser, - "while parsing a node", start_mark, - "found undefined tag handle", tag_mark) - return false - } - } - } - - implicit := len(tag) == 0 - if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), - } - return true - } - if token.typ == yaml_SCALAR_TOKEN { - var plain_implicit, quoted_implicit bool - end_mark = token.end_mark - if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { - plain_implicit = true - } else if len(tag) == 0 { - quoted_implicit = true - } - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - value: token.value, - implicit: plain_implicit, - quoted_implicit: quoted_implicit, - style: yaml_style_t(token.style), - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true - } - if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { - // [Go] Some of the events below can be merged as they differ only on style. - end_mark = token.end_mark - parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), - } - yaml_parser_set_event_comments(parser, event) - return true - } - if token.typ == yaml_FLOW_MAPPING_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), - } - yaml_parser_set_event_comments(parser, event) - return true - } - if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_SEQUENCE_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), - } - if parser.stem_comment != nil { - event.head_comment = parser.stem_comment - parser.stem_comment = nil - } - return true - } - if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { - end_mark = token.end_mark - parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), - } - if parser.stem_comment != nil { - event.head_comment = parser.stem_comment - parser.stem_comment = nil - } - return true - } - if len(anchor) > 0 || len(tag) > 0 { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: start_mark, - end_mark: end_mark, - anchor: anchor, - tag: tag, - implicit: implicit, - quoted_implicit: false, - style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), - } - return true - } - - context := "while parsing a flow node" - if block { - context = "while parsing a block node" - } - yaml_parser_set_parser_error_context(parser, context, start_mark, - "did not find expected node content", token.start_mark) - return false -} - -// Parse the productions: -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END -// ******************** *********** * ********* -// -func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - if token == nil { - return false - } - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_BLOCK_ENTRY_TOKEN { - mark := token.end_mark - prior_head_len := len(parser.head_comment) - skip_token(parser) - yaml_parser_split_stem_comment(parser, prior_head_len) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, true, false) - } else { - parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - } - if token.typ == yaml_BLOCK_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - - skip_token(parser) - return true - } - - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a block collection", context_mark, - "did not find expected '-' indicator", token.start_mark) -} - -// Parse the productions: -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ -// *********** * -func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ == yaml_BLOCK_ENTRY_TOKEN { - mark := token.end_mark - prior_head_len := len(parser.head_comment) - skip_token(parser) - yaml_parser_split_stem_comment(parser, prior_head_len) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_BLOCK_ENTRY_TOKEN && - token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, true, false) - } - parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? - } - return true -} - -// Split stem comment from head comment. -// -// When a sequence or map is found under a sequence entry, the former head comment -// is assigned to the underlying sequence or map as a whole, not the individual -// sequence or map entry as would be expected otherwise. To handle this case the -// previous head comment is moved aside as the stem comment. -func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) { - if stem_len == 0 { - return - } - - token := peek_token(parser) - if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN { - return - } - - parser.stem_comment = parser.head_comment[:stem_len] - if len(parser.head_comment) == stem_len { - parser.head_comment = nil - } else { - // Copy suffix to prevent very strange bugs if someone ever appends - // further bytes to the prefix in the stem_comment slice above. - parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...) - } -} - -// Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START -// ******************* -// ((KEY block_node_or_indentless_sequence?)? -// *** * -// (VALUE block_node_or_indentless_sequence?)?)* -// -// BLOCK-END -// ********* -// -func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - if token == nil { - return false - } - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - // [Go] A tail comment was left from the prior mapping value processed. Emit an event - // as it needs to be processed with that value and not the following key. - if len(parser.tail_comment) > 0 { - *event = yaml_event_t{ - typ: yaml_TAIL_COMMENT_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - foot_comment: parser.tail_comment, - } - parser.tail_comment = nil - return true - } - - if token.typ == yaml_KEY_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, true, true) - } else { - parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - } else if token.typ == yaml_BLOCK_END_TOKEN { - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true - } - - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a block mapping", context_mark, - "did not find expected key", token.start_mark) -} - -// Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START -// -// ((KEY block_node_or_indentless_sequence?)? -// -// (VALUE block_node_or_indentless_sequence?)?)* -// ***** * -// BLOCK-END -// -// -func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_VALUE_TOKEN { - mark := token.end_mark - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_KEY_TOKEN && - token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_BLOCK_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) - return yaml_parser_parse_node(parser, event, true, true) - } - parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) - } - parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Parse the productions: -// flow_sequence ::= FLOW-SEQUENCE-START -// ******************* -// (flow_sequence_entry FLOW-ENTRY)* -// * ********** -// flow_sequence_entry? -// * -// FLOW-SEQUENCE-END -// ***************** -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * -// -func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - if token == nil { - return false - } - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - if !first { - if token.typ == yaml_FLOW_ENTRY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } else { - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow sequence", context_mark, - "did not find expected ',' or ']'", token.start_mark) - } - } - - if token.typ == yaml_KEY_TOKEN { - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_START_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - implicit: true, - style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), - } - skip_token(parser) - return true - } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - - *event = yaml_event_t{ - typ: yaml_SEQUENCE_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - yaml_parser_set_event_comments(parser, event) - - skip_token(parser) - return true -} - -// -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// *** * -// -func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_FLOW_ENTRY_TOKEN && - token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - mark := token.end_mark - skip_token(parser) - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, mark) -} - -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// ***** * -// -func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - if token.typ == yaml_VALUE_TOKEN { - skip_token(parser) - token := peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * -// -func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { - token := peek_token(parser) - if token == nil { - return false - } - parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? - } - return true -} - -// Parse the productions: -// flow_mapping ::= FLOW-MAPPING-START -// ****************** -// (flow_mapping_entry FLOW-ENTRY)* -// * ********** -// flow_mapping_entry? -// ****************** -// FLOW-MAPPING-END -// **************** -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * *** * -// -func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { - if first { - token := peek_token(parser) - parser.marks = append(parser.marks, token.start_mark) - skip_token(parser) - } - - token := peek_token(parser) - if token == nil { - return false - } - - if token.typ != yaml_FLOW_MAPPING_END_TOKEN { - if !first { - if token.typ == yaml_FLOW_ENTRY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } else { - context_mark := parser.marks[len(parser.marks)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - return yaml_parser_set_parser_error_context(parser, - "while parsing a flow mapping", context_mark, - "did not find expected ',' or '}'", token.start_mark) - } - } - - if token.typ == yaml_KEY_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_VALUE_TOKEN && - token.typ != yaml_FLOW_ENTRY_TOKEN && - token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } else { - parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) - } - } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - - parser.state = parser.states[len(parser.states)-1] - parser.states = parser.states[:len(parser.states)-1] - parser.marks = parser.marks[:len(parser.marks)-1] - *event = yaml_event_t{ - typ: yaml_MAPPING_END_EVENT, - start_mark: token.start_mark, - end_mark: token.end_mark, - } - yaml_parser_set_event_comments(parser, event) - skip_token(parser) - return true -} - -// Parse the productions: -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// * ***** * -// -func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { - token := peek_token(parser) - if token == nil { - return false - } - if empty { - parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) - } - if token.typ == yaml_VALUE_TOKEN { - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { - parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) - return yaml_parser_parse_node(parser, event, false, false) - } - } - parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE - return yaml_parser_process_empty_scalar(parser, event, token.start_mark) -} - -// Generate an empty scalar event. -func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { - *event = yaml_event_t{ - typ: yaml_SCALAR_EVENT, - start_mark: mark, - end_mark: mark, - value: nil, // Empty - implicit: true, - style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), - } - return true -} - -var default_tag_directives = []yaml_tag_directive_t{ - {[]byte("!"), []byte("!")}, - {[]byte("!!"), []byte("tag:yaml.org,2002:")}, -} - -// Parse directives. -func yaml_parser_process_directives(parser *yaml_parser_t, - version_directive_ref **yaml_version_directive_t, - tag_directives_ref *[]yaml_tag_directive_t) bool { - - var version_directive *yaml_version_directive_t - var tag_directives []yaml_tag_directive_t - - token := peek_token(parser) - if token == nil { - return false - } - - for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { - if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { - if version_directive != nil { - yaml_parser_set_parser_error(parser, - "found duplicate %YAML directive", token.start_mark) - return false - } - if token.major != 1 || token.minor != 1 { - yaml_parser_set_parser_error(parser, - "found incompatible YAML document", token.start_mark) - return false - } - version_directive = &yaml_version_directive_t{ - major: token.major, - minor: token.minor, - } - } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { - value := yaml_tag_directive_t{ - handle: token.value, - prefix: token.prefix, - } - if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { - return false - } - tag_directives = append(tag_directives, value) - } - - skip_token(parser) - token = peek_token(parser) - if token == nil { - return false - } - } - - for i := range default_tag_directives { - if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { - return false - } - } - - if version_directive_ref != nil { - *version_directive_ref = version_directive - } - if tag_directives_ref != nil { - *tag_directives_ref = tag_directives - } - return true -} - -// Append a tag directive to the directives stack. -func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { - for i := range parser.tag_directives { - if bytes.Equal(value.handle, parser.tag_directives[i].handle) { - if allow_duplicates { - return true - } - return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) - } - } - - // [Go] I suspect the copy is unnecessary. This was likely done - // because there was no way to track ownership of the data. - value_copy := yaml_tag_directive_t{ - handle: make([]byte, len(value.handle)), - prefix: make([]byte, len(value.prefix)), - } - copy(value_copy.handle, value.handle) - copy(value_copy.prefix, value.prefix) - parser.tag_directives = append(parser.tag_directives, value_copy) - return true -} diff --git a/vendor/gopkg.in/yaml.v3/readerc.go b/vendor/gopkg.in/yaml.v3/readerc.go deleted file mode 100644 index b7de0a89..00000000 --- a/vendor/gopkg.in/yaml.v3/readerc.go +++ /dev/null @@ -1,434 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -import ( - "io" -) - -// Set the reader error and return 0. -func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool { - parser.error = yaml_READER_ERROR - parser.problem = problem - parser.problem_offset = offset - parser.problem_value = value - return false -} - -// Byte order marks. -const ( - bom_UTF8 = "\xef\xbb\xbf" - bom_UTF16LE = "\xff\xfe" - bom_UTF16BE = "\xfe\xff" -) - -// Determine the input stream encoding by checking the BOM symbol. If no BOM is -// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. -func yaml_parser_determine_encoding(parser *yaml_parser_t) bool { - // Ensure that we had enough bytes in the raw buffer. - for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 { - if !yaml_parser_update_raw_buffer(parser) { - return false - } - } - - // Determine the encoding. - buf := parser.raw_buffer - pos := parser.raw_buffer_pos - avail := len(buf) - pos - if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] { - parser.encoding = yaml_UTF16LE_ENCODING - parser.raw_buffer_pos += 2 - parser.offset += 2 - } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] { - parser.encoding = yaml_UTF16BE_ENCODING - parser.raw_buffer_pos += 2 - parser.offset += 2 - } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] { - parser.encoding = yaml_UTF8_ENCODING - parser.raw_buffer_pos += 3 - parser.offset += 3 - } else { - parser.encoding = yaml_UTF8_ENCODING - } - return true -} - -// Update the raw buffer. -func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool { - size_read := 0 - - // Return if the raw buffer is full. - if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) { - return true - } - - // Return on EOF. - if parser.eof { - return true - } - - // Move the remaining bytes in the raw buffer to the beginning. - if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) { - copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:]) - } - parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos] - parser.raw_buffer_pos = 0 - - // Call the read handler to fill the buffer. - size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)]) - parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read] - if err == io.EOF { - parser.eof = true - } else if err != nil { - return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1) - } - return true -} - -// Ensure that the buffer contains at least `length` characters. -// Return true on success, false on failure. -// -// The length is supposed to be significantly less that the buffer size. -func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { - if parser.read_handler == nil { - panic("read handler must be set") - } - - // [Go] This function was changed to guarantee the requested length size at EOF. - // The fact we need to do this is pretty awful, but the description above implies - // for that to be the case, and there are tests - - // If the EOF flag is set and the raw buffer is empty, do nothing. - if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) { - // [Go] ACTUALLY! Read the documentation of this function above. - // This is just broken. To return true, we need to have the - // given length in the buffer. Not doing that means every single - // check that calls this function to make sure the buffer has a - // given length is Go) panicking; or C) accessing invalid memory. - //return true - } - - // Return if the buffer contains enough characters. - if parser.unread >= length { - return true - } - - // Determine the input encoding if it is not known yet. - if parser.encoding == yaml_ANY_ENCODING { - if !yaml_parser_determine_encoding(parser) { - return false - } - } - - // Move the unread characters to the beginning of the buffer. - buffer_len := len(parser.buffer) - if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len { - copy(parser.buffer, parser.buffer[parser.buffer_pos:]) - buffer_len -= parser.buffer_pos - parser.buffer_pos = 0 - } else if parser.buffer_pos == buffer_len { - buffer_len = 0 - parser.buffer_pos = 0 - } - - // Open the whole buffer for writing, and cut it before returning. - parser.buffer = parser.buffer[:cap(parser.buffer)] - - // Fill the buffer until it has enough characters. - first := true - for parser.unread < length { - - // Fill the raw buffer if necessary. - if !first || parser.raw_buffer_pos == len(parser.raw_buffer) { - if !yaml_parser_update_raw_buffer(parser) { - parser.buffer = parser.buffer[:buffer_len] - return false - } - } - first = false - - // Decode the raw buffer. - inner: - for parser.raw_buffer_pos != len(parser.raw_buffer) { - var value rune - var width int - - raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos - - // Decode the next character. - switch parser.encoding { - case yaml_UTF8_ENCODING: - // Decode a UTF-8 character. Check RFC 3629 - // (http://www.ietf.org/rfc/rfc3629.txt) for more details. - // - // The following table (taken from the RFC) is used for - // decoding. - // - // Char. number range | UTF-8 octet sequence - // (hexadecimal) | (binary) - // --------------------+------------------------------------ - // 0000 0000-0000 007F | 0xxxxxxx - // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx - // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx - // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - // - // Additionally, the characters in the range 0xD800-0xDFFF - // are prohibited as they are reserved for use with UTF-16 - // surrogate pairs. - - // Determine the length of the UTF-8 sequence. - octet := parser.raw_buffer[parser.raw_buffer_pos] - switch { - case octet&0x80 == 0x00: - width = 1 - case octet&0xE0 == 0xC0: - width = 2 - case octet&0xF0 == 0xE0: - width = 3 - case octet&0xF8 == 0xF0: - width = 4 - default: - // The leading octet is invalid. - return yaml_parser_set_reader_error(parser, - "invalid leading UTF-8 octet", - parser.offset, int(octet)) - } - - // Check if the raw buffer contains an incomplete character. - if width > raw_unread { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-8 octet sequence", - parser.offset, -1) - } - break inner - } - - // Decode the leading octet. - switch { - case octet&0x80 == 0x00: - value = rune(octet & 0x7F) - case octet&0xE0 == 0xC0: - value = rune(octet & 0x1F) - case octet&0xF0 == 0xE0: - value = rune(octet & 0x0F) - case octet&0xF8 == 0xF0: - value = rune(octet & 0x07) - default: - value = 0 - } - - // Check and decode the trailing octets. - for k := 1; k < width; k++ { - octet = parser.raw_buffer[parser.raw_buffer_pos+k] - - // Check if the octet is valid. - if (octet & 0xC0) != 0x80 { - return yaml_parser_set_reader_error(parser, - "invalid trailing UTF-8 octet", - parser.offset+k, int(octet)) - } - - // Decode the octet. - value = (value << 6) + rune(octet&0x3F) - } - - // Check the length of the sequence against the value. - switch { - case width == 1: - case width == 2 && value >= 0x80: - case width == 3 && value >= 0x800: - case width == 4 && value >= 0x10000: - default: - return yaml_parser_set_reader_error(parser, - "invalid length of a UTF-8 sequence", - parser.offset, -1) - } - - // Check the range of the value. - if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF { - return yaml_parser_set_reader_error(parser, - "invalid Unicode character", - parser.offset, int(value)) - } - - case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING: - var low, high int - if parser.encoding == yaml_UTF16LE_ENCODING { - low, high = 0, 1 - } else { - low, high = 1, 0 - } - - // The UTF-16 encoding is not as simple as one might - // naively think. Check RFC 2781 - // (http://www.ietf.org/rfc/rfc2781.txt). - // - // Normally, two subsequent bytes describe a Unicode - // character. However a special technique (called a - // surrogate pair) is used for specifying character - // values larger than 0xFFFF. - // - // A surrogate pair consists of two pseudo-characters: - // high surrogate area (0xD800-0xDBFF) - // low surrogate area (0xDC00-0xDFFF) - // - // The following formulas are used for decoding - // and encoding characters using surrogate pairs: - // - // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) - // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) - // W1 = 110110yyyyyyyyyy - // W2 = 110111xxxxxxxxxx - // - // where U is the character value, W1 is the high surrogate - // area, W2 is the low surrogate area. - - // Check for incomplete UTF-16 character. - if raw_unread < 2 { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 character", - parser.offset, -1) - } - break inner - } - - // Get the character. - value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) + - (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8) - - // Check for unexpected low surrogate area. - if value&0xFC00 == 0xDC00 { - return yaml_parser_set_reader_error(parser, - "unexpected low surrogate area", - parser.offset, int(value)) - } - - // Check for a high surrogate area. - if value&0xFC00 == 0xD800 { - width = 4 - - // Check for incomplete surrogate pair. - if raw_unread < 4 { - if parser.eof { - return yaml_parser_set_reader_error(parser, - "incomplete UTF-16 surrogate pair", - parser.offset, -1) - } - break inner - } - - // Get the next character. - value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) + - (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8) - - // Check for a low surrogate area. - if value2&0xFC00 != 0xDC00 { - return yaml_parser_set_reader_error(parser, - "expected low surrogate area", - parser.offset+2, int(value2)) - } - - // Generate the value of the surrogate pair. - value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF) - } else { - width = 2 - } - - default: - panic("impossible") - } - - // Check if the character is in the allowed range: - // #x9 | #xA | #xD | [#x20-#x7E] (8 bit) - // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) - // | [#x10000-#x10FFFF] (32 bit) - switch { - case value == 0x09: - case value == 0x0A: - case value == 0x0D: - case value >= 0x20 && value <= 0x7E: - case value == 0x85: - case value >= 0xA0 && value <= 0xD7FF: - case value >= 0xE000 && value <= 0xFFFD: - case value >= 0x10000 && value <= 0x10FFFF: - default: - return yaml_parser_set_reader_error(parser, - "control characters are not allowed", - parser.offset, int(value)) - } - - // Move the raw pointers. - parser.raw_buffer_pos += width - parser.offset += width - - // Finally put the character into the buffer. - if value <= 0x7F { - // 0000 0000-0000 007F . 0xxxxxxx - parser.buffer[buffer_len+0] = byte(value) - buffer_len += 1 - } else if value <= 0x7FF { - // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6)) - parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F)) - buffer_len += 2 - } else if value <= 0xFFFF { - // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12)) - parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F)) - parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F)) - buffer_len += 3 - } else { - // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18)) - parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F)) - parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F)) - parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F)) - buffer_len += 4 - } - - parser.unread++ - } - - // On EOF, put NUL into the buffer and return. - if parser.eof { - parser.buffer[buffer_len] = 0 - buffer_len++ - parser.unread++ - break - } - } - // [Go] Read the documentation of this function above. To return true, - // we need to have the given length in the buffer. Not doing that means - // every single check that calls this function to make sure the buffer - // has a given length is Go) panicking; or C) accessing invalid memory. - // This happens here due to the EOF above breaking early. - for buffer_len < length { - parser.buffer[buffer_len] = 0 - buffer_len++ - } - parser.buffer = parser.buffer[:buffer_len] - return true -} diff --git a/vendor/gopkg.in/yaml.v3/resolve.go b/vendor/gopkg.in/yaml.v3/resolve.go deleted file mode 100644 index 64ae8880..00000000 --- a/vendor/gopkg.in/yaml.v3/resolve.go +++ /dev/null @@ -1,326 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package yaml - -import ( - "encoding/base64" - "math" - "regexp" - "strconv" - "strings" - "time" -) - -type resolveMapItem struct { - value interface{} - tag string -} - -var resolveTable = make([]byte, 256) -var resolveMap = make(map[string]resolveMapItem) - -func init() { - t := resolveTable - t[int('+')] = 'S' // Sign - t[int('-')] = 'S' - for _, c := range "0123456789" { - t[int(c)] = 'D' // Digit - } - for _, c := range "yYnNtTfFoO~" { - t[int(c)] = 'M' // In map - } - t[int('.')] = '.' // Float (potentially in map) - - var resolveMapList = []struct { - v interface{} - tag string - l []string - }{ - {true, boolTag, []string{"true", "True", "TRUE"}}, - {false, boolTag, []string{"false", "False", "FALSE"}}, - {nil, nullTag, []string{"", "~", "null", "Null", "NULL"}}, - {math.NaN(), floatTag, []string{".nan", ".NaN", ".NAN"}}, - {math.Inf(+1), floatTag, []string{".inf", ".Inf", ".INF"}}, - {math.Inf(+1), floatTag, []string{"+.inf", "+.Inf", "+.INF"}}, - {math.Inf(-1), floatTag, []string{"-.inf", "-.Inf", "-.INF"}}, - {"<<", mergeTag, []string{"<<"}}, - } - - m := resolveMap - for _, item := range resolveMapList { - for _, s := range item.l { - m[s] = resolveMapItem{item.v, item.tag} - } - } -} - -const ( - nullTag = "!!null" - boolTag = "!!bool" - strTag = "!!str" - intTag = "!!int" - floatTag = "!!float" - timestampTag = "!!timestamp" - seqTag = "!!seq" - mapTag = "!!map" - binaryTag = "!!binary" - mergeTag = "!!merge" -) - -var longTags = make(map[string]string) -var shortTags = make(map[string]string) - -func init() { - for _, stag := range []string{nullTag, boolTag, strTag, intTag, floatTag, timestampTag, seqTag, mapTag, binaryTag, mergeTag} { - ltag := longTag(stag) - longTags[stag] = ltag - shortTags[ltag] = stag - } -} - -const longTagPrefix = "tag:yaml.org,2002:" - -func shortTag(tag string) string { - if strings.HasPrefix(tag, longTagPrefix) { - if stag, ok := shortTags[tag]; ok { - return stag - } - return "!!" + tag[len(longTagPrefix):] - } - return tag -} - -func longTag(tag string) string { - if strings.HasPrefix(tag, "!!") { - if ltag, ok := longTags[tag]; ok { - return ltag - } - return longTagPrefix + tag[2:] - } - return tag -} - -func resolvableTag(tag string) bool { - switch tag { - case "", strTag, boolTag, intTag, floatTag, nullTag, timestampTag: - return true - } - return false -} - -var yamlStyleFloat = regexp.MustCompile(`^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$`) - -func resolve(tag string, in string) (rtag string, out interface{}) { - tag = shortTag(tag) - if !resolvableTag(tag) { - return tag, in - } - - defer func() { - switch tag { - case "", rtag, strTag, binaryTag: - return - case floatTag: - if rtag == intTag { - switch v := out.(type) { - case int64: - rtag = floatTag - out = float64(v) - return - case int: - rtag = floatTag - out = float64(v) - return - } - } - } - failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) - }() - - // Any data is accepted as a !!str or !!binary. - // Otherwise, the prefix is enough of a hint about what it might be. - hint := byte('N') - if in != "" { - hint = resolveTable[in[0]] - } - if hint != 0 && tag != strTag && tag != binaryTag { - // Handle things we can lookup in a map. - if item, ok := resolveMap[in]; ok { - return item.tag, item.value - } - - // Base 60 floats are a bad idea, were dropped in YAML 1.2, and - // are purposefully unsupported here. They're still quoted on - // the way out for compatibility with other parser, though. - - switch hint { - case 'M': - // We've already checked the map above. - - case '.': - // Not in the map, so maybe a normal float. - floatv, err := strconv.ParseFloat(in, 64) - if err == nil { - return floatTag, floatv - } - - case 'D', 'S': - // Int, float, or timestamp. - // Only try values as a timestamp if the value is unquoted or there's an explicit - // !!timestamp tag. - if tag == "" || tag == timestampTag { - t, ok := parseTimestamp(in) - if ok { - return timestampTag, t - } - } - - plain := strings.Replace(in, "_", "", -1) - intv, err := strconv.ParseInt(plain, 0, 64) - if err == nil { - if intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - uintv, err := strconv.ParseUint(plain, 0, 64) - if err == nil { - return intTag, uintv - } - if yamlStyleFloat.MatchString(plain) { - floatv, err := strconv.ParseFloat(plain, 64) - if err == nil { - return floatTag, floatv - } - } - if strings.HasPrefix(plain, "0b") { - intv, err := strconv.ParseInt(plain[2:], 2, 64) - if err == nil { - if intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - uintv, err := strconv.ParseUint(plain[2:], 2, 64) - if err == nil { - return intTag, uintv - } - } else if strings.HasPrefix(plain, "-0b") { - intv, err := strconv.ParseInt("-"+plain[3:], 2, 64) - if err == nil { - if true || intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - } - // Octals as introduced in version 1.2 of the spec. - // Octals from the 1.1 spec, spelled as 0777, are still - // decoded by default in v3 as well for compatibility. - // May be dropped in v4 depending on how usage evolves. - if strings.HasPrefix(plain, "0o") { - intv, err := strconv.ParseInt(plain[2:], 8, 64) - if err == nil { - if intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - uintv, err := strconv.ParseUint(plain[2:], 8, 64) - if err == nil { - return intTag, uintv - } - } else if strings.HasPrefix(plain, "-0o") { - intv, err := strconv.ParseInt("-"+plain[3:], 8, 64) - if err == nil { - if true || intv == int64(int(intv)) { - return intTag, int(intv) - } else { - return intTag, intv - } - } - } - default: - panic("internal error: missing handler for resolver table: " + string(rune(hint)) + " (with " + in + ")") - } - } - return strTag, in -} - -// encodeBase64 encodes s as base64 that is broken up into multiple lines -// as appropriate for the resulting length. -func encodeBase64(s string) string { - const lineLen = 70 - encLen := base64.StdEncoding.EncodedLen(len(s)) - lines := encLen/lineLen + 1 - buf := make([]byte, encLen*2+lines) - in := buf[0:encLen] - out := buf[encLen:] - base64.StdEncoding.Encode(in, []byte(s)) - k := 0 - for i := 0; i < len(in); i += lineLen { - j := i + lineLen - if j > len(in) { - j = len(in) - } - k += copy(out[k:], in[i:j]) - if lines > 1 { - out[k] = '\n' - k++ - } - } - return string(out[:k]) -} - -// This is a subset of the formats allowed by the regular expression -// defined at http://yaml.org/type/timestamp.html. -var allowedTimestampFormats = []string{ - "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields. - "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t". - "2006-1-2 15:4:5.999999999", // space separated with no time zone - "2006-1-2", // date only - // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5" - // from the set of examples. -} - -// parseTimestamp parses s as a timestamp string and -// returns the timestamp and reports whether it succeeded. -// Timestamp formats are defined at http://yaml.org/type/timestamp.html -func parseTimestamp(s string) (time.Time, bool) { - // TODO write code to check all the formats supported by - // http://yaml.org/type/timestamp.html instead of using time.Parse. - - // Quick check: all date formats start with YYYY-. - i := 0 - for ; i < len(s); i++ { - if c := s[i]; c < '0' || c > '9' { - break - } - } - if i != 4 || i == len(s) || s[i] != '-' { - return time.Time{}, false - } - for _, format := range allowedTimestampFormats { - if t, err := time.Parse(format, s); err == nil { - return t, true - } - } - return time.Time{}, false -} diff --git a/vendor/gopkg.in/yaml.v3/scannerc.go b/vendor/gopkg.in/yaml.v3/scannerc.go deleted file mode 100644 index ca007010..00000000 --- a/vendor/gopkg.in/yaml.v3/scannerc.go +++ /dev/null @@ -1,3038 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -import ( - "bytes" - "fmt" -) - -// Introduction -// ************ -// -// The following notes assume that you are familiar with the YAML specification -// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in -// some cases we are less restrictive that it requires. -// -// The process of transforming a YAML stream into a sequence of events is -// divided on two steps: Scanning and Parsing. -// -// The Scanner transforms the input stream into a sequence of tokens, while the -// parser transform the sequence of tokens produced by the Scanner into a -// sequence of parsing events. -// -// The Scanner is rather clever and complicated. The Parser, on the contrary, -// is a straightforward implementation of a recursive-descendant parser (or, -// LL(1) parser, as it is usually called). -// -// Actually there are two issues of Scanning that might be called "clever", the -// rest is quite straightforward. The issues are "block collection start" and -// "simple keys". Both issues are explained below in details. -// -// Here the Scanning step is explained and implemented. We start with the list -// of all the tokens produced by the Scanner together with short descriptions. -// -// Now, tokens: -// -// STREAM-START(encoding) # The stream start. -// STREAM-END # The stream end. -// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. -// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. -// DOCUMENT-START # '---' -// DOCUMENT-END # '...' -// BLOCK-SEQUENCE-START # Indentation increase denoting a block -// BLOCK-MAPPING-START # sequence or a block mapping. -// BLOCK-END # Indentation decrease. -// FLOW-SEQUENCE-START # '[' -// FLOW-SEQUENCE-END # ']' -// BLOCK-SEQUENCE-START # '{' -// BLOCK-SEQUENCE-END # '}' -// BLOCK-ENTRY # '-' -// FLOW-ENTRY # ',' -// KEY # '?' or nothing (simple keys). -// VALUE # ':' -// ALIAS(anchor) # '*anchor' -// ANCHOR(anchor) # '&anchor' -// TAG(handle,suffix) # '!handle!suffix' -// SCALAR(value,style) # A scalar. -// -// The following two tokens are "virtual" tokens denoting the beginning and the -// end of the stream: -// -// STREAM-START(encoding) -// STREAM-END -// -// We pass the information about the input stream encoding with the -// STREAM-START token. -// -// The next two tokens are responsible for tags: -// -// VERSION-DIRECTIVE(major,minor) -// TAG-DIRECTIVE(handle,prefix) -// -// Example: -// -// %YAML 1.1 -// %TAG ! !foo -// %TAG !yaml! tag:yaml.org,2002: -// --- -// -// The correspoding sequence of tokens: -// -// STREAM-START(utf-8) -// VERSION-DIRECTIVE(1,1) -// TAG-DIRECTIVE("!","!foo") -// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") -// DOCUMENT-START -// STREAM-END -// -// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole -// line. -// -// The document start and end indicators are represented by: -// -// DOCUMENT-START -// DOCUMENT-END -// -// Note that if a YAML stream contains an implicit document (without '---' -// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be -// produced. -// -// In the following examples, we present whole documents together with the -// produced tokens. -// -// 1. An implicit document: -// -// 'a scalar' -// -// Tokens: -// -// STREAM-START(utf-8) -// SCALAR("a scalar",single-quoted) -// STREAM-END -// -// 2. An explicit document: -// -// --- -// 'a scalar' -// ... -// -// Tokens: -// -// STREAM-START(utf-8) -// DOCUMENT-START -// SCALAR("a scalar",single-quoted) -// DOCUMENT-END -// STREAM-END -// -// 3. Several documents in a stream: -// -// 'a scalar' -// --- -// 'another scalar' -// --- -// 'yet another scalar' -// -// Tokens: -// -// STREAM-START(utf-8) -// SCALAR("a scalar",single-quoted) -// DOCUMENT-START -// SCALAR("another scalar",single-quoted) -// DOCUMENT-START -// SCALAR("yet another scalar",single-quoted) -// STREAM-END -// -// We have already introduced the SCALAR token above. The following tokens are -// used to describe aliases, anchors, tag, and scalars: -// -// ALIAS(anchor) -// ANCHOR(anchor) -// TAG(handle,suffix) -// SCALAR(value,style) -// -// The following series of examples illustrate the usage of these tokens: -// -// 1. A recursive sequence: -// -// &A [ *A ] -// -// Tokens: -// -// STREAM-START(utf-8) -// ANCHOR("A") -// FLOW-SEQUENCE-START -// ALIAS("A") -// FLOW-SEQUENCE-END -// STREAM-END -// -// 2. A tagged scalar: -// -// !!float "3.14" # A good approximation. -// -// Tokens: -// -// STREAM-START(utf-8) -// TAG("!!","float") -// SCALAR("3.14",double-quoted) -// STREAM-END -// -// 3. Various scalar styles: -// -// --- # Implicit empty plain scalars do not produce tokens. -// --- a plain scalar -// --- 'a single-quoted scalar' -// --- "a double-quoted scalar" -// --- |- -// a literal scalar -// --- >- -// a folded -// scalar -// -// Tokens: -// -// STREAM-START(utf-8) -// DOCUMENT-START -// DOCUMENT-START -// SCALAR("a plain scalar",plain) -// DOCUMENT-START -// SCALAR("a single-quoted scalar",single-quoted) -// DOCUMENT-START -// SCALAR("a double-quoted scalar",double-quoted) -// DOCUMENT-START -// SCALAR("a literal scalar",literal) -// DOCUMENT-START -// SCALAR("a folded scalar",folded) -// STREAM-END -// -// Now it's time to review collection-related tokens. We will start with -// flow collections: -// -// FLOW-SEQUENCE-START -// FLOW-SEQUENCE-END -// FLOW-MAPPING-START -// FLOW-MAPPING-END -// FLOW-ENTRY -// KEY -// VALUE -// -// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and -// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' -// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the -// indicators '?' and ':', which are used for denoting mapping keys and values, -// are represented by the KEY and VALUE tokens. -// -// The following examples show flow collections: -// -// 1. A flow sequence: -// -// [item 1, item 2, item 3] -// -// Tokens: -// -// STREAM-START(utf-8) -// FLOW-SEQUENCE-START -// SCALAR("item 1",plain) -// FLOW-ENTRY -// SCALAR("item 2",plain) -// FLOW-ENTRY -// SCALAR("item 3",plain) -// FLOW-SEQUENCE-END -// STREAM-END -// -// 2. A flow mapping: -// -// { -// a simple key: a value, # Note that the KEY token is produced. -// ? a complex key: another value, -// } -// -// Tokens: -// -// STREAM-START(utf-8) -// FLOW-MAPPING-START -// KEY -// SCALAR("a simple key",plain) -// VALUE -// SCALAR("a value",plain) -// FLOW-ENTRY -// KEY -// SCALAR("a complex key",plain) -// VALUE -// SCALAR("another value",plain) -// FLOW-ENTRY -// FLOW-MAPPING-END -// STREAM-END -// -// A simple key is a key which is not denoted by the '?' indicator. Note that -// the Scanner still produce the KEY token whenever it encounters a simple key. -// -// For scanning block collections, the following tokens are used (note that we -// repeat KEY and VALUE here): -// -// BLOCK-SEQUENCE-START -// BLOCK-MAPPING-START -// BLOCK-END -// BLOCK-ENTRY -// KEY -// VALUE -// -// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation -// increase that precedes a block collection (cf. the INDENT token in Python). -// The token BLOCK-END denote indentation decrease that ends a block collection -// (cf. the DEDENT token in Python). However YAML has some syntax pecularities -// that makes detections of these tokens more complex. -// -// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators -// '-', '?', and ':' correspondingly. -// -// The following examples show how the tokens BLOCK-SEQUENCE-START, -// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: -// -// 1. Block sequences: -// -// - item 1 -// - item 2 -// - -// - item 3.1 -// - item 3.2 -// - -// key 1: value 1 -// key 2: value 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-ENTRY -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 3.1",plain) -// BLOCK-ENTRY -// SCALAR("item 3.2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// 2. Block mappings: -// -// a simple key: a value # The KEY token is produced here. -// ? a complex key -// : another value -// a mapping: -// key 1: value 1 -// key 2: value 2 -// a sequence: -// - item 1 -// - item 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("a simple key",plain) -// VALUE -// SCALAR("a value",plain) -// KEY -// SCALAR("a complex key",plain) -// VALUE -// SCALAR("another value",plain) -// KEY -// SCALAR("a mapping",plain) -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// KEY -// SCALAR("a sequence",plain) -// VALUE -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// YAML does not always require to start a new block collection from a new -// line. If the current line contains only '-', '?', and ':' indicators, a new -// block collection may start at the current line. The following examples -// illustrate this case: -// -// 1. Collections in a sequence: -// -// - - item 1 -// - item 2 -// - key 1: value 1 -// key 2: value 2 -// - ? complex key -// : complex value -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-ENTRY -// BLOCK-MAPPING-START -// KEY -// SCALAR("complex key") -// VALUE -// SCALAR("complex value") -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// 2. Collections in a mapping: -// -// ? a sequence -// : - item 1 -// - item 2 -// ? a mapping -// : key 1: value 1 -// key 2: value 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("a sequence",plain) -// VALUE -// BLOCK-SEQUENCE-START -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// KEY -// SCALAR("a mapping",plain) -// VALUE -// BLOCK-MAPPING-START -// KEY -// SCALAR("key 1",plain) -// VALUE -// SCALAR("value 1",plain) -// KEY -// SCALAR("key 2",plain) -// VALUE -// SCALAR("value 2",plain) -// BLOCK-END -// BLOCK-END -// STREAM-END -// -// YAML also permits non-indented sequences if they are included into a block -// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: -// -// key: -// - item 1 # BLOCK-SEQUENCE-START is NOT produced here. -// - item 2 -// -// Tokens: -// -// STREAM-START(utf-8) -// BLOCK-MAPPING-START -// KEY -// SCALAR("key",plain) -// VALUE -// BLOCK-ENTRY -// SCALAR("item 1",plain) -// BLOCK-ENTRY -// SCALAR("item 2",plain) -// BLOCK-END -// - -// Ensure that the buffer contains the required number of characters. -// Return true on success, false on failure (reader error or memory error). -func cache(parser *yaml_parser_t, length int) bool { - // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B) - return parser.unread >= length || yaml_parser_update_buffer(parser, length) -} - -// Advance the buffer pointer. -func skip(parser *yaml_parser_t) { - if !is_blank(parser.buffer, parser.buffer_pos) { - parser.newlines = 0 - } - parser.mark.index++ - parser.mark.column++ - parser.unread-- - parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) -} - -func skip_line(parser *yaml_parser_t) { - if is_crlf(parser.buffer, parser.buffer_pos) { - parser.mark.index += 2 - parser.mark.column = 0 - parser.mark.line++ - parser.unread -= 2 - parser.buffer_pos += 2 - parser.newlines++ - } else if is_break(parser.buffer, parser.buffer_pos) { - parser.mark.index++ - parser.mark.column = 0 - parser.mark.line++ - parser.unread-- - parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) - parser.newlines++ - } -} - -// Copy a character to a string buffer and advance pointers. -func read(parser *yaml_parser_t, s []byte) []byte { - if !is_blank(parser.buffer, parser.buffer_pos) { - parser.newlines = 0 - } - w := width(parser.buffer[parser.buffer_pos]) - if w == 0 { - panic("invalid character sequence") - } - if len(s) == 0 { - s = make([]byte, 0, 32) - } - if w == 1 && len(s)+w <= cap(s) { - s = s[:len(s)+1] - s[len(s)-1] = parser.buffer[parser.buffer_pos] - parser.buffer_pos++ - } else { - s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...) - parser.buffer_pos += w - } - parser.mark.index++ - parser.mark.column++ - parser.unread-- - return s -} - -// Copy a line break character to a string buffer and advance pointers. -func read_line(parser *yaml_parser_t, s []byte) []byte { - buf := parser.buffer - pos := parser.buffer_pos - switch { - case buf[pos] == '\r' && buf[pos+1] == '\n': - // CR LF . LF - s = append(s, '\n') - parser.buffer_pos += 2 - parser.mark.index++ - parser.unread-- - case buf[pos] == '\r' || buf[pos] == '\n': - // CR|LF . LF - s = append(s, '\n') - parser.buffer_pos += 1 - case buf[pos] == '\xC2' && buf[pos+1] == '\x85': - // NEL . LF - s = append(s, '\n') - parser.buffer_pos += 2 - case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'): - // LS|PS . LS|PS - s = append(s, buf[parser.buffer_pos:pos+3]...) - parser.buffer_pos += 3 - default: - return s - } - parser.mark.index++ - parser.mark.column = 0 - parser.mark.line++ - parser.unread-- - parser.newlines++ - return s -} - -// Get the next token. -func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool { - // Erase the token object. - *token = yaml_token_t{} // [Go] Is this necessary? - - // No tokens after STREAM-END or error. - if parser.stream_end_produced || parser.error != yaml_NO_ERROR { - return true - } - - // Ensure that the tokens queue contains enough tokens. - if !parser.token_available { - if !yaml_parser_fetch_more_tokens(parser) { - return false - } - } - - // Fetch the next token from the queue. - *token = parser.tokens[parser.tokens_head] - parser.tokens_head++ - parser.tokens_parsed++ - parser.token_available = false - - if token.typ == yaml_STREAM_END_TOKEN { - parser.stream_end_produced = true - } - return true -} - -// Set the scanner error and return false. -func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool { - parser.error = yaml_SCANNER_ERROR - parser.context = context - parser.context_mark = context_mark - parser.problem = problem - parser.problem_mark = parser.mark - return false -} - -func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool { - context := "while parsing a tag" - if directive { - context = "while parsing a %TAG directive" - } - return yaml_parser_set_scanner_error(parser, context, context_mark, problem) -} - -func trace(args ...interface{}) func() { - pargs := append([]interface{}{"+++"}, args...) - fmt.Println(pargs...) - pargs = append([]interface{}{"---"}, args...) - return func() { fmt.Println(pargs...) } -} - -// Ensure that the tokens queue contains at least one token which can be -// returned to the Parser. -func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { - // While we need more tokens to fetch, do it. - for { - // [Go] The comment parsing logic requires a lookahead of two tokens - // so that foot comments may be parsed in time of associating them - // with the tokens that are parsed before them, and also for line - // comments to be transformed into head comments in some edge cases. - if parser.tokens_head < len(parser.tokens)-2 { - // If a potential simple key is at the head position, we need to fetch - // the next token to disambiguate it. - head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed] - if !ok { - break - } else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok { - return false - } else if !valid { - break - } - } - // Fetch the next token. - if !yaml_parser_fetch_next_token(parser) { - return false - } - } - - parser.token_available = true - return true -} - -// The dispatcher for token fetchers. -func yaml_parser_fetch_next_token(parser *yaml_parser_t) (ok bool) { - // Ensure that the buffer is initialized. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check if we just started scanning. Fetch STREAM-START then. - if !parser.stream_start_produced { - return yaml_parser_fetch_stream_start(parser) - } - - scan_mark := parser.mark - - // Eat whitespaces and comments until we reach the next token. - if !yaml_parser_scan_to_next_token(parser) { - return false - } - - // [Go] While unrolling indents, transform the head comments of prior - // indentation levels observed after scan_start into foot comments at - // the respective indexes. - - // Check the indentation level against the current column. - if !yaml_parser_unroll_indent(parser, parser.mark.column, scan_mark) { - return false - } - - // Ensure that the buffer contains at least 4 characters. 4 is the length - // of the longest indicators ('--- ' and '... '). - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - - // Is it the end of the stream? - if is_z(parser.buffer, parser.buffer_pos) { - return yaml_parser_fetch_stream_end(parser) - } - - // Is it a directive? - if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' { - return yaml_parser_fetch_directive(parser) - } - - buf := parser.buffer - pos := parser.buffer_pos - - // Is it the document start indicator? - if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) { - return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN) - } - - // Is it the document end indicator? - if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) { - return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN) - } - - comment_mark := parser.mark - if len(parser.tokens) > 0 && (parser.flow_level == 0 && buf[pos] == ':' || parser.flow_level > 0 && buf[pos] == ',') { - // Associate any following comments with the prior token. - comment_mark = parser.tokens[len(parser.tokens)-1].start_mark - } - defer func() { - if !ok { - return - } - if len(parser.tokens) > 0 && parser.tokens[len(parser.tokens)-1].typ == yaml_BLOCK_ENTRY_TOKEN { - // Sequence indicators alone have no line comments. It becomes - // a head comment for whatever follows. - return - } - if !yaml_parser_scan_line_comment(parser, comment_mark) { - ok = false - return - } - }() - - // Is it the flow sequence start indicator? - if buf[pos] == '[' { - return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN) - } - - // Is it the flow mapping start indicator? - if parser.buffer[parser.buffer_pos] == '{' { - return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN) - } - - // Is it the flow sequence end indicator? - if parser.buffer[parser.buffer_pos] == ']' { - return yaml_parser_fetch_flow_collection_end(parser, - yaml_FLOW_SEQUENCE_END_TOKEN) - } - - // Is it the flow mapping end indicator? - if parser.buffer[parser.buffer_pos] == '}' { - return yaml_parser_fetch_flow_collection_end(parser, - yaml_FLOW_MAPPING_END_TOKEN) - } - - // Is it the flow entry indicator? - if parser.buffer[parser.buffer_pos] == ',' { - return yaml_parser_fetch_flow_entry(parser) - } - - // Is it the block entry indicator? - if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) { - return yaml_parser_fetch_block_entry(parser) - } - - // Is it the key indicator? - if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_key(parser) - } - - // Is it the value indicator? - if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_value(parser) - } - - // Is it an alias? - if parser.buffer[parser.buffer_pos] == '*' { - return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN) - } - - // Is it an anchor? - if parser.buffer[parser.buffer_pos] == '&' { - return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN) - } - - // Is it a tag? - if parser.buffer[parser.buffer_pos] == '!' { - return yaml_parser_fetch_tag(parser) - } - - // Is it a literal scalar? - if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 { - return yaml_parser_fetch_block_scalar(parser, true) - } - - // Is it a folded scalar? - if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 { - return yaml_parser_fetch_block_scalar(parser, false) - } - - // Is it a single-quoted scalar? - if parser.buffer[parser.buffer_pos] == '\'' { - return yaml_parser_fetch_flow_scalar(parser, true) - } - - // Is it a double-quoted scalar? - if parser.buffer[parser.buffer_pos] == '"' { - return yaml_parser_fetch_flow_scalar(parser, false) - } - - // Is it a plain scalar? - // - // A plain scalar may start with any non-blank characters except - // - // '-', '?', ':', ',', '[', ']', '{', '}', - // '#', '&', '*', '!', '|', '>', '\'', '\"', - // '%', '@', '`'. - // - // In the block context (and, for the '-' indicator, in the flow context - // too), it may also start with the characters - // - // '-', '?', ':' - // - // if it is followed by a non-space character. - // - // The last rule is more restrictive than the specification requires. - // [Go] TODO Make this logic more reasonable. - //switch parser.buffer[parser.buffer_pos] { - //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`': - //} - if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' || - parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' || - parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || - parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' || - parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' || - parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' || - parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' || - parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' || - parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') || - (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) || - (parser.flow_level == 0 && - (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') && - !is_blankz(parser.buffer, parser.buffer_pos+1)) { - return yaml_parser_fetch_plain_scalar(parser) - } - - // If we don't determine the token type so far, it is an error. - return yaml_parser_set_scanner_error(parser, - "while scanning for the next token", parser.mark, - "found character that cannot start any token") -} - -func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) { - if !simple_key.possible { - return false, true - } - - // The 1.2 specification says: - // - // "If the ? indicator is omitted, parsing needs to see past the - // implicit key to recognize it as such. To limit the amount of - // lookahead required, the “:” indicator must appear at most 1024 - // Unicode characters beyond the start of the key. In addition, the key - // is restricted to a single line." - // - if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index { - // Check if the potential simple key to be removed is required. - if simple_key.required { - return false, yaml_parser_set_scanner_error(parser, - "while scanning a simple key", simple_key.mark, - "could not find expected ':'") - } - simple_key.possible = false - return false, true - } - return true, true -} - -// Check if a simple key may start at the current position and add it if -// needed. -func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { - // A simple key is required at the current position if the scanner is in - // the block context and the current column coincides with the indentation - // level. - - required := parser.flow_level == 0 && parser.indent == parser.mark.column - - // - // If the current position may start a simple key, save it. - // - if parser.simple_key_allowed { - simple_key := yaml_simple_key_t{ - possible: true, - required: required, - token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), - mark: parser.mark, - } - - if !yaml_parser_remove_simple_key(parser) { - return false - } - parser.simple_keys[len(parser.simple_keys)-1] = simple_key - parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1 - } - return true -} - -// Remove a potential simple key at the current flow level. -func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool { - i := len(parser.simple_keys) - 1 - if parser.simple_keys[i].possible { - // If the key is required, it is an error. - if parser.simple_keys[i].required { - return yaml_parser_set_scanner_error(parser, - "while scanning a simple key", parser.simple_keys[i].mark, - "could not find expected ':'") - } - // Remove the key from the stack. - parser.simple_keys[i].possible = false - delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number) - } - return true -} - -// max_flow_level limits the flow_level -const max_flow_level = 10000 - -// Increase the flow level and resize the simple key list if needed. -func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { - // Reset the simple key on the next level. - parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{ - possible: false, - required: false, - token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), - mark: parser.mark, - }) - - // Increase the flow level. - parser.flow_level++ - if parser.flow_level > max_flow_level { - return yaml_parser_set_scanner_error(parser, - "while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark, - fmt.Sprintf("exceeded max depth of %d", max_flow_level)) - } - return true -} - -// Decrease the flow level. -func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { - if parser.flow_level > 0 { - parser.flow_level-- - last := len(parser.simple_keys) - 1 - delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number) - parser.simple_keys = parser.simple_keys[:last] - } - return true -} - -// max_indents limits the indents stack size -const max_indents = 10000 - -// Push the current indentation level to the stack and set the new level -// the current column is greater than the indentation level. In this case, -// append or insert the specified token into the token queue. -func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool { - // In the flow context, do nothing. - if parser.flow_level > 0 { - return true - } - - if parser.indent < column { - // Push the current indentation level to the stack and set the new - // indentation level. - parser.indents = append(parser.indents, parser.indent) - parser.indent = column - if len(parser.indents) > max_indents { - return yaml_parser_set_scanner_error(parser, - "while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark, - fmt.Sprintf("exceeded max depth of %d", max_indents)) - } - - // Create a token and insert it into the queue. - token := yaml_token_t{ - typ: typ, - start_mark: mark, - end_mark: mark, - } - if number > -1 { - number -= parser.tokens_parsed - } - yaml_insert_token(parser, number, &token) - } - return true -} - -// Pop indentation levels from the indents stack until the current level -// becomes less or equal to the column. For each indentation level, append -// the BLOCK-END token. -func yaml_parser_unroll_indent(parser *yaml_parser_t, column int, scan_mark yaml_mark_t) bool { - // In the flow context, do nothing. - if parser.flow_level > 0 { - return true - } - - block_mark := scan_mark - block_mark.index-- - - // Loop through the indentation levels in the stack. - for parser.indent > column { - - // [Go] Reposition the end token before potential following - // foot comments of parent blocks. For that, search - // backwards for recent comments that were at the same - // indent as the block that is ending now. - stop_index := block_mark.index - for i := len(parser.comments) - 1; i >= 0; i-- { - comment := &parser.comments[i] - - if comment.end_mark.index < stop_index { - // Don't go back beyond the start of the comment/whitespace scan, unless column < 0. - // If requested indent column is < 0, then the document is over and everything else - // is a foot anyway. - break - } - if comment.start_mark.column == parser.indent+1 { - // This is a good match. But maybe there's a former comment - // at that same indent level, so keep searching. - block_mark = comment.start_mark - } - - // While the end of the former comment matches with - // the start of the following one, we know there's - // nothing in between and scanning is still safe. - stop_index = comment.scan_mark.index - } - - // Create a token and append it to the queue. - token := yaml_token_t{ - typ: yaml_BLOCK_END_TOKEN, - start_mark: block_mark, - end_mark: block_mark, - } - yaml_insert_token(parser, -1, &token) - - // Pop the indentation level. - parser.indent = parser.indents[len(parser.indents)-1] - parser.indents = parser.indents[:len(parser.indents)-1] - } - return true -} - -// Initialize the scanner and produce the STREAM-START token. -func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool { - - // Set the initial indentation. - parser.indent = -1 - - // Initialize the simple key stack. - parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) - - parser.simple_keys_by_tok = make(map[int]int) - - // A simple key is allowed at the beginning of the stream. - parser.simple_key_allowed = true - - // We have started. - parser.stream_start_produced = true - - // Create the STREAM-START token and append it to the queue. - token := yaml_token_t{ - typ: yaml_STREAM_START_TOKEN, - start_mark: parser.mark, - end_mark: parser.mark, - encoding: parser.encoding, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the STREAM-END token and shut down the scanner. -func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool { - - // Force new line. - if parser.mark.column != 0 { - parser.mark.column = 0 - parser.mark.line++ - } - - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1, parser.mark) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Create the STREAM-END token and append it to the queue. - token := yaml_token_t{ - typ: yaml_STREAM_END_TOKEN, - start_mark: parser.mark, - end_mark: parser.mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. -func yaml_parser_fetch_directive(parser *yaml_parser_t) bool { - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1, parser.mark) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. - token := yaml_token_t{} - if !yaml_parser_scan_directive(parser, &token) { - return false - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the DOCUMENT-START or DOCUMENT-END token. -func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // Reset the indentation level. - if !yaml_parser_unroll_indent(parser, -1, parser.mark) { - return false - } - - // Reset simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - parser.simple_key_allowed = false - - // Consume the token. - start_mark := parser.mark - - skip(parser) - skip(parser) - skip(parser) - - end_mark := parser.mark - - // Create the DOCUMENT-START or DOCUMENT-END token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. -func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool { - - // The indicators '[' and '{' may start a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // Increase the flow level. - if !yaml_parser_increase_flow_level(parser) { - return false - } - - // A simple key may follow the indicators '[' and '{'. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. -func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // Reset any potential simple key on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Decrease the flow level. - if !yaml_parser_decrease_flow_level(parser) { - return false - } - - // No simple keys after the indicators ']' and '}'. - parser.simple_key_allowed = false - - // Consume the token. - - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. - token := yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - } - // Append the token to the queue. - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the FLOW-ENTRY token. -func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool { - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after ','. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the FLOW-ENTRY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_FLOW_ENTRY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the BLOCK-ENTRY token. -func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool { - // Check if the scanner is in the block context. - if parser.flow_level == 0 { - // Check if we are allowed to start a new entry. - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "block sequence entries are not allowed in this context") - } - // Add the BLOCK-SEQUENCE-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) { - return false - } - } else { - // It is an error for the '-' indicator to occur in the flow context, - // but we let the Parser detect and report about it because the Parser - // is able to point to the context. - } - - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after '-'. - parser.simple_key_allowed = true - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the BLOCK-ENTRY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_BLOCK_ENTRY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the KEY token. -func yaml_parser_fetch_key(parser *yaml_parser_t) bool { - - // In the block context, additional checks are required. - if parser.flow_level == 0 { - // Check if we are allowed to start a new key (not nessesary simple). - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "mapping keys are not allowed in this context") - } - // Add the BLOCK-MAPPING-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { - return false - } - } - - // Reset any potential simple keys on the current flow level. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // Simple keys are allowed after '?' in the block context. - parser.simple_key_allowed = parser.flow_level == 0 - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the KEY token and append it to the queue. - token := yaml_token_t{ - typ: yaml_KEY_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the VALUE token. -func yaml_parser_fetch_value(parser *yaml_parser_t) bool { - - simple_key := &parser.simple_keys[len(parser.simple_keys)-1] - - // Have we found a simple key? - if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok { - return false - - } else if valid { - - // Create the KEY token and insert it into the queue. - token := yaml_token_t{ - typ: yaml_KEY_TOKEN, - start_mark: simple_key.mark, - end_mark: simple_key.mark, - } - yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token) - - // In the block context, we may need to add the BLOCK-MAPPING-START token. - if !yaml_parser_roll_indent(parser, simple_key.mark.column, - simple_key.token_number, - yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) { - return false - } - - // Remove the simple key. - simple_key.possible = false - delete(parser.simple_keys_by_tok, simple_key.token_number) - - // A simple key cannot follow another simple key. - parser.simple_key_allowed = false - - } else { - // The ':' indicator follows a complex key. - - // In the block context, extra checks are required. - if parser.flow_level == 0 { - - // Check if we are allowed to start a complex value. - if !parser.simple_key_allowed { - return yaml_parser_set_scanner_error(parser, "", parser.mark, - "mapping values are not allowed in this context") - } - - // Add the BLOCK-MAPPING-START token if needed. - if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { - return false - } - } - - // Simple keys after ':' are allowed in the block context. - parser.simple_key_allowed = parser.flow_level == 0 - } - - // Consume the token. - start_mark := parser.mark - skip(parser) - end_mark := parser.mark - - // Create the VALUE token and append it to the queue. - token := yaml_token_t{ - typ: yaml_VALUE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the ALIAS or ANCHOR token. -func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool { - // An anchor or an alias could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow an anchor or an alias. - parser.simple_key_allowed = false - - // Create the ALIAS or ANCHOR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_anchor(parser, &token, typ) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the TAG token. -func yaml_parser_fetch_tag(parser *yaml_parser_t) bool { - // A tag could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a tag. - parser.simple_key_allowed = false - - // Create the TAG token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_tag(parser, &token) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. -func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool { - // Remove any potential simple keys. - if !yaml_parser_remove_simple_key(parser) { - return false - } - - // A simple key may follow a block scalar. - parser.simple_key_allowed = true - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_block_scalar(parser, &token, literal) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. -func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool { - // A plain scalar could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a flow scalar. - parser.simple_key_allowed = false - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_flow_scalar(parser, &token, single) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Produce the SCALAR(...,plain) token. -func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool { - // A plain scalar could be a simple key. - if !yaml_parser_save_simple_key(parser) { - return false - } - - // A simple key cannot follow a flow scalar. - parser.simple_key_allowed = false - - // Create the SCALAR token and append it to the queue. - var token yaml_token_t - if !yaml_parser_scan_plain_scalar(parser, &token) { - return false - } - yaml_insert_token(parser, -1, &token) - return true -} - -// Eat whitespaces and comments until the next token is found. -func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool { - - scan_mark := parser.mark - - // Until the next token is not found. - for { - // Allow the BOM mark to start a line. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) { - skip(parser) - } - - // Eat whitespaces. - // Tabs are allowed: - // - in the flow context - // - in the block context, but not at the beginning of the line or - // after '-', '?', or ':' (complex value). - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if we just had a line comment under a sequence entry that - // looks more like a header to the following content. Similar to this: - // - // - # The comment - // - Some data - // - // If so, transform the line comment to a head comment and reposition. - if len(parser.comments) > 0 && len(parser.tokens) > 1 { - tokenA := parser.tokens[len(parser.tokens)-2] - tokenB := parser.tokens[len(parser.tokens)-1] - comment := &parser.comments[len(parser.comments)-1] - if tokenA.typ == yaml_BLOCK_SEQUENCE_START_TOKEN && tokenB.typ == yaml_BLOCK_ENTRY_TOKEN && len(comment.line) > 0 && !is_break(parser.buffer, parser.buffer_pos) { - // If it was in the prior line, reposition so it becomes a - // header of the follow up token. Otherwise, keep it in place - // so it becomes a header of the former. - comment.head = comment.line - comment.line = nil - if comment.start_mark.line == parser.mark.line-1 { - comment.token_mark = parser.mark - } - } - } - - // Eat a comment until a line break. - if parser.buffer[parser.buffer_pos] == '#' { - if !yaml_parser_scan_comments(parser, scan_mark) { - return false - } - } - - // If it is a line break, eat it. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - - // In the block context, a new line may start a simple key. - if parser.flow_level == 0 { - parser.simple_key_allowed = true - } - } else { - break // We have found a token. - } - } - - return true -} - -// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// -func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool { - // Eat '%'. - start_mark := parser.mark - skip(parser) - - // Scan the directive name. - var name []byte - if !yaml_parser_scan_directive_name(parser, start_mark, &name) { - return false - } - - // Is it a YAML directive? - if bytes.Equal(name, []byte("YAML")) { - // Scan the VERSION directive value. - var major, minor int8 - if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) { - return false - } - end_mark := parser.mark - - // Create a VERSION-DIRECTIVE token. - *token = yaml_token_t{ - typ: yaml_VERSION_DIRECTIVE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - major: major, - minor: minor, - } - - // Is it a TAG directive? - } else if bytes.Equal(name, []byte("TAG")) { - // Scan the TAG directive value. - var handle, prefix []byte - if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) { - return false - } - end_mark := parser.mark - - // Create a TAG-DIRECTIVE token. - *token = yaml_token_t{ - typ: yaml_TAG_DIRECTIVE_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: handle, - prefix: prefix, - } - - // Unknown directive. - } else { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unknown directive name") - return false - } - - // Eat the rest of the line including any comments. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - if parser.buffer[parser.buffer_pos] == '#' { - // [Go] Discard this inline comment for the time being. - //if !yaml_parser_scan_line_comment(parser, start_mark) { - // return false - //} - for !is_breakz(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - } - - // Check if we are at the end of the line. - if !is_breakz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "did not find expected comment or line break") - return false - } - - // Eat a line break. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } - - return true -} - -// Scan the directive name. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^ -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^ -// -func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool { - // Consume the directive name. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - var s []byte - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the name is empty. - if len(s) == 0 { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "could not find expected directive name") - return false - } - - // Check for an blank character after the name. - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a directive", - start_mark, "found unexpected non-alphabetical character") - return false - } - *name = s - return true -} - -// Scan the value of VERSION-DIRECTIVE. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^^^^^^ -func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool { - // Eat whitespaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Consume the major version number. - if !yaml_parser_scan_version_directive_number(parser, start_mark, major) { - return false - } - - // Eat '.'. - if parser.buffer[parser.buffer_pos] != '.' { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected digit or '.' character") - } - - skip(parser) - - // Consume the minor version number. - if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) { - return false - } - return true -} - -const max_number_length = 2 - -// Scan the version number of VERSION-DIRECTIVE. -// -// Scope: -// %YAML 1.1 # a comment \n -// ^ -// %YAML 1.1 # a comment \n -// ^ -func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool { - - // Repeat while the next character is digit. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - var value, length int8 - for is_digit(parser.buffer, parser.buffer_pos) { - // Check if the number is too long. - length++ - if length > max_number_length { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "found extremely long version number") - } - value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos)) - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the number was present. - if length == 0 { - return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", - start_mark, "did not find expected version number") - } - *number = value - return true -} - -// Scan the value of a TAG-DIRECTIVE token. -// -// Scope: -// %TAG !yaml! tag:yaml.org,2002: \n -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -// -func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool { - var handle_value, prefix_value []byte - - // Eat whitespaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Scan a handle. - if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) { - return false - } - - // Expect a whitespace. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blank(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace") - return false - } - - // Eat whitespaces. - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Scan a prefix. - if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) { - return false - } - - // Expect a whitespace or line break. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", - start_mark, "did not find expected whitespace or line break") - return false - } - - *handle = handle_value - *prefix = prefix_value - return true -} - -func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool { - var s []byte - - // Eat the indicator character. - start_mark := parser.mark - skip(parser) - - // Consume the value. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - end_mark := parser.mark - - /* - * Check if length of the anchor is greater than 0 and it is followed by - * a whitespace character or one of the indicators: - * - * '?', ':', ',', ']', '}', '%', '@', '`'. - */ - - if len(s) == 0 || - !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' || - parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' || - parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' || - parser.buffer[parser.buffer_pos] == '`') { - context := "while scanning an alias" - if typ == yaml_ANCHOR_TOKEN { - context = "while scanning an anchor" - } - yaml_parser_set_scanner_error(parser, context, start_mark, - "did not find expected alphabetic or numeric character") - return false - } - - // Create a token. - *token = yaml_token_t{ - typ: typ, - start_mark: start_mark, - end_mark: end_mark, - value: s, - } - - return true -} - -/* - * Scan a TAG token. - */ - -func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool { - var handle, suffix []byte - - start_mark := parser.mark - - // Check if the tag is in the canonical form. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - if parser.buffer[parser.buffer_pos+1] == '<' { - // Keep the handle as '' - - // Eat '!<' - skip(parser) - skip(parser) - - // Consume the tag value. - if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { - return false - } - - // Check for '>' and eat it. - if parser.buffer[parser.buffer_pos] != '>' { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find the expected '>'") - return false - } - - skip(parser) - } else { - // The tag has either the '!suffix' or the '!handle!suffix' form. - - // First, try to scan a handle. - if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) { - return false - } - - // Check if it is, indeed, handle. - if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' { - // Scan the suffix now. - if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { - return false - } - } else { - // It wasn't a handle after all. Scan the rest of the tag. - if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) { - return false - } - - // Set the handle to '!'. - handle = []byte{'!'} - - // A special case: the '!' tag. Set the handle to '' and the - // suffix to '!'. - if len(suffix) == 0 { - handle, suffix = suffix, handle - } - } - } - - // Check the character which ends the tag. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if !is_blankz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a tag", - start_mark, "did not find expected whitespace or line break") - return false - } - - end_mark := parser.mark - - // Create a token. - *token = yaml_token_t{ - typ: yaml_TAG_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: handle, - suffix: suffix, - } - return true -} - -// Scan a tag handle. -func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool { - // Check the initial '!' character. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.buffer[parser.buffer_pos] != '!' { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected '!'") - return false - } - - var s []byte - - // Copy the '!' character. - s = read(parser, s) - - // Copy all subsequent alphabetical and numerical characters. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_alpha(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check if the trailing character is '!' and copy it. - if parser.buffer[parser.buffer_pos] == '!' { - s = read(parser, s) - } else { - // It's either the '!' tag or not really a tag handle. If it's a %TAG - // directive, it's an error. If it's a tag token, it must be a part of URI. - if directive && string(s) != "!" { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected '!'") - return false - } - } - - *handle = s - return true -} - -// Scan a tag. -func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool { - //size_t length = head ? strlen((char *)head) : 0 - var s []byte - hasTag := len(head) > 0 - - // Copy the head if needed. - // - // Note that we don't copy the leading '!' character. - if len(head) > 1 { - s = append(s, head[1:]...) - } - - // Scan the tag. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // The set of characters that may appear in URI is as follows: - // - // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', - // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', - // '%'. - // [Go] TODO Convert this into more reasonable logic. - for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' || - parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' || - parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' || - parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' || - parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' || - parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' || - parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' || - parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' || - parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' || - parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' || - parser.buffer[parser.buffer_pos] == '%' { - // Check if it is a URI-escape sequence. - if parser.buffer[parser.buffer_pos] == '%' { - if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) { - return false - } - } else { - s = read(parser, s) - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - hasTag = true - } - - if !hasTag { - yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find expected tag URI") - return false - } - *uri = s - return true -} - -// Decode an URI-escape sequence corresponding to a single UTF-8 character. -func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool { - - // Decode the required number of characters. - w := 1024 - for w > 0 { - // Check for a URI-escaped octet. - if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { - return false - } - - if !(parser.buffer[parser.buffer_pos] == '%' && - is_hex(parser.buffer, parser.buffer_pos+1) && - is_hex(parser.buffer, parser.buffer_pos+2)) { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "did not find URI escaped octet") - } - - // Get the octet. - octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2)) - - // If it is the leading octet, determine the length of the UTF-8 sequence. - if w == 1024 { - w = width(octet) - if w == 0 { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "found an incorrect leading UTF-8 octet") - } - } else { - // Check if the trailing octet is correct. - if octet&0xC0 != 0x80 { - return yaml_parser_set_scanner_tag_error(parser, directive, - start_mark, "found an incorrect trailing UTF-8 octet") - } - } - - // Copy the octet and move the pointers. - *s = append(*s, octet) - skip(parser) - skip(parser) - skip(parser) - w-- - } - return true -} - -// Scan a block scalar. -func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool { - // Eat the indicator '|' or '>'. - start_mark := parser.mark - skip(parser) - - // Scan the additional block scalar indicators. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check for a chomping indicator. - var chomping, increment int - if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { - // Set the chomping method and eat the indicator. - if parser.buffer[parser.buffer_pos] == '+' { - chomping = +1 - } else { - chomping = -1 - } - skip(parser) - - // Check for an indentation indicator. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if is_digit(parser.buffer, parser.buffer_pos) { - // Check that the indentation is greater than 0. - if parser.buffer[parser.buffer_pos] == '0' { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0") - return false - } - - // Get the indentation level and eat the indicator. - increment = as_digit(parser.buffer, parser.buffer_pos) - skip(parser) - } - - } else if is_digit(parser.buffer, parser.buffer_pos) { - // Do the same as above, but in the opposite order. - - if parser.buffer[parser.buffer_pos] == '0' { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found an indentation indicator equal to 0") - return false - } - increment = as_digit(parser.buffer, parser.buffer_pos) - skip(parser) - - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { - if parser.buffer[parser.buffer_pos] == '+' { - chomping = +1 - } else { - chomping = -1 - } - skip(parser) - } - } - - // Eat whitespaces and comments to the end of the line. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for is_blank(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - if parser.buffer[parser.buffer_pos] == '#' { - if !yaml_parser_scan_line_comment(parser, start_mark) { - return false - } - for !is_breakz(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - } - - // Check if we are at the end of the line. - if !is_breakz(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "did not find expected comment or line break") - return false - } - - // Eat a line break. - if is_break(parser.buffer, parser.buffer_pos) { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } - - end_mark := parser.mark - - // Set the indentation level if it was specified. - var indent int - if increment > 0 { - if parser.indent >= 0 { - indent = parser.indent + increment - } else { - indent = increment - } - } - - // Scan the leading line breaks and determine the indentation level if needed. - var s, leading_break, trailing_breaks []byte - if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { - return false - } - - // Scan the block scalar content. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - var leading_blank, trailing_blank bool - for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) { - // We are at the beginning of a non-empty line. - - // Is it a trailing whitespace? - trailing_blank = is_blank(parser.buffer, parser.buffer_pos) - - // Check if we need to fold the leading line break. - if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' { - // Do we need to join the lines by space? - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } - } else { - s = append(s, leading_break...) - } - leading_break = leading_break[:0] - - // Append the remaining line breaks. - s = append(s, trailing_breaks...) - trailing_breaks = trailing_breaks[:0] - - // Is it a leading whitespace? - leading_blank = is_blank(parser.buffer, parser.buffer_pos) - - // Consume the current line. - for !is_breakz(parser.buffer, parser.buffer_pos) { - s = read(parser, s) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Consume the line break. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - leading_break = read_line(parser, leading_break) - - // Eat the following indentation spaces and line breaks. - if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { - return false - } - } - - // Chomp the tail. - if chomping != -1 { - s = append(s, leading_break...) - } - if chomping == 1 { - s = append(s, trailing_breaks...) - } - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_LITERAL_SCALAR_STYLE, - } - if !literal { - token.style = yaml_FOLDED_SCALAR_STYLE - } - return true -} - -// Scan indentation spaces and line breaks for a block scalar. Determine the -// indentation level if needed. -func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool { - *end_mark = parser.mark - - // Eat the indentation spaces and line breaks. - max_indent := 0 - for { - // Eat the indentation spaces. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) { - skip(parser) - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - if parser.mark.column > max_indent { - max_indent = parser.mark.column - } - - // Check for a tab character messing the indentation. - if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) { - return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", - start_mark, "found a tab character where an indentation space is expected") - } - - // Have we found a non-empty line? - if !is_break(parser.buffer, parser.buffer_pos) { - break - } - - // Consume the line break. - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - // [Go] Should really be returning breaks instead. - *breaks = read_line(parser, *breaks) - *end_mark = parser.mark - } - - // Determine the indentation level if needed. - if *indent == 0 { - *indent = max_indent - if *indent < parser.indent+1 { - *indent = parser.indent + 1 - } - if *indent < 1 { - *indent = 1 - } - } - return true -} - -// Scan a quoted scalar. -func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool { - // Eat the left quote. - start_mark := parser.mark - skip(parser) - - // Consume the content of the quoted scalar. - var s, leading_break, trailing_breaks, whitespaces []byte - for { - // Check that there are no document indicators at the beginning of the line. - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - - if parser.mark.column == 0 && - ((parser.buffer[parser.buffer_pos+0] == '-' && - parser.buffer[parser.buffer_pos+1] == '-' && - parser.buffer[parser.buffer_pos+2] == '-') || - (parser.buffer[parser.buffer_pos+0] == '.' && - parser.buffer[parser.buffer_pos+1] == '.' && - parser.buffer[parser.buffer_pos+2] == '.')) && - is_blankz(parser.buffer, parser.buffer_pos+3) { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected document indicator") - return false - } - - // Check for EOF. - if is_z(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", - start_mark, "found unexpected end of stream") - return false - } - - // Consume non-blank characters. - leading_blanks := false - for !is_blankz(parser.buffer, parser.buffer_pos) { - if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' { - // Is is an escaped single quote. - s = append(s, '\'') - skip(parser) - skip(parser) - - } else if single && parser.buffer[parser.buffer_pos] == '\'' { - // It is a right single quote. - break - } else if !single && parser.buffer[parser.buffer_pos] == '"' { - // It is a right double quote. - break - - } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) { - // It is an escaped line break. - if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { - return false - } - skip(parser) - skip_line(parser) - leading_blanks = true - break - - } else if !single && parser.buffer[parser.buffer_pos] == '\\' { - // It is an escape sequence. - code_length := 0 - - // Check the escape character. - switch parser.buffer[parser.buffer_pos+1] { - case '0': - s = append(s, 0) - case 'a': - s = append(s, '\x07') - case 'b': - s = append(s, '\x08') - case 't', '\t': - s = append(s, '\x09') - case 'n': - s = append(s, '\x0A') - case 'v': - s = append(s, '\x0B') - case 'f': - s = append(s, '\x0C') - case 'r': - s = append(s, '\x0D') - case 'e': - s = append(s, '\x1B') - case ' ': - s = append(s, '\x20') - case '"': - s = append(s, '"') - case '\'': - s = append(s, '\'') - case '\\': - s = append(s, '\\') - case 'N': // NEL (#x85) - s = append(s, '\xC2') - s = append(s, '\x85') - case '_': // #xA0 - s = append(s, '\xC2') - s = append(s, '\xA0') - case 'L': // LS (#x2028) - s = append(s, '\xE2') - s = append(s, '\x80') - s = append(s, '\xA8') - case 'P': // PS (#x2029) - s = append(s, '\xE2') - s = append(s, '\x80') - s = append(s, '\xA9') - case 'x': - code_length = 2 - case 'u': - code_length = 4 - case 'U': - code_length = 8 - default: - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found unknown escape character") - return false - } - - skip(parser) - skip(parser) - - // Consume an arbitrary escape code. - if code_length > 0 { - var value int - - // Scan the character value. - if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) { - return false - } - for k := 0; k < code_length; k++ { - if !is_hex(parser.buffer, parser.buffer_pos+k) { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "did not find expected hexdecimal number") - return false - } - value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k) - } - - // Check the value and write the character. - if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF { - yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", - start_mark, "found invalid Unicode character escape code") - return false - } - if value <= 0x7F { - s = append(s, byte(value)) - } else if value <= 0x7FF { - s = append(s, byte(0xC0+(value>>6))) - s = append(s, byte(0x80+(value&0x3F))) - } else if value <= 0xFFFF { - s = append(s, byte(0xE0+(value>>12))) - s = append(s, byte(0x80+((value>>6)&0x3F))) - s = append(s, byte(0x80+(value&0x3F))) - } else { - s = append(s, byte(0xF0+(value>>18))) - s = append(s, byte(0x80+((value>>12)&0x3F))) - s = append(s, byte(0x80+((value>>6)&0x3F))) - s = append(s, byte(0x80+(value&0x3F))) - } - - // Advance the pointer. - for k := 0; k < code_length; k++ { - skip(parser) - } - } - } else { - // It is a non-escaped non-blank character. - s = read(parser, s) - } - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - } - - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - // Check if we are at the end of the scalar. - if single { - if parser.buffer[parser.buffer_pos] == '\'' { - break - } - } else { - if parser.buffer[parser.buffer_pos] == '"' { - break - } - } - - // Consume blank characters. - for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { - if is_blank(parser.buffer, parser.buffer_pos) { - // Consume a space or a tab character. - if !leading_blanks { - whitespaces = read(parser, whitespaces) - } else { - skip(parser) - } - } else { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - // Check if it is a first line break. - if !leading_blanks { - whitespaces = whitespaces[:0] - leading_break = read_line(parser, leading_break) - leading_blanks = true - } else { - trailing_breaks = read_line(parser, trailing_breaks) - } - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Join the whitespaces or fold line breaks. - if leading_blanks { - // Do we need to fold line breaks? - if len(leading_break) > 0 && leading_break[0] == '\n' { - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } else { - s = append(s, trailing_breaks...) - } - } else { - s = append(s, leading_break...) - s = append(s, trailing_breaks...) - } - trailing_breaks = trailing_breaks[:0] - leading_break = leading_break[:0] - } else { - s = append(s, whitespaces...) - whitespaces = whitespaces[:0] - } - } - - // Eat the right quote. - skip(parser) - end_mark := parser.mark - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_SINGLE_QUOTED_SCALAR_STYLE, - } - if !single { - token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE - } - return true -} - -// Scan a plain scalar. -func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool { - - var s, leading_break, trailing_breaks, whitespaces []byte - var leading_blanks bool - var indent = parser.indent + 1 - - start_mark := parser.mark - end_mark := parser.mark - - // Consume the content of the plain scalar. - for { - // Check for a document indicator. - if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { - return false - } - if parser.mark.column == 0 && - ((parser.buffer[parser.buffer_pos+0] == '-' && - parser.buffer[parser.buffer_pos+1] == '-' && - parser.buffer[parser.buffer_pos+2] == '-') || - (parser.buffer[parser.buffer_pos+0] == '.' && - parser.buffer[parser.buffer_pos+1] == '.' && - parser.buffer[parser.buffer_pos+2] == '.')) && - is_blankz(parser.buffer, parser.buffer_pos+3) { - break - } - - // Check for a comment. - if parser.buffer[parser.buffer_pos] == '#' { - break - } - - // Consume non-blank characters. - for !is_blankz(parser.buffer, parser.buffer_pos) { - - // Check for indicators that may end a plain scalar. - if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) || - (parser.flow_level > 0 && - (parser.buffer[parser.buffer_pos] == ',' || - parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' || - parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || - parser.buffer[parser.buffer_pos] == '}')) { - break - } - - // Check if we need to join whitespaces and breaks. - if leading_blanks || len(whitespaces) > 0 { - if leading_blanks { - // Do we need to fold line breaks? - if leading_break[0] == '\n' { - if len(trailing_breaks) == 0 { - s = append(s, ' ') - } else { - s = append(s, trailing_breaks...) - } - } else { - s = append(s, leading_break...) - s = append(s, trailing_breaks...) - } - trailing_breaks = trailing_breaks[:0] - leading_break = leading_break[:0] - leading_blanks = false - } else { - s = append(s, whitespaces...) - whitespaces = whitespaces[:0] - } - } - - // Copy the character. - s = read(parser, s) - - end_mark = parser.mark - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - } - - // Is it the end? - if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) { - break - } - - // Consume blank characters. - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - - for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { - if is_blank(parser.buffer, parser.buffer_pos) { - - // Check for tab characters that abuse indentation. - if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) { - yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", - start_mark, "found a tab character that violates indentation") - return false - } - - // Consume a space or a tab character. - if !leading_blanks { - whitespaces = read(parser, whitespaces) - } else { - skip(parser) - } - } else { - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - - // Check if it is a first line break. - if !leading_blanks { - whitespaces = whitespaces[:0] - leading_break = read_line(parser, leading_break) - leading_blanks = true - } else { - trailing_breaks = read_line(parser, trailing_breaks) - } - } - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - } - - // Check indentation level. - if parser.flow_level == 0 && parser.mark.column < indent { - break - } - } - - // Create a token. - *token = yaml_token_t{ - typ: yaml_SCALAR_TOKEN, - start_mark: start_mark, - end_mark: end_mark, - value: s, - style: yaml_PLAIN_SCALAR_STYLE, - } - - // Note that we change the 'simple_key_allowed' flag. - if leading_blanks { - parser.simple_key_allowed = true - } - return true -} - -func yaml_parser_scan_line_comment(parser *yaml_parser_t, token_mark yaml_mark_t) bool { - if parser.newlines > 0 { - return true - } - - var start_mark yaml_mark_t - var text []byte - - for peek := 0; peek < 512; peek++ { - if parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) { - break - } - if is_blank(parser.buffer, parser.buffer_pos+peek) { - continue - } - if parser.buffer[parser.buffer_pos+peek] == '#' { - seen := parser.mark.index+peek - for { - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if is_breakz(parser.buffer, parser.buffer_pos) { - if parser.mark.index >= seen { - break - } - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } else if parser.mark.index >= seen { - if len(text) == 0 { - start_mark = parser.mark - } - text = read(parser, text) - } else { - skip(parser) - } - } - } - break - } - if len(text) > 0 { - parser.comments = append(parser.comments, yaml_comment_t{ - token_mark: token_mark, - start_mark: start_mark, - line: text, - }) - } - return true -} - -func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) bool { - token := parser.tokens[len(parser.tokens)-1] - - if token.typ == yaml_FLOW_ENTRY_TOKEN && len(parser.tokens) > 1 { - token = parser.tokens[len(parser.tokens)-2] - } - - var token_mark = token.start_mark - var start_mark yaml_mark_t - var next_indent = parser.indent - if next_indent < 0 { - next_indent = 0 - } - - var recent_empty = false - var first_empty = parser.newlines <= 1 - - var line = parser.mark.line - var column = parser.mark.column - - var text []byte - - // The foot line is the place where a comment must start to - // still be considered as a foot of the prior content. - // If there's some content in the currently parsed line, then - // the foot is the line below it. - var foot_line = -1 - if scan_mark.line > 0 { - foot_line = parser.mark.line-parser.newlines+1 - if parser.newlines == 0 && parser.mark.column > 1 { - foot_line++ - } - } - - var peek = 0 - for ; peek < 512; peek++ { - if parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) { - break - } - column++ - if is_blank(parser.buffer, parser.buffer_pos+peek) { - continue - } - c := parser.buffer[parser.buffer_pos+peek] - var close_flow = parser.flow_level > 0 && (c == ']' || c == '}') - if close_flow || is_breakz(parser.buffer, parser.buffer_pos+peek) { - // Got line break or terminator. - if close_flow || !recent_empty { - if close_flow || first_empty && (start_mark.line == foot_line && token.typ != yaml_VALUE_TOKEN || start_mark.column-1 < next_indent) { - // This is the first empty line and there were no empty lines before, - // so this initial part of the comment is a foot of the prior token - // instead of being a head for the following one. Split it up. - // Alternatively, this might also be the last comment inside a flow - // scope, so it must be a footer. - if len(text) > 0 { - if start_mark.column-1 < next_indent { - // If dedented it's unrelated to the prior token. - token_mark = start_mark - } - parser.comments = append(parser.comments, yaml_comment_t{ - scan_mark: scan_mark, - token_mark: token_mark, - start_mark: start_mark, - end_mark: yaml_mark_t{parser.mark.index + peek, line, column}, - foot: text, - }) - scan_mark = yaml_mark_t{parser.mark.index + peek, line, column} - token_mark = scan_mark - text = nil - } - } else { - if len(text) > 0 && parser.buffer[parser.buffer_pos+peek] != 0 { - text = append(text, '\n') - } - } - } - if !is_break(parser.buffer, parser.buffer_pos+peek) { - break - } - first_empty = false - recent_empty = true - column = 0 - line++ - continue - } - - if len(text) > 0 && (close_flow || column-1 < next_indent && column != start_mark.column) { - // The comment at the different indentation is a foot of the - // preceding data rather than a head of the upcoming one. - parser.comments = append(parser.comments, yaml_comment_t{ - scan_mark: scan_mark, - token_mark: token_mark, - start_mark: start_mark, - end_mark: yaml_mark_t{parser.mark.index + peek, line, column}, - foot: text, - }) - scan_mark = yaml_mark_t{parser.mark.index + peek, line, column} - token_mark = scan_mark - text = nil - } - - if parser.buffer[parser.buffer_pos+peek] != '#' { - break - } - - if len(text) == 0 { - start_mark = yaml_mark_t{parser.mark.index + peek, line, column} - } else { - text = append(text, '\n') - } - - recent_empty = false - - // Consume until after the consumed comment line. - seen := parser.mark.index+peek - for { - if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { - return false - } - if is_breakz(parser.buffer, parser.buffer_pos) { - if parser.mark.index >= seen { - break - } - if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { - return false - } - skip_line(parser) - } else if parser.mark.index >= seen { - text = read(parser, text) - } else { - skip(parser) - } - } - - peek = 0 - column = 0 - line = parser.mark.line - next_indent = parser.indent - if next_indent < 0 { - next_indent = 0 - } - } - - if len(text) > 0 { - parser.comments = append(parser.comments, yaml_comment_t{ - scan_mark: scan_mark, - token_mark: start_mark, - start_mark: start_mark, - end_mark: yaml_mark_t{parser.mark.index + peek - 1, line, column}, - head: text, - }) - } - return true -} diff --git a/vendor/gopkg.in/yaml.v3/sorter.go b/vendor/gopkg.in/yaml.v3/sorter.go deleted file mode 100644 index 9210ece7..00000000 --- a/vendor/gopkg.in/yaml.v3/sorter.go +++ /dev/null @@ -1,134 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package yaml - -import ( - "reflect" - "unicode" -) - -type keyList []reflect.Value - -func (l keyList) Len() int { return len(l) } -func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } -func (l keyList) Less(i, j int) bool { - a := l[i] - b := l[j] - ak := a.Kind() - bk := b.Kind() - for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { - a = a.Elem() - ak = a.Kind() - } - for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { - b = b.Elem() - bk = b.Kind() - } - af, aok := keyFloat(a) - bf, bok := keyFloat(b) - if aok && bok { - if af != bf { - return af < bf - } - if ak != bk { - return ak < bk - } - return numLess(a, b) - } - if ak != reflect.String || bk != reflect.String { - return ak < bk - } - ar, br := []rune(a.String()), []rune(b.String()) - digits := false - for i := 0; i < len(ar) && i < len(br); i++ { - if ar[i] == br[i] { - digits = unicode.IsDigit(ar[i]) - continue - } - al := unicode.IsLetter(ar[i]) - bl := unicode.IsLetter(br[i]) - if al && bl { - return ar[i] < br[i] - } - if al || bl { - if digits { - return al - } else { - return bl - } - } - var ai, bi int - var an, bn int64 - if ar[i] == '0' || br[i] == '0' { - for j := i - 1; j >= 0 && unicode.IsDigit(ar[j]); j-- { - if ar[j] != '0' { - an = 1 - bn = 1 - break - } - } - } - for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { - an = an*10 + int64(ar[ai]-'0') - } - for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { - bn = bn*10 + int64(br[bi]-'0') - } - if an != bn { - return an < bn - } - if ai != bi { - return ai < bi - } - return ar[i] < br[i] - } - return len(ar) < len(br) -} - -// keyFloat returns a float value for v if it is a number/bool -// and whether it is a number/bool or not. -func keyFloat(v reflect.Value) (f float64, ok bool) { - switch v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return float64(v.Int()), true - case reflect.Float32, reflect.Float64: - return v.Float(), true - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return float64(v.Uint()), true - case reflect.Bool: - if v.Bool() { - return 1, true - } - return 0, true - } - return 0, false -} - -// numLess returns whether a < b. -// a and b must necessarily have the same kind. -func numLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return a.Int() < b.Int() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Bool: - return !a.Bool() && b.Bool() - } - panic("not a number") -} diff --git a/vendor/gopkg.in/yaml.v3/writerc.go b/vendor/gopkg.in/yaml.v3/writerc.go deleted file mode 100644 index b8a116bf..00000000 --- a/vendor/gopkg.in/yaml.v3/writerc.go +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -// Set the writer error and return false. -func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { - emitter.error = yaml_WRITER_ERROR - emitter.problem = problem - return false -} - -// Flush the output buffer. -func yaml_emitter_flush(emitter *yaml_emitter_t) bool { - if emitter.write_handler == nil { - panic("write handler not set") - } - - // Check if the buffer is empty. - if emitter.buffer_pos == 0 { - return true - } - - if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { - return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) - } - emitter.buffer_pos = 0 - return true -} diff --git a/vendor/gopkg.in/yaml.v3/yaml.go b/vendor/gopkg.in/yaml.v3/yaml.go deleted file mode 100644 index 8cec6da4..00000000 --- a/vendor/gopkg.in/yaml.v3/yaml.go +++ /dev/null @@ -1,698 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package yaml implements YAML support for the Go language. -// -// Source code and other details for the project are available at GitHub: -// -// https://github.com/go-yaml/yaml -// -package yaml - -import ( - "errors" - "fmt" - "io" - "reflect" - "strings" - "sync" - "unicode/utf8" -) - -// The Unmarshaler interface may be implemented by types to customize their -// behavior when being unmarshaled from a YAML document. -type Unmarshaler interface { - UnmarshalYAML(value *Node) error -} - -type obsoleteUnmarshaler interface { - UnmarshalYAML(unmarshal func(interface{}) error) error -} - -// The Marshaler interface may be implemented by types to customize their -// behavior when being marshaled into a YAML document. The returned value -// is marshaled in place of the original value implementing Marshaler. -// -// If an error is returned by MarshalYAML, the marshaling procedure stops -// and returns with the provided error. -type Marshaler interface { - MarshalYAML() (interface{}, error) -} - -// Unmarshal decodes the first document found within the in byte slice -// and assigns decoded values into the out value. -// -// Maps and pointers (to a struct, string, int, etc) are accepted as out -// values. If an internal pointer within a struct is not initialized, -// the yaml package will initialize it if necessary for unmarshalling -// the provided data. The out parameter must not be nil. -// -// The type of the decoded values should be compatible with the respective -// values in out. If one or more values cannot be decoded due to a type -// mismatches, decoding continues partially until the end of the YAML -// content, and a *yaml.TypeError is returned with details for all -// missed values. -// -// Struct fields are only unmarshalled if they are exported (have an -// upper case first letter), and are unmarshalled using the field name -// lowercased as the default key. Custom keys may be defined via the -// "yaml" name in the field tag: the content preceding the first comma -// is used as the key, and the following comma-separated options are -// used to tweak the marshalling process (see Marshal). -// Conflicting names result in a runtime error. -// -// For example: -// -// type T struct { -// F int `yaml:"a,omitempty"` -// B int -// } -// var t T -// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t) -// -// See the documentation of Marshal for the format of tags and a list of -// supported tag options. -// -func Unmarshal(in []byte, out interface{}) (err error) { - return unmarshal(in, out, false) -} - -// A Decoder reads and decodes YAML values from an input stream. -type Decoder struct { - parser *parser - knownFields bool -} - -// NewDecoder returns a new decoder that reads from r. -// -// The decoder introduces its own buffering and may read -// data from r beyond the YAML values requested. -func NewDecoder(r io.Reader) *Decoder { - return &Decoder{ - parser: newParserFromReader(r), - } -} - -// KnownFields ensures that the keys in decoded mappings to -// exist as fields in the struct being decoded into. -func (dec *Decoder) KnownFields(enable bool) { - dec.knownFields = enable -} - -// Decode reads the next YAML-encoded value from its input -// and stores it in the value pointed to by v. -// -// See the documentation for Unmarshal for details about the -// conversion of YAML into a Go value. -func (dec *Decoder) Decode(v interface{}) (err error) { - d := newDecoder() - d.knownFields = dec.knownFields - defer handleErr(&err) - node := dec.parser.parse() - if node == nil { - return io.EOF - } - out := reflect.ValueOf(v) - if out.Kind() == reflect.Ptr && !out.IsNil() { - out = out.Elem() - } - d.unmarshal(node, out) - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -// Decode decodes the node and stores its data into the value pointed to by v. -// -// See the documentation for Unmarshal for details about the -// conversion of YAML into a Go value. -func (n *Node) Decode(v interface{}) (err error) { - d := newDecoder() - defer handleErr(&err) - out := reflect.ValueOf(v) - if out.Kind() == reflect.Ptr && !out.IsNil() { - out = out.Elem() - } - d.unmarshal(n, out) - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -func unmarshal(in []byte, out interface{}, strict bool) (err error) { - defer handleErr(&err) - d := newDecoder() - p := newParser(in) - defer p.destroy() - node := p.parse() - if node != nil { - v := reflect.ValueOf(out) - if v.Kind() == reflect.Ptr && !v.IsNil() { - v = v.Elem() - } - d.unmarshal(node, v) - } - if len(d.terrors) > 0 { - return &TypeError{d.terrors} - } - return nil -} - -// Marshal serializes the value provided into a YAML document. The structure -// of the generated document will reflect the structure of the value itself. -// Maps and pointers (to struct, string, int, etc) are accepted as the in value. -// -// Struct fields are only marshalled if they are exported (have an upper case -// first letter), and are marshalled using the field name lowercased as the -// default key. Custom keys may be defined via the "yaml" name in the field -// tag: the content preceding the first comma is used as the key, and the -// following comma-separated options are used to tweak the marshalling process. -// Conflicting names result in a runtime error. -// -// The field tag format accepted is: -// -// `(...) yaml:"[][,[,]]" (...)` -// -// The following flags are currently supported: -// -// omitempty Only include the field if it's not set to the zero -// value for the type or to empty slices or maps. -// Zero valued structs will be omitted if all their public -// fields are zero, unless they implement an IsZero -// method (see the IsZeroer interface type), in which -// case the field will be excluded if IsZero returns true. -// -// flow Marshal using a flow style (useful for structs, -// sequences and maps). -// -// inline Inline the field, which must be a struct or a map, -// causing all of its fields or keys to be processed as if -// they were part of the outer struct. For maps, keys must -// not conflict with the yaml keys of other struct fields. -// -// In addition, if the key is "-", the field is ignored. -// -// For example: -// -// type T struct { -// F int `yaml:"a,omitempty"` -// B int -// } -// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n" -// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n" -// -func Marshal(in interface{}) (out []byte, err error) { - defer handleErr(&err) - e := newEncoder() - defer e.destroy() - e.marshalDoc("", reflect.ValueOf(in)) - e.finish() - out = e.out - return -} - -// An Encoder writes YAML values to an output stream. -type Encoder struct { - encoder *encoder -} - -// NewEncoder returns a new encoder that writes to w. -// The Encoder should be closed after use to flush all data -// to w. -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{ - encoder: newEncoderWithWriter(w), - } -} - -// Encode writes the YAML encoding of v to the stream. -// If multiple items are encoded to the stream, the -// second and subsequent document will be preceded -// with a "---" document separator, but the first will not. -// -// See the documentation for Marshal for details about the conversion of Go -// values to YAML. -func (e *Encoder) Encode(v interface{}) (err error) { - defer handleErr(&err) - e.encoder.marshalDoc("", reflect.ValueOf(v)) - return nil -} - -// Encode encodes value v and stores its representation in n. -// -// See the documentation for Marshal for details about the -// conversion of Go values into YAML. -func (n *Node) Encode(v interface{}) (err error) { - defer handleErr(&err) - e := newEncoder() - defer e.destroy() - e.marshalDoc("", reflect.ValueOf(v)) - e.finish() - p := newParser(e.out) - p.textless = true - defer p.destroy() - doc := p.parse() - *n = *doc.Content[0] - return nil -} - -// SetIndent changes the used indentation used when encoding. -func (e *Encoder) SetIndent(spaces int) { - if spaces < 0 { - panic("yaml: cannot indent to a negative number of spaces") - } - e.encoder.indent = spaces -} - -// Close closes the encoder by writing any remaining data. -// It does not write a stream terminating string "...". -func (e *Encoder) Close() (err error) { - defer handleErr(&err) - e.encoder.finish() - return nil -} - -func handleErr(err *error) { - if v := recover(); v != nil { - if e, ok := v.(yamlError); ok { - *err = e.err - } else { - panic(v) - } - } -} - -type yamlError struct { - err error -} - -func fail(err error) { - panic(yamlError{err}) -} - -func failf(format string, args ...interface{}) { - panic(yamlError{fmt.Errorf("yaml: "+format, args...)}) -} - -// A TypeError is returned by Unmarshal when one or more fields in -// the YAML document cannot be properly decoded into the requested -// types. When this error is returned, the value is still -// unmarshaled partially. -type TypeError struct { - Errors []string -} - -func (e *TypeError) Error() string { - return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n ")) -} - -type Kind uint32 - -const ( - DocumentNode Kind = 1 << iota - SequenceNode - MappingNode - ScalarNode - AliasNode -) - -type Style uint32 - -const ( - TaggedStyle Style = 1 << iota - DoubleQuotedStyle - SingleQuotedStyle - LiteralStyle - FoldedStyle - FlowStyle -) - -// Node represents an element in the YAML document hierarchy. While documents -// are typically encoded and decoded into higher level types, such as structs -// and maps, Node is an intermediate representation that allows detailed -// control over the content being decoded or encoded. -// -// It's worth noting that although Node offers access into details such as -// line numbers, colums, and comments, the content when re-encoded will not -// have its original textual representation preserved. An effort is made to -// render the data plesantly, and to preserve comments near the data they -// describe, though. -// -// Values that make use of the Node type interact with the yaml package in the -// same way any other type would do, by encoding and decoding yaml data -// directly or indirectly into them. -// -// For example: -// -// var person struct { -// Name string -// Address yaml.Node -// } -// err := yaml.Unmarshal(data, &person) -// -// Or by itself: -// -// var person Node -// err := yaml.Unmarshal(data, &person) -// -type Node struct { - // Kind defines whether the node is a document, a mapping, a sequence, - // a scalar value, or an alias to another node. The specific data type of - // scalar nodes may be obtained via the ShortTag and LongTag methods. - Kind Kind - - // Style allows customizing the apperance of the node in the tree. - Style Style - - // Tag holds the YAML tag defining the data type for the value. - // When decoding, this field will always be set to the resolved tag, - // even when it wasn't explicitly provided in the YAML content. - // When encoding, if this field is unset the value type will be - // implied from the node properties, and if it is set, it will only - // be serialized into the representation if TaggedStyle is used or - // the implicit tag diverges from the provided one. - Tag string - - // Value holds the unescaped and unquoted represenation of the value. - Value string - - // Anchor holds the anchor name for this node, which allows aliases to point to it. - Anchor string - - // Alias holds the node that this alias points to. Only valid when Kind is AliasNode. - Alias *Node - - // Content holds contained nodes for documents, mappings, and sequences. - Content []*Node - - // HeadComment holds any comments in the lines preceding the node and - // not separated by an empty line. - HeadComment string - - // LineComment holds any comments at the end of the line where the node is in. - LineComment string - - // FootComment holds any comments following the node and before empty lines. - FootComment string - - // Line and Column hold the node position in the decoded YAML text. - // These fields are not respected when encoding the node. - Line int - Column int -} - -// IsZero returns whether the node has all of its fields unset. -func (n *Node) IsZero() bool { - return n.Kind == 0 && n.Style == 0 && n.Tag == "" && n.Value == "" && n.Anchor == "" && n.Alias == nil && n.Content == nil && - n.HeadComment == "" && n.LineComment == "" && n.FootComment == "" && n.Line == 0 && n.Column == 0 -} - - -// LongTag returns the long form of the tag that indicates the data type for -// the node. If the Tag field isn't explicitly defined, one will be computed -// based on the node properties. -func (n *Node) LongTag() string { - return longTag(n.ShortTag()) -} - -// ShortTag returns the short form of the YAML tag that indicates data type for -// the node. If the Tag field isn't explicitly defined, one will be computed -// based on the node properties. -func (n *Node) ShortTag() string { - if n.indicatedString() { - return strTag - } - if n.Tag == "" || n.Tag == "!" { - switch n.Kind { - case MappingNode: - return mapTag - case SequenceNode: - return seqTag - case AliasNode: - if n.Alias != nil { - return n.Alias.ShortTag() - } - case ScalarNode: - tag, _ := resolve("", n.Value) - return tag - case 0: - // Special case to make the zero value convenient. - if n.IsZero() { - return nullTag - } - } - return "" - } - return shortTag(n.Tag) -} - -func (n *Node) indicatedString() bool { - return n.Kind == ScalarNode && - (shortTag(n.Tag) == strTag || - (n.Tag == "" || n.Tag == "!") && n.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0) -} - -// SetString is a convenience function that sets the node to a string value -// and defines its style in a pleasant way depending on its content. -func (n *Node) SetString(s string) { - n.Kind = ScalarNode - if utf8.ValidString(s) { - n.Value = s - n.Tag = strTag - } else { - n.Value = encodeBase64(s) - n.Tag = binaryTag - } - if strings.Contains(n.Value, "\n") { - n.Style = LiteralStyle - } -} - -// -------------------------------------------------------------------------- -// Maintain a mapping of keys to structure field indexes - -// The code in this section was copied from mgo/bson. - -// structInfo holds details for the serialization of fields of -// a given struct. -type structInfo struct { - FieldsMap map[string]fieldInfo - FieldsList []fieldInfo - - // InlineMap is the number of the field in the struct that - // contains an ,inline map, or -1 if there's none. - InlineMap int - - // InlineUnmarshalers holds indexes to inlined fields that - // contain unmarshaler values. - InlineUnmarshalers [][]int -} - -type fieldInfo struct { - Key string - Num int - OmitEmpty bool - Flow bool - // Id holds the unique field identifier, so we can cheaply - // check for field duplicates without maintaining an extra map. - Id int - - // Inline holds the field index if the field is part of an inlined struct. - Inline []int -} - -var structMap = make(map[reflect.Type]*structInfo) -var fieldMapMutex sync.RWMutex -var unmarshalerType reflect.Type - -func init() { - var v Unmarshaler - unmarshalerType = reflect.ValueOf(&v).Elem().Type() -} - -func getStructInfo(st reflect.Type) (*structInfo, error) { - fieldMapMutex.RLock() - sinfo, found := structMap[st] - fieldMapMutex.RUnlock() - if found { - return sinfo, nil - } - - n := st.NumField() - fieldsMap := make(map[string]fieldInfo) - fieldsList := make([]fieldInfo, 0, n) - inlineMap := -1 - inlineUnmarshalers := [][]int(nil) - for i := 0; i != n; i++ { - field := st.Field(i) - if field.PkgPath != "" && !field.Anonymous { - continue // Private field - } - - info := fieldInfo{Num: i} - - tag := field.Tag.Get("yaml") - if tag == "" && strings.Index(string(field.Tag), ":") < 0 { - tag = string(field.Tag) - } - if tag == "-" { - continue - } - - inline := false - fields := strings.Split(tag, ",") - if len(fields) > 1 { - for _, flag := range fields[1:] { - switch flag { - case "omitempty": - info.OmitEmpty = true - case "flow": - info.Flow = true - case "inline": - inline = true - default: - return nil, errors.New(fmt.Sprintf("unsupported flag %q in tag %q of type %s", flag, tag, st)) - } - } - tag = fields[0] - } - - if inline { - switch field.Type.Kind() { - case reflect.Map: - if inlineMap >= 0 { - return nil, errors.New("multiple ,inline maps in struct " + st.String()) - } - if field.Type.Key() != reflect.TypeOf("") { - return nil, errors.New("option ,inline needs a map with string keys in struct " + st.String()) - } - inlineMap = info.Num - case reflect.Struct, reflect.Ptr: - ftype := field.Type - for ftype.Kind() == reflect.Ptr { - ftype = ftype.Elem() - } - if ftype.Kind() != reflect.Struct { - return nil, errors.New("option ,inline may only be used on a struct or map field") - } - if reflect.PtrTo(ftype).Implements(unmarshalerType) { - inlineUnmarshalers = append(inlineUnmarshalers, []int{i}) - } else { - sinfo, err := getStructInfo(ftype) - if err != nil { - return nil, err - } - for _, index := range sinfo.InlineUnmarshalers { - inlineUnmarshalers = append(inlineUnmarshalers, append([]int{i}, index...)) - } - for _, finfo := range sinfo.FieldsList { - if _, found := fieldsMap[finfo.Key]; found { - msg := "duplicated key '" + finfo.Key + "' in struct " + st.String() - return nil, errors.New(msg) - } - if finfo.Inline == nil { - finfo.Inline = []int{i, finfo.Num} - } else { - finfo.Inline = append([]int{i}, finfo.Inline...) - } - finfo.Id = len(fieldsList) - fieldsMap[finfo.Key] = finfo - fieldsList = append(fieldsList, finfo) - } - } - default: - return nil, errors.New("option ,inline may only be used on a struct or map field") - } - continue - } - - if tag != "" { - info.Key = tag - } else { - info.Key = strings.ToLower(field.Name) - } - - if _, found = fieldsMap[info.Key]; found { - msg := "duplicated key '" + info.Key + "' in struct " + st.String() - return nil, errors.New(msg) - } - - info.Id = len(fieldsList) - fieldsList = append(fieldsList, info) - fieldsMap[info.Key] = info - } - - sinfo = &structInfo{ - FieldsMap: fieldsMap, - FieldsList: fieldsList, - InlineMap: inlineMap, - InlineUnmarshalers: inlineUnmarshalers, - } - - fieldMapMutex.Lock() - structMap[st] = sinfo - fieldMapMutex.Unlock() - return sinfo, nil -} - -// IsZeroer is used to check whether an object is zero to -// determine whether it should be omitted when marshaling -// with the omitempty flag. One notable implementation -// is time.Time. -type IsZeroer interface { - IsZero() bool -} - -func isZero(v reflect.Value) bool { - kind := v.Kind() - if z, ok := v.Interface().(IsZeroer); ok { - if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() { - return true - } - return z.IsZero() - } - switch kind { - case reflect.String: - return len(v.String()) == 0 - case reflect.Interface, reflect.Ptr: - return v.IsNil() - case reflect.Slice: - return v.Len() == 0 - case reflect.Map: - return v.Len() == 0 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Bool: - return !v.Bool() - case reflect.Struct: - vt := v.Type() - for i := v.NumField() - 1; i >= 0; i-- { - if vt.Field(i).PkgPath != "" { - continue // Private field - } - if !isZero(v.Field(i)) { - return false - } - } - return true - } - return false -} diff --git a/vendor/gopkg.in/yaml.v3/yamlh.go b/vendor/gopkg.in/yaml.v3/yamlh.go deleted file mode 100644 index 7c6d0077..00000000 --- a/vendor/gopkg.in/yaml.v3/yamlh.go +++ /dev/null @@ -1,807 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -import ( - "fmt" - "io" -) - -// The version directive data. -type yaml_version_directive_t struct { - major int8 // The major version number. - minor int8 // The minor version number. -} - -// The tag directive data. -type yaml_tag_directive_t struct { - handle []byte // The tag handle. - prefix []byte // The tag prefix. -} - -type yaml_encoding_t int - -// The stream encoding. -const ( - // Let the parser choose the encoding. - yaml_ANY_ENCODING yaml_encoding_t = iota - - yaml_UTF8_ENCODING // The default UTF-8 encoding. - yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM. - yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM. -) - -type yaml_break_t int - -// Line break types. -const ( - // Let the parser choose the break type. - yaml_ANY_BREAK yaml_break_t = iota - - yaml_CR_BREAK // Use CR for line breaks (Mac style). - yaml_LN_BREAK // Use LN for line breaks (Unix style). - yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style). -) - -type yaml_error_type_t int - -// Many bad things could happen with the parser and emitter. -const ( - // No error is produced. - yaml_NO_ERROR yaml_error_type_t = iota - - yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory. - yaml_READER_ERROR // Cannot read or decode the input stream. - yaml_SCANNER_ERROR // Cannot scan the input stream. - yaml_PARSER_ERROR // Cannot parse the input stream. - yaml_COMPOSER_ERROR // Cannot compose a YAML document. - yaml_WRITER_ERROR // Cannot write to the output stream. - yaml_EMITTER_ERROR // Cannot emit a YAML stream. -) - -// The pointer position. -type yaml_mark_t struct { - index int // The position index. - line int // The position line. - column int // The position column. -} - -// Node Styles - -type yaml_style_t int8 - -type yaml_scalar_style_t yaml_style_t - -// Scalar styles. -const ( - // Let the emitter choose the style. - yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = 0 - - yaml_PLAIN_SCALAR_STYLE yaml_scalar_style_t = 1 << iota // The plain scalar style. - yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style. - yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style. - yaml_LITERAL_SCALAR_STYLE // The literal scalar style. - yaml_FOLDED_SCALAR_STYLE // The folded scalar style. -) - -type yaml_sequence_style_t yaml_style_t - -// Sequence styles. -const ( - // Let the emitter choose the style. - yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota - - yaml_BLOCK_SEQUENCE_STYLE // The block sequence style. - yaml_FLOW_SEQUENCE_STYLE // The flow sequence style. -) - -type yaml_mapping_style_t yaml_style_t - -// Mapping styles. -const ( - // Let the emitter choose the style. - yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota - - yaml_BLOCK_MAPPING_STYLE // The block mapping style. - yaml_FLOW_MAPPING_STYLE // The flow mapping style. -) - -// Tokens - -type yaml_token_type_t int - -// Token types. -const ( - // An empty token. - yaml_NO_TOKEN yaml_token_type_t = iota - - yaml_STREAM_START_TOKEN // A STREAM-START token. - yaml_STREAM_END_TOKEN // A STREAM-END token. - - yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token. - yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token. - yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token. - yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token. - - yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token. - yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token. - yaml_BLOCK_END_TOKEN // A BLOCK-END token. - - yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token. - yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token. - yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token. - yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token. - - yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token. - yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token. - yaml_KEY_TOKEN // A KEY token. - yaml_VALUE_TOKEN // A VALUE token. - - yaml_ALIAS_TOKEN // An ALIAS token. - yaml_ANCHOR_TOKEN // An ANCHOR token. - yaml_TAG_TOKEN // A TAG token. - yaml_SCALAR_TOKEN // A SCALAR token. -) - -func (tt yaml_token_type_t) String() string { - switch tt { - case yaml_NO_TOKEN: - return "yaml_NO_TOKEN" - case yaml_STREAM_START_TOKEN: - return "yaml_STREAM_START_TOKEN" - case yaml_STREAM_END_TOKEN: - return "yaml_STREAM_END_TOKEN" - case yaml_VERSION_DIRECTIVE_TOKEN: - return "yaml_VERSION_DIRECTIVE_TOKEN" - case yaml_TAG_DIRECTIVE_TOKEN: - return "yaml_TAG_DIRECTIVE_TOKEN" - case yaml_DOCUMENT_START_TOKEN: - return "yaml_DOCUMENT_START_TOKEN" - case yaml_DOCUMENT_END_TOKEN: - return "yaml_DOCUMENT_END_TOKEN" - case yaml_BLOCK_SEQUENCE_START_TOKEN: - return "yaml_BLOCK_SEQUENCE_START_TOKEN" - case yaml_BLOCK_MAPPING_START_TOKEN: - return "yaml_BLOCK_MAPPING_START_TOKEN" - case yaml_BLOCK_END_TOKEN: - return "yaml_BLOCK_END_TOKEN" - case yaml_FLOW_SEQUENCE_START_TOKEN: - return "yaml_FLOW_SEQUENCE_START_TOKEN" - case yaml_FLOW_SEQUENCE_END_TOKEN: - return "yaml_FLOW_SEQUENCE_END_TOKEN" - case yaml_FLOW_MAPPING_START_TOKEN: - return "yaml_FLOW_MAPPING_START_TOKEN" - case yaml_FLOW_MAPPING_END_TOKEN: - return "yaml_FLOW_MAPPING_END_TOKEN" - case yaml_BLOCK_ENTRY_TOKEN: - return "yaml_BLOCK_ENTRY_TOKEN" - case yaml_FLOW_ENTRY_TOKEN: - return "yaml_FLOW_ENTRY_TOKEN" - case yaml_KEY_TOKEN: - return "yaml_KEY_TOKEN" - case yaml_VALUE_TOKEN: - return "yaml_VALUE_TOKEN" - case yaml_ALIAS_TOKEN: - return "yaml_ALIAS_TOKEN" - case yaml_ANCHOR_TOKEN: - return "yaml_ANCHOR_TOKEN" - case yaml_TAG_TOKEN: - return "yaml_TAG_TOKEN" - case yaml_SCALAR_TOKEN: - return "yaml_SCALAR_TOKEN" - } - return "" -} - -// The token structure. -type yaml_token_t struct { - // The token type. - typ yaml_token_type_t - - // The start/end of the token. - start_mark, end_mark yaml_mark_t - - // The stream encoding (for yaml_STREAM_START_TOKEN). - encoding yaml_encoding_t - - // The alias/anchor/scalar value or tag/tag directive handle - // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN). - value []byte - - // The tag suffix (for yaml_TAG_TOKEN). - suffix []byte - - // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN). - prefix []byte - - // The scalar style (for yaml_SCALAR_TOKEN). - style yaml_scalar_style_t - - // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN). - major, minor int8 -} - -// Events - -type yaml_event_type_t int8 - -// Event types. -const ( - // An empty event. - yaml_NO_EVENT yaml_event_type_t = iota - - yaml_STREAM_START_EVENT // A STREAM-START event. - yaml_STREAM_END_EVENT // A STREAM-END event. - yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event. - yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event. - yaml_ALIAS_EVENT // An ALIAS event. - yaml_SCALAR_EVENT // A SCALAR event. - yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event. - yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event. - yaml_MAPPING_START_EVENT // A MAPPING-START event. - yaml_MAPPING_END_EVENT // A MAPPING-END event. - yaml_TAIL_COMMENT_EVENT -) - -var eventStrings = []string{ - yaml_NO_EVENT: "none", - yaml_STREAM_START_EVENT: "stream start", - yaml_STREAM_END_EVENT: "stream end", - yaml_DOCUMENT_START_EVENT: "document start", - yaml_DOCUMENT_END_EVENT: "document end", - yaml_ALIAS_EVENT: "alias", - yaml_SCALAR_EVENT: "scalar", - yaml_SEQUENCE_START_EVENT: "sequence start", - yaml_SEQUENCE_END_EVENT: "sequence end", - yaml_MAPPING_START_EVENT: "mapping start", - yaml_MAPPING_END_EVENT: "mapping end", - yaml_TAIL_COMMENT_EVENT: "tail comment", -} - -func (e yaml_event_type_t) String() string { - if e < 0 || int(e) >= len(eventStrings) { - return fmt.Sprintf("unknown event %d", e) - } - return eventStrings[e] -} - -// The event structure. -type yaml_event_t struct { - - // The event type. - typ yaml_event_type_t - - // The start and end of the event. - start_mark, end_mark yaml_mark_t - - // The document encoding (for yaml_STREAM_START_EVENT). - encoding yaml_encoding_t - - // The version directive (for yaml_DOCUMENT_START_EVENT). - version_directive *yaml_version_directive_t - - // The list of tag directives (for yaml_DOCUMENT_START_EVENT). - tag_directives []yaml_tag_directive_t - - // The comments - head_comment []byte - line_comment []byte - foot_comment []byte - tail_comment []byte - - // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT). - anchor []byte - - // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). - tag []byte - - // The scalar value (for yaml_SCALAR_EVENT). - value []byte - - // Is the document start/end indicator implicit, or the tag optional? - // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT). - implicit bool - - // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT). - quoted_implicit bool - - // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). - style yaml_style_t -} - -func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) } -func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) } -func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) } - -// Nodes - -const ( - yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null. - yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false. - yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values. - yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values. - yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values. - yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values. - - yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences. - yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping. - - // Not in original libyaml. - yaml_BINARY_TAG = "tag:yaml.org,2002:binary" - yaml_MERGE_TAG = "tag:yaml.org,2002:merge" - - yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str. - yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq. - yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map. -) - -type yaml_node_type_t int - -// Node types. -const ( - // An empty node. - yaml_NO_NODE yaml_node_type_t = iota - - yaml_SCALAR_NODE // A scalar node. - yaml_SEQUENCE_NODE // A sequence node. - yaml_MAPPING_NODE // A mapping node. -) - -// An element of a sequence node. -type yaml_node_item_t int - -// An element of a mapping node. -type yaml_node_pair_t struct { - key int // The key of the element. - value int // The value of the element. -} - -// The node structure. -type yaml_node_t struct { - typ yaml_node_type_t // The node type. - tag []byte // The node tag. - - // The node data. - - // The scalar parameters (for yaml_SCALAR_NODE). - scalar struct { - value []byte // The scalar value. - length int // The length of the scalar value. - style yaml_scalar_style_t // The scalar style. - } - - // The sequence parameters (for YAML_SEQUENCE_NODE). - sequence struct { - items_data []yaml_node_item_t // The stack of sequence items. - style yaml_sequence_style_t // The sequence style. - } - - // The mapping parameters (for yaml_MAPPING_NODE). - mapping struct { - pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value). - pairs_start *yaml_node_pair_t // The beginning of the stack. - pairs_end *yaml_node_pair_t // The end of the stack. - pairs_top *yaml_node_pair_t // The top of the stack. - style yaml_mapping_style_t // The mapping style. - } - - start_mark yaml_mark_t // The beginning of the node. - end_mark yaml_mark_t // The end of the node. - -} - -// The document structure. -type yaml_document_t struct { - - // The document nodes. - nodes []yaml_node_t - - // The version directive. - version_directive *yaml_version_directive_t - - // The list of tag directives. - tag_directives_data []yaml_tag_directive_t - tag_directives_start int // The beginning of the tag directives list. - tag_directives_end int // The end of the tag directives list. - - start_implicit int // Is the document start indicator implicit? - end_implicit int // Is the document end indicator implicit? - - // The start/end of the document. - start_mark, end_mark yaml_mark_t -} - -// The prototype of a read handler. -// -// The read handler is called when the parser needs to read more bytes from the -// source. The handler should write not more than size bytes to the buffer. -// The number of written bytes should be set to the size_read variable. -// -// [in,out] data A pointer to an application data specified by -// yaml_parser_set_input(). -// [out] buffer The buffer to write the data from the source. -// [in] size The size of the buffer. -// [out] size_read The actual number of bytes read from the source. -// -// On success, the handler should return 1. If the handler failed, -// the returned value should be 0. On EOF, the handler should set the -// size_read to 0 and return 1. -type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error) - -// This structure holds information about a potential simple key. -type yaml_simple_key_t struct { - possible bool // Is a simple key possible? - required bool // Is a simple key required? - token_number int // The number of the token. - mark yaml_mark_t // The position mark. -} - -// The states of the parser. -type yaml_parser_state_t int - -const ( - yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota - - yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document. - yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START. - yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document. - yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END. - yaml_PARSE_BLOCK_NODE_STATE // Expect a block node. - yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence. - yaml_PARSE_FLOW_NODE_STATE // Expect a flow node. - yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence. - yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence. - yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence. - yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. - yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key. - yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value. - yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping. - yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry. - yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. - yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. - yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. - yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping. - yaml_PARSE_END_STATE // Expect nothing. -) - -func (ps yaml_parser_state_t) String() string { - switch ps { - case yaml_PARSE_STREAM_START_STATE: - return "yaml_PARSE_STREAM_START_STATE" - case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE" - case yaml_PARSE_DOCUMENT_START_STATE: - return "yaml_PARSE_DOCUMENT_START_STATE" - case yaml_PARSE_DOCUMENT_CONTENT_STATE: - return "yaml_PARSE_DOCUMENT_CONTENT_STATE" - case yaml_PARSE_DOCUMENT_END_STATE: - return "yaml_PARSE_DOCUMENT_END_STATE" - case yaml_PARSE_BLOCK_NODE_STATE: - return "yaml_PARSE_BLOCK_NODE_STATE" - case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE" - case yaml_PARSE_FLOW_NODE_STATE: - return "yaml_PARSE_FLOW_NODE_STATE" - case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE" - case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE" - case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: - return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE" - case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: - return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE" - case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE" - case yaml_PARSE_FLOW_MAPPING_KEY_STATE: - return "yaml_PARSE_FLOW_MAPPING_KEY_STATE" - case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: - return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE" - case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE" - case yaml_PARSE_END_STATE: - return "yaml_PARSE_END_STATE" - } - return "" -} - -// This structure holds aliases data. -type yaml_alias_data_t struct { - anchor []byte // The anchor. - index int // The node id. - mark yaml_mark_t // The anchor mark. -} - -// The parser structure. -// -// All members are internal. Manage the structure using the -// yaml_parser_ family of functions. -type yaml_parser_t struct { - - // Error handling - - error yaml_error_type_t // Error type. - - problem string // Error description. - - // The byte about which the problem occurred. - problem_offset int - problem_value int - problem_mark yaml_mark_t - - // The error context. - context string - context_mark yaml_mark_t - - // Reader stuff - - read_handler yaml_read_handler_t // Read handler. - - input_reader io.Reader // File input data. - input []byte // String input data. - input_pos int - - eof bool // EOF flag - - buffer []byte // The working buffer. - buffer_pos int // The current position of the buffer. - - unread int // The number of unread characters in the buffer. - - newlines int // The number of line breaks since last non-break/non-blank character - - raw_buffer []byte // The raw buffer. - raw_buffer_pos int // The current position of the buffer. - - encoding yaml_encoding_t // The input encoding. - - offset int // The offset of the current position (in bytes). - mark yaml_mark_t // The mark of the current position. - - // Comments - - head_comment []byte // The current head comments - line_comment []byte // The current line comments - foot_comment []byte // The current foot comments - tail_comment []byte // Foot comment that happens at the end of a block. - stem_comment []byte // Comment in item preceding a nested structure (list inside list item, etc) - - comments []yaml_comment_t // The folded comments for all parsed tokens - comments_head int - - // Scanner stuff - - stream_start_produced bool // Have we started to scan the input stream? - stream_end_produced bool // Have we reached the end of the input stream? - - flow_level int // The number of unclosed '[' and '{' indicators. - - tokens []yaml_token_t // The tokens queue. - tokens_head int // The head of the tokens queue. - tokens_parsed int // The number of tokens fetched from the queue. - token_available bool // Does the tokens queue contain a token ready for dequeueing. - - indent int // The current indentation level. - indents []int // The indentation levels stack. - - simple_key_allowed bool // May a simple key occur at the current position? - simple_keys []yaml_simple_key_t // The stack of simple keys. - simple_keys_by_tok map[int]int // possible simple_key indexes indexed by token_number - - // Parser stuff - - state yaml_parser_state_t // The current parser state. - states []yaml_parser_state_t // The parser states stack. - marks []yaml_mark_t // The stack of marks. - tag_directives []yaml_tag_directive_t // The list of TAG directives. - - // Dumper stuff - - aliases []yaml_alias_data_t // The alias data. - - document *yaml_document_t // The currently parsed document. -} - -type yaml_comment_t struct { - - scan_mark yaml_mark_t // Position where scanning for comments started - token_mark yaml_mark_t // Position after which tokens will be associated with this comment - start_mark yaml_mark_t // Position of '#' comment mark - end_mark yaml_mark_t // Position where comment terminated - - head []byte - line []byte - foot []byte -} - -// Emitter Definitions - -// The prototype of a write handler. -// -// The write handler is called when the emitter needs to flush the accumulated -// characters to the output. The handler should write @a size bytes of the -// @a buffer to the output. -// -// @param[in,out] data A pointer to an application data specified by -// yaml_emitter_set_output(). -// @param[in] buffer The buffer with bytes to be written. -// @param[in] size The size of the buffer. -// -// @returns On success, the handler should return @c 1. If the handler failed, -// the returned value should be @c 0. -// -type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error - -type yaml_emitter_state_t int - -// The emitter states. -const ( - // Expect STREAM-START. - yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota - - yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END. - yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END. - yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document. - yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END. - yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence. - yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE // Expect the next item of a flow sequence, with the comma already written out - yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence. - yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE // Expect the next key of a flow mapping, with the comma already written out - yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping. - yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. - yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence. - yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence. - yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping. - yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping. - yaml_EMIT_END_STATE // Expect nothing. -) - -// The emitter structure. -// -// All members are internal. Manage the structure using the @c yaml_emitter_ -// family of functions. -type yaml_emitter_t struct { - - // Error handling - - error yaml_error_type_t // Error type. - problem string // Error description. - - // Writer stuff - - write_handler yaml_write_handler_t // Write handler. - - output_buffer *[]byte // String output data. - output_writer io.Writer // File output data. - - buffer []byte // The working buffer. - buffer_pos int // The current position of the buffer. - - raw_buffer []byte // The raw buffer. - raw_buffer_pos int // The current position of the buffer. - - encoding yaml_encoding_t // The stream encoding. - - // Emitter stuff - - canonical bool // If the output is in the canonical style? - best_indent int // The number of indentation spaces. - best_width int // The preferred width of the output lines. - unicode bool // Allow unescaped non-ASCII characters? - line_break yaml_break_t // The preferred line break. - - state yaml_emitter_state_t // The current emitter state. - states []yaml_emitter_state_t // The stack of states. - - events []yaml_event_t // The event queue. - events_head int // The head of the event queue. - - indents []int // The stack of indentation levels. - - tag_directives []yaml_tag_directive_t // The list of tag directives. - - indent int // The current indentation level. - - flow_level int // The current flow level. - - root_context bool // Is it the document root context? - sequence_context bool // Is it a sequence context? - mapping_context bool // Is it a mapping context? - simple_key_context bool // Is it a simple mapping key context? - - line int // The current line. - column int // The current column. - whitespace bool // If the last character was a whitespace? - indention bool // If the last character was an indentation character (' ', '-', '?', ':')? - open_ended bool // If an explicit document end is required? - - space_above bool // Is there's an empty line above? - foot_indent int // The indent used to write the foot comment above, or -1 if none. - - // Anchor analysis. - anchor_data struct { - anchor []byte // The anchor value. - alias bool // Is it an alias? - } - - // Tag analysis. - tag_data struct { - handle []byte // The tag handle. - suffix []byte // The tag suffix. - } - - // Scalar analysis. - scalar_data struct { - value []byte // The scalar value. - multiline bool // Does the scalar contain line breaks? - flow_plain_allowed bool // Can the scalar be expessed in the flow plain style? - block_plain_allowed bool // Can the scalar be expressed in the block plain style? - single_quoted_allowed bool // Can the scalar be expressed in the single quoted style? - block_allowed bool // Can the scalar be expressed in the literal or folded styles? - style yaml_scalar_style_t // The output style. - } - - // Comments - head_comment []byte - line_comment []byte - foot_comment []byte - tail_comment []byte - - key_line_comment []byte - - // Dumper stuff - - opened bool // If the stream was already opened? - closed bool // If the stream was already closed? - - // The information associated with the document nodes. - anchors *struct { - references int // The number of references. - anchor int // The anchor id. - serialized bool // If the node has been emitted? - } - - last_anchor_id int // The last assigned anchor id. - - document *yaml_document_t // The currently emitted document. -} diff --git a/vendor/gopkg.in/yaml.v3/yamlprivateh.go b/vendor/gopkg.in/yaml.v3/yamlprivateh.go deleted file mode 100644 index e88f9c54..00000000 --- a/vendor/gopkg.in/yaml.v3/yamlprivateh.go +++ /dev/null @@ -1,198 +0,0 @@ -// -// Copyright (c) 2011-2019 Canonical Ltd -// Copyright (c) 2006-2010 Kirill Simonov -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package yaml - -const ( - // The size of the input raw buffer. - input_raw_buffer_size = 512 - - // The size of the input buffer. - // It should be possible to decode the whole raw buffer. - input_buffer_size = input_raw_buffer_size * 3 - - // The size of the output buffer. - output_buffer_size = 128 - - // The size of the output raw buffer. - // It should be possible to encode the whole output buffer. - output_raw_buffer_size = (output_buffer_size*2 + 2) - - // The size of other stacks and queues. - initial_stack_size = 16 - initial_queue_size = 16 - initial_string_size = 16 -) - -// Check if the character at the specified position is an alphabetical -// character, a digit, '_', or '-'. -func is_alpha(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-' -} - -// Check if the character at the specified position is a digit. -func is_digit(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' -} - -// Get the value of a digit. -func as_digit(b []byte, i int) int { - return int(b[i]) - '0' -} - -// Check if the character at the specified position is a hex-digit. -func is_hex(b []byte, i int) bool { - return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f' -} - -// Get the value of a hex-digit. -func as_hex(b []byte, i int) int { - bi := b[i] - if bi >= 'A' && bi <= 'F' { - return int(bi) - 'A' + 10 - } - if bi >= 'a' && bi <= 'f' { - return int(bi) - 'a' + 10 - } - return int(bi) - '0' -} - -// Check if the character is ASCII. -func is_ascii(b []byte, i int) bool { - return b[i] <= 0x7F -} - -// Check if the character at the start of the buffer can be printed unescaped. -func is_printable(b []byte, i int) bool { - return ((b[i] == 0x0A) || // . == #x0A - (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E - (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF - (b[i] > 0xC2 && b[i] < 0xED) || - (b[i] == 0xED && b[i+1] < 0xA0) || - (b[i] == 0xEE) || - (b[i] == 0xEF && // #xE000 <= . <= #xFFFD - !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF - !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF)))) -} - -// Check if the character at the specified position is NUL. -func is_z(b []byte, i int) bool { - return b[i] == 0x00 -} - -// Check if the beginning of the buffer is a BOM. -func is_bom(b []byte, i int) bool { - return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF -} - -// Check if the character at the specified position is space. -func is_space(b []byte, i int) bool { - return b[i] == ' ' -} - -// Check if the character at the specified position is tab. -func is_tab(b []byte, i int) bool { - return b[i] == '\t' -} - -// Check if the character at the specified position is blank (space or tab). -func is_blank(b []byte, i int) bool { - //return is_space(b, i) || is_tab(b, i) - return b[i] == ' ' || b[i] == '\t' -} - -// Check if the character at the specified position is a line break. -func is_break(b []byte, i int) bool { - return (b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029) -} - -func is_crlf(b []byte, i int) bool { - return b[i] == '\r' && b[i+1] == '\n' -} - -// Check if the character is a line break or NUL. -func is_breakz(b []byte, i int) bool { - //return is_break(b, i) || is_z(b, i) - return ( - // is_break: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - // is_z: - b[i] == 0) -} - -// Check if the character is a line break, space, or NUL. -func is_spacez(b []byte, i int) bool { - //return is_space(b, i) || is_breakz(b, i) - return ( - // is_space: - b[i] == ' ' || - // is_breakz: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - b[i] == 0) -} - -// Check if the character is a line break, space, tab, or NUL. -func is_blankz(b []byte, i int) bool { - //return is_blank(b, i) || is_breakz(b, i) - return ( - // is_blank: - b[i] == ' ' || b[i] == '\t' || - // is_breakz: - b[i] == '\r' || // CR (#xD) - b[i] == '\n' || // LF (#xA) - b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) - b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) - b[i] == 0) -} - -// Determine the width of the character. -func width(b byte) int { - // Don't replace these by a switch without first - // confirming that it is being inlined. - if b&0x80 == 0x00 { - return 1 - } - if b&0xE0 == 0xC0 { - return 2 - } - if b&0xF0 == 0xE0 { - return 3 - } - if b&0xF8 == 0xF0 { - return 4 - } - return 0 - -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 3b629f45..7cddc58b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -233,14 +233,14 @@ github.com/yapingcat/gomedia/codec # github.com/yapingcat/gomedia/mpeg2 v0.0.0-20220617074658-94762898dc25 ## explicit; go 1.16 github.com/yapingcat/gomedia/mpeg2 -# golang.org/x/crypto v0.39.0 -## explicit; go 1.23.0 +# golang.org/x/crypto v0.45.0 +## explicit; go 1.24.0 golang.org/x/crypto/cryptobyte golang.org/x/crypto/cryptobyte/asn1 golang.org/x/crypto/curve25519 golang.org/x/crypto/ssh/terminal -# golang.org/x/net v0.41.0 -## explicit; go 1.23.0 +# golang.org/x/net v0.47.0 +## explicit; go 1.24.0 golang.org/x/net/bpf golang.org/x/net/dns/dnsmessage golang.org/x/net/internal/iana @@ -249,12 +249,12 @@ golang.org/x/net/internal/socks golang.org/x/net/ipv4 golang.org/x/net/ipv6 golang.org/x/net/proxy -# golang.org/x/sys v0.33.0 -## explicit; go 1.23.0 +# golang.org/x/sys v0.38.0 +## explicit; go 1.24.0 golang.org/x/sys/cpu golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.32.0 -## explicit; go 1.23.0 +# golang.org/x/term v0.37.0 +## explicit; go 1.24.0 golang.org/x/term