Integrate BACKBEAT SDK and resolve KACHING license validation
Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
3
vendor/github.com/multiformats/go-multiaddr/.gitignore
generated
vendored
Normal file
3
vendor/github.com/multiformats/go-multiaddr/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.vscode/
|
||||
multiaddr/multiaddr
|
||||
tmp/
|
||||
21
vendor/github.com/multiformats/go-multiaddr/LICENSE
generated
vendored
Normal file
21
vendor/github.com/multiformats/go-multiaddr/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Juan Batiz-Benet
|
||||
|
||||
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.
|
||||
117
vendor/github.com/multiformats/go-multiaddr/README.md
generated
vendored
Normal file
117
vendor/github.com/multiformats/go-multiaddr/README.md
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
# go-multiaddr
|
||||
|
||||
[](http://ipn.io)
|
||||
[](https://github.com/multiformats/multiformats)
|
||||
[](https://webchat.freenode.net/?channels=%23ipfs)
|
||||
[](https://github.com/RichardLitt/standard-readme)
|
||||
[](https://godoc.org/github.com/multiformats/go-multiaddr)
|
||||
[](https://travis-ci.org/multiformats/go-multiaddr)
|
||||
[](https://codecov.io/github/multiformats/go-multiaddr?branch=master)
|
||||
|
||||
> [multiaddr](https://github.com/multiformats/multiaddr) implementation in go
|
||||
|
||||
Multiaddr is a standard way to represent addresses that:
|
||||
|
||||
- Support any standard network protocols.
|
||||
- Self-describe (include protocols).
|
||||
- Have a binary packed format.
|
||||
- Have a nice string representation.
|
||||
- Encapsulate well.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [Example](#example)
|
||||
- [Simple](#simple)
|
||||
- [Protocols](#protocols)
|
||||
- [En/decapsulate](#endecapsulate)
|
||||
- [Tunneling](#tunneling)
|
||||
- [Maintainers](#maintainers)
|
||||
- [Contribute](#contribute)
|
||||
- [License](#license)
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
go get github.com/multiformats/go-multiaddr
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Example
|
||||
|
||||
#### Simple
|
||||
|
||||
```go
|
||||
import ma "github.com/multiformats/go-multiaddr"
|
||||
|
||||
// construct from a string (err signals parse failure)
|
||||
m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
|
||||
|
||||
// construct from bytes (err signals parse failure)
|
||||
m2, err := ma.NewMultiaddrBytes(m1.Bytes())
|
||||
|
||||
// true
|
||||
strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234")
|
||||
strings.Equal(m1.String(), m2.String())
|
||||
bytes.Equal(m1.Bytes(), m2.Bytes())
|
||||
m1.Equal(m2)
|
||||
m2.Equal(m1)
|
||||
```
|
||||
|
||||
#### Protocols
|
||||
|
||||
```go
|
||||
// get the multiaddr protocol description objects
|
||||
m1.Protocols()
|
||||
// []Protocol{
|
||||
// Protocol{ Code: 4, Name: 'ip4', Size: 32},
|
||||
// Protocol{ Code: 17, Name: 'udp', Size: 16},
|
||||
// }
|
||||
```
|
||||
|
||||
#### En/decapsulate
|
||||
|
||||
```go
|
||||
import ma "github.com/multiformats/go-multiaddr"
|
||||
|
||||
m, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
|
||||
// <Multiaddr /ip4/127.0.0.1/udp/1234>
|
||||
|
||||
sctpMA, err := ma.NewMultiaddr("/sctp/5678")
|
||||
|
||||
m.Encapsulate(sctpMA)
|
||||
// <Multiaddr /ip4/127.0.0.1/udp/1234/sctp/5678>
|
||||
|
||||
udpMA, err := ma.NewMultiaddr("/udp/1234")
|
||||
|
||||
m.Decapsulate(udpMA) // up to + inc last occurrence of subaddr
|
||||
// <Multiaddr /ip4/127.0.0.1>
|
||||
```
|
||||
|
||||
#### Tunneling
|
||||
|
||||
Multiaddr allows expressing tunnels very nicely.
|
||||
|
||||
```js
|
||||
printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80")
|
||||
proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443")
|
||||
printerOverProxy := proxy.Encapsulate(printer)
|
||||
// /ip4/10.20.30.40/tcp/443/ip4/192.168.0.13/tcp/80
|
||||
|
||||
proxyAgain := printerOverProxy.Decapsulate(printer)
|
||||
// /ip4/10.20.30.40/tcp/443
|
||||
```
|
||||
|
||||
## Contribute
|
||||
|
||||
Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multiaddr/issues).
|
||||
|
||||
Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
|
||||
|
||||
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE) © 2014 Juan Batiz-Benet
|
||||
178
vendor/github.com/multiformats/go-multiaddr/codec.go
generated
vendored
Normal file
178
vendor/github.com/multiformats/go-multiaddr/codec.go
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/multiformats/go-varint"
|
||||
)
|
||||
|
||||
func stringToBytes(s string) ([]byte, error) {
|
||||
// consume trailing slashes
|
||||
s = strings.TrimRight(s, "/")
|
||||
|
||||
var b bytes.Buffer
|
||||
sp := strings.Split(s, "/")
|
||||
|
||||
if sp[0] != "" {
|
||||
return nil, fmt.Errorf("failed to parse multiaddr %q: must begin with /", s)
|
||||
}
|
||||
|
||||
// consume first empty elem
|
||||
sp = sp[1:]
|
||||
|
||||
if len(sp) == 0 {
|
||||
return nil, fmt.Errorf("failed to parse multiaddr %q: empty multiaddr", s)
|
||||
}
|
||||
|
||||
for len(sp) > 0 {
|
||||
name := sp[0]
|
||||
p := ProtocolWithName(name)
|
||||
if p.Code == 0 {
|
||||
return nil, fmt.Errorf("failed to parse multiaddr %q: unknown protocol %s", s, sp[0])
|
||||
}
|
||||
_, _ = b.Write(p.VCode)
|
||||
sp = sp[1:]
|
||||
|
||||
if p.Size == 0 { // no length.
|
||||
continue
|
||||
}
|
||||
|
||||
if len(sp) < 1 {
|
||||
return nil, fmt.Errorf("failed to parse multiaddr %q: unexpected end of multiaddr", s)
|
||||
}
|
||||
|
||||
if p.Path {
|
||||
// it's a path protocol (terminal).
|
||||
// consume the rest of the address as the next component.
|
||||
sp = []string{"/" + strings.Join(sp, "/")}
|
||||
}
|
||||
|
||||
a, err := p.Transcoder.StringToBytes(sp[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse multiaddr %q: invalid value %q for protocol %s: %s", s, sp[0], p.Name, err)
|
||||
}
|
||||
if p.Size < 0 { // varint size.
|
||||
_, _ = b.Write(varint.ToUvarint(uint64(len(a))))
|
||||
}
|
||||
b.Write(a)
|
||||
sp = sp[1:]
|
||||
}
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func validateBytes(b []byte) (err error) {
|
||||
if len(b) == 0 {
|
||||
return fmt.Errorf("empty multiaddr")
|
||||
}
|
||||
for len(b) > 0 {
|
||||
code, n, err := ReadVarintCode(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b = b[n:]
|
||||
p := ProtocolWithCode(code)
|
||||
if p.Code == 0 {
|
||||
return fmt.Errorf("no protocol with code %d", code)
|
||||
}
|
||||
|
||||
if p.Size == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
n, size, err := sizeForAddr(p, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b = b[n:]
|
||||
|
||||
if len(b) < size || size < 0 {
|
||||
return fmt.Errorf("invalid value for size %d", len(b))
|
||||
}
|
||||
|
||||
err = p.Transcoder.ValidateBytes(b[:size])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b = b[size:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readComponent(b []byte) (int, Component, error) {
|
||||
var offset int
|
||||
code, n, err := ReadVarintCode(b)
|
||||
if err != nil {
|
||||
return 0, Component{}, err
|
||||
}
|
||||
offset += n
|
||||
|
||||
p := ProtocolWithCode(code)
|
||||
if p.Code == 0 {
|
||||
return 0, Component{}, fmt.Errorf("no protocol with code %d", code)
|
||||
}
|
||||
|
||||
if p.Size == 0 {
|
||||
return offset, Component{
|
||||
bytes: b[:offset],
|
||||
offset: offset,
|
||||
protocol: p,
|
||||
}, nil
|
||||
}
|
||||
|
||||
n, size, err := sizeForAddr(p, b[offset:])
|
||||
if err != nil {
|
||||
return 0, Component{}, err
|
||||
}
|
||||
|
||||
offset += n
|
||||
|
||||
if len(b[offset:]) < size || size < 0 {
|
||||
return 0, Component{}, fmt.Errorf("invalid value for size %d", len(b[offset:]))
|
||||
}
|
||||
|
||||
return offset + size, Component{
|
||||
bytes: b[:offset+size],
|
||||
protocol: p,
|
||||
offset: offset,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func bytesToString(b []byte) (ret string, err error) {
|
||||
if len(b) == 0 {
|
||||
return "", fmt.Errorf("empty multiaddr")
|
||||
}
|
||||
var buf strings.Builder
|
||||
|
||||
for len(b) > 0 {
|
||||
n, c, err := readComponent(b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b = b[n:]
|
||||
c.writeTo(&buf)
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
func sizeForAddr(p Protocol, b []byte) (skip, size int, err error) {
|
||||
switch {
|
||||
case p.Size > 0:
|
||||
return 0, (p.Size / 8), nil
|
||||
case p.Size == 0:
|
||||
return 0, 0, nil
|
||||
default:
|
||||
size, n, err := ReadVarintCode(b)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return n, size, nil
|
||||
}
|
||||
}
|
||||
2
vendor/github.com/multiformats/go-multiaddr/codecov.yml
generated
vendored
Normal file
2
vendor/github.com/multiformats/go-multiaddr/codecov.yml
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
ignore:
|
||||
- "multiaddr"
|
||||
183
vendor/github.com/multiformats/go-multiaddr/component.go
generated
vendored
Normal file
183
vendor/github.com/multiformats/go-multiaddr/component.go
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/multiformats/go-varint"
|
||||
)
|
||||
|
||||
// Component is a single multiaddr Component.
|
||||
type Component struct {
|
||||
bytes []byte
|
||||
protocol Protocol
|
||||
offset int
|
||||
}
|
||||
|
||||
func (c *Component) Bytes() []byte {
|
||||
return c.bytes
|
||||
}
|
||||
|
||||
func (c *Component) MarshalBinary() ([]byte, error) {
|
||||
return c.Bytes(), nil
|
||||
}
|
||||
|
||||
func (c *Component) UnmarshalBinary(data []byte) error {
|
||||
_, comp, err := readComponent(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*c = comp
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Component) MarshalText() ([]byte, error) {
|
||||
return []byte(c.String()), nil
|
||||
}
|
||||
|
||||
func (c *Component) UnmarshalText(data []byte) error {
|
||||
bytes, err := stringToBytes(string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, comp, err := readComponent(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*c = comp
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Component) MarshalJSON() ([]byte, error) {
|
||||
txt, err := c.MarshalText()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(string(txt))
|
||||
}
|
||||
|
||||
func (m *Component) UnmarshalJSON(data []byte) error {
|
||||
var v string
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.UnmarshalText([]byte(v))
|
||||
}
|
||||
|
||||
func (c *Component) Equal(o Multiaddr) bool {
|
||||
return bytes.Equal(c.bytes, o.Bytes())
|
||||
}
|
||||
|
||||
func (c *Component) Protocols() []Protocol {
|
||||
return []Protocol{c.protocol}
|
||||
}
|
||||
|
||||
func (c *Component) Decapsulate(o Multiaddr) Multiaddr {
|
||||
if c.Equal(o) {
|
||||
return nil
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Component) Encapsulate(o Multiaddr) Multiaddr {
|
||||
m := &multiaddr{bytes: c.bytes}
|
||||
return m.Encapsulate(o)
|
||||
}
|
||||
|
||||
func (c *Component) ValueForProtocol(code int) (string, error) {
|
||||
if c.protocol.Code != code {
|
||||
return "", ErrProtocolNotFound
|
||||
}
|
||||
return c.Value(), nil
|
||||
}
|
||||
|
||||
func (c *Component) Protocol() Protocol {
|
||||
return c.protocol
|
||||
}
|
||||
|
||||
func (c *Component) RawValue() []byte {
|
||||
return c.bytes[c.offset:]
|
||||
}
|
||||
|
||||
func (c *Component) Value() string {
|
||||
if c.protocol.Transcoder == nil {
|
||||
return ""
|
||||
}
|
||||
value, err := c.protocol.Transcoder.BytesToString(c.bytes[c.offset:])
|
||||
if err != nil {
|
||||
// This Component must have been checked.
|
||||
panic(err)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func (c *Component) String() string {
|
||||
var b strings.Builder
|
||||
c.writeTo(&b)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// writeTo is an efficient, private function for string-formatting a multiaddr.
|
||||
// Trust me, we tend to allocate a lot when doing this.
|
||||
func (c *Component) writeTo(b *strings.Builder) {
|
||||
b.WriteByte('/')
|
||||
b.WriteString(c.protocol.Name)
|
||||
value := c.Value()
|
||||
if len(value) == 0 {
|
||||
return
|
||||
}
|
||||
if !(c.protocol.Path && value[0] == '/') {
|
||||
b.WriteByte('/')
|
||||
}
|
||||
b.WriteString(value)
|
||||
}
|
||||
|
||||
// NewComponent constructs a new multiaddr component
|
||||
func NewComponent(protocol, value string) (*Component, error) {
|
||||
p := ProtocolWithName(protocol)
|
||||
if p.Code == 0 {
|
||||
return nil, fmt.Errorf("unsupported protocol: %s", protocol)
|
||||
}
|
||||
if p.Transcoder != nil {
|
||||
bts, err := p.Transcoder.StringToBytes(value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newComponent(p, bts), nil
|
||||
} else if value != "" {
|
||||
return nil, fmt.Errorf("protocol %s doesn't take a value", p.Name)
|
||||
}
|
||||
return newComponent(p, nil), nil
|
||||
// TODO: handle path /?
|
||||
}
|
||||
|
||||
func newComponent(protocol Protocol, bvalue []byte) *Component {
|
||||
size := len(bvalue)
|
||||
size += len(protocol.VCode)
|
||||
if protocol.Size < 0 {
|
||||
size += varint.UvarintSize(uint64(len(bvalue)))
|
||||
}
|
||||
maddr := make([]byte, size)
|
||||
var offset int
|
||||
offset += copy(maddr[offset:], protocol.VCode)
|
||||
if protocol.Size < 0 {
|
||||
offset += binary.PutUvarint(maddr[offset:], uint64(len(bvalue)))
|
||||
}
|
||||
copy(maddr[offset:], bvalue)
|
||||
|
||||
// For debugging
|
||||
if len(maddr) != offset+len(bvalue) {
|
||||
panic("incorrect length")
|
||||
}
|
||||
|
||||
return &Component{
|
||||
bytes: maddr,
|
||||
protocol: protocol,
|
||||
offset: offset,
|
||||
}
|
||||
}
|
||||
35
vendor/github.com/multiformats/go-multiaddr/doc.go
generated
vendored
Normal file
35
vendor/github.com/multiformats/go-multiaddr/doc.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Package multiaddr provides an implementation of the Multiaddr network
|
||||
address format. Multiaddr emphasizes explicitness, self-description, and
|
||||
portability. It allows applications to treat addresses as opaque tokens,
|
||||
and to avoid making assumptions about the address representation (e.g. length).
|
||||
Learn more at https://github.com/multiformats/multiaddr
|
||||
|
||||
Basic Use:
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// construct from a string (err signals parse failure)
|
||||
m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
|
||||
|
||||
// construct from bytes (err signals parse failure)
|
||||
m2, err := ma.NewMultiaddrBytes(m1.Bytes())
|
||||
|
||||
// true
|
||||
strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234")
|
||||
strings.Equal(m1.String(), m2.String())
|
||||
bytes.Equal(m1.Bytes(), m2.Bytes())
|
||||
m1.Equal(m2)
|
||||
m2.Equal(m1)
|
||||
|
||||
// tunneling (en/decap)
|
||||
printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80")
|
||||
proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443")
|
||||
printerOverProxy := proxy.Encapsulate(printer)
|
||||
proxyAgain := printerOverProxy.Decapsulate(printer)
|
||||
*/
|
||||
package multiaddr
|
||||
145
vendor/github.com/multiformats/go-multiaddr/filter.go
generated
vendored
Normal file
145
vendor/github.com/multiformats/go-multiaddr/filter.go
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Action is an enum modelling all possible filter actions.
|
||||
type Action int32
|
||||
|
||||
const (
|
||||
ActionNone Action = iota // zero value.
|
||||
ActionAccept
|
||||
ActionDeny
|
||||
)
|
||||
|
||||
type filterEntry struct {
|
||||
f net.IPNet
|
||||
action Action
|
||||
}
|
||||
|
||||
// Filters is a structure representing a collection of accept/deny
|
||||
// net.IPNet filters, together with the DefaultAction flag, which
|
||||
// represents the default filter policy.
|
||||
//
|
||||
// Note that the last policy added to the Filters is authoritative.
|
||||
type Filters struct {
|
||||
DefaultAction Action
|
||||
|
||||
mu sync.RWMutex
|
||||
filters []*filterEntry
|
||||
}
|
||||
|
||||
// NewFilters constructs and returns a new set of net.IPNet filters.
|
||||
// By default, the new filter accepts all addresses.
|
||||
func NewFilters() *Filters {
|
||||
return &Filters{
|
||||
DefaultAction: ActionAccept,
|
||||
filters: make([]*filterEntry, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *Filters) find(ipnet net.IPNet) (int, *filterEntry) {
|
||||
s := ipnet.String()
|
||||
for idx, ft := range fs.filters {
|
||||
if ft.f.String() == s {
|
||||
return idx, ft
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// AddFilter adds a rule to the Filters set, enforcing the desired action for
|
||||
// the provided IPNet mask.
|
||||
func (fs *Filters) AddFilter(ipnet net.IPNet, action Action) {
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
|
||||
if _, f := fs.find(ipnet); f != nil {
|
||||
f.action = action
|
||||
} else {
|
||||
fs.filters = append(fs.filters, &filterEntry{ipnet, action})
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveLiteral removes the first filter associated with the supplied IPNet,
|
||||
// returning whether something was removed or not. It makes no distinction
|
||||
// between whether the rule is an accept or a deny.
|
||||
func (fs *Filters) RemoveLiteral(ipnet net.IPNet) (removed bool) {
|
||||
fs.mu.Lock()
|
||||
defer fs.mu.Unlock()
|
||||
|
||||
if idx, _ := fs.find(ipnet); idx != -1 {
|
||||
fs.filters = append(fs.filters[:idx], fs.filters[idx+1:]...)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddrBlocked parses a ma.Multiaddr and, if a valid netip is found, it applies the
|
||||
// Filter set rules, returning true if the given address should be denied, and false if
|
||||
// the given address is accepted.
|
||||
//
|
||||
// If a parsing error occurs, or no filter matches, the Filters'
|
||||
// default is returned.
|
||||
//
|
||||
// TODO: currently, the last filter to match wins always, but it shouldn't be that way.
|
||||
//
|
||||
// Instead, the highest-specific last filter should win; that way more specific filters
|
||||
// override more general ones.
|
||||
func (fs *Filters) AddrBlocked(a Multiaddr) (deny bool) {
|
||||
var (
|
||||
netip net.IP
|
||||
found bool
|
||||
)
|
||||
|
||||
ForEach(a, func(c Component) bool {
|
||||
switch c.Protocol().Code {
|
||||
case P_IP6ZONE:
|
||||
return true
|
||||
case P_IP6, P_IP4:
|
||||
found = true
|
||||
netip = net.IP(c.RawValue())
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
if !found {
|
||||
return fs.DefaultAction == ActionDeny
|
||||
}
|
||||
|
||||
fs.mu.RLock()
|
||||
defer fs.mu.RUnlock()
|
||||
|
||||
action := fs.DefaultAction
|
||||
for _, ft := range fs.filters {
|
||||
if ft.f.Contains(netip) {
|
||||
action = ft.action
|
||||
}
|
||||
}
|
||||
|
||||
return action == ActionDeny
|
||||
}
|
||||
|
||||
func (fs *Filters) ActionForFilter(ipnet net.IPNet) (action Action, ok bool) {
|
||||
if _, f := fs.find(ipnet); f != nil {
|
||||
return f.action, true
|
||||
}
|
||||
return ActionNone, false
|
||||
}
|
||||
|
||||
// FiltersForAction returns the filters associated with the indicated action.
|
||||
func (fs *Filters) FiltersForAction(action Action) (result []net.IPNet) {
|
||||
fs.mu.RLock()
|
||||
defer fs.mu.RUnlock()
|
||||
|
||||
for _, ff := range fs.filters {
|
||||
if ff.action == action {
|
||||
result = append(result, ff.f)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
63
vendor/github.com/multiformats/go-multiaddr/interface.go
generated
vendored
Normal file
63
vendor/github.com/multiformats/go-multiaddr/interface.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
/*
|
||||
Multiaddr is a cross-protocol, cross-platform format for representing
|
||||
internet addresses. It emphasizes explicitness and self-description.
|
||||
Learn more here: https://github.com/multiformats/multiaddr
|
||||
|
||||
Multiaddrs have both a binary and string representation.
|
||||
|
||||
import ma "github.com/multiformats/go-multiaddr"
|
||||
|
||||
addr, err := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/80")
|
||||
// err non-nil when parsing failed.
|
||||
*/
|
||||
type Multiaddr interface {
|
||||
json.Marshaler
|
||||
json.Unmarshaler
|
||||
encoding.TextMarshaler
|
||||
encoding.TextUnmarshaler
|
||||
encoding.BinaryMarshaler
|
||||
encoding.BinaryUnmarshaler
|
||||
|
||||
// Equal returns whether two Multiaddrs are exactly equal
|
||||
Equal(Multiaddr) bool
|
||||
|
||||
// Bytes returns the []byte representation of this Multiaddr
|
||||
//
|
||||
// This function may expose immutable, internal state. Do not modify.
|
||||
Bytes() []byte
|
||||
|
||||
// String returns the string representation of this Multiaddr
|
||||
// (may panic if internal state is corrupted)
|
||||
String() string
|
||||
|
||||
// Protocols returns the list of Protocols this Multiaddr includes
|
||||
// will panic if protocol code incorrect (and bytes accessed incorrectly)
|
||||
Protocols() []Protocol
|
||||
|
||||
// Encapsulate wraps this Multiaddr around another. For example:
|
||||
//
|
||||
// /ip4/1.2.3.4 encapsulate /tcp/80 = /ip4/1.2.3.4/tcp/80
|
||||
//
|
||||
Encapsulate(Multiaddr) Multiaddr
|
||||
|
||||
// Decapsulate removes a Multiaddr wrapping. For example:
|
||||
//
|
||||
// /ip4/1.2.3.4/tcp/80 decapsulate /tcp/80 = /ip4/1.2.3.4
|
||||
// /ip4/1.2.3.4/tcp/80 decapsulate /udp/80 = /ip4/1.2.3.4/tcp/80
|
||||
// /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = nil
|
||||
//
|
||||
Decapsulate(Multiaddr) Multiaddr
|
||||
|
||||
// ValueForProtocol returns the value (if any) following the specified protocol
|
||||
//
|
||||
// Note: protocols can appear multiple times in a single multiaddr.
|
||||
// Consider using `ForEach` to walk over the addr manually.
|
||||
ValueForProtocol(code int) (string, error)
|
||||
}
|
||||
235
vendor/github.com/multiformats/go-multiaddr/multiaddr.go
generated
vendored
Normal file
235
vendor/github.com/multiformats/go-multiaddr/multiaddr.go
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// multiaddr is the data structure representing a Multiaddr
|
||||
type multiaddr struct {
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
// NewMultiaddr parses and validates an input string, returning a *Multiaddr
|
||||
func NewMultiaddr(s string) (a Multiaddr, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
log.Printf("Panic in NewMultiaddr on input %q: %s", s, e)
|
||||
err = fmt.Errorf("%v", e)
|
||||
}
|
||||
}()
|
||||
b, err := stringToBytes(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &multiaddr{bytes: b}, nil
|
||||
}
|
||||
|
||||
// NewMultiaddrBytes initializes a Multiaddr from a byte representation.
|
||||
// It validates it as an input string.
|
||||
func NewMultiaddrBytes(b []byte) (a Multiaddr, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
log.Printf("Panic in NewMultiaddrBytes on input %q: %s", b, e)
|
||||
err = fmt.Errorf("%v", e)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := validateBytes(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &multiaddr{bytes: b}, nil
|
||||
}
|
||||
|
||||
// Equal tests whether two multiaddrs are equal
|
||||
func (m *multiaddr) Equal(m2 Multiaddr) bool {
|
||||
return bytes.Equal(m.bytes, m2.Bytes())
|
||||
}
|
||||
|
||||
// Bytes returns the []byte representation of this Multiaddr
|
||||
//
|
||||
// Do not modify the returned buffer, it may be shared.
|
||||
func (m *multiaddr) Bytes() []byte {
|
||||
return m.bytes
|
||||
}
|
||||
|
||||
// String returns the string representation of a Multiaddr
|
||||
func (m *multiaddr) String() string {
|
||||
s, err := bytesToString(m.bytes)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("multiaddr failed to convert back to string. corrupted? %s", err))
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (m *multiaddr) MarshalBinary() ([]byte, error) {
|
||||
return m.Bytes(), nil
|
||||
}
|
||||
|
||||
func (m *multiaddr) UnmarshalBinary(data []byte) error {
|
||||
new, err := NewMultiaddrBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = *(new.(*multiaddr))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *multiaddr) MarshalText() ([]byte, error) {
|
||||
return []byte(m.String()), nil
|
||||
}
|
||||
|
||||
func (m *multiaddr) UnmarshalText(data []byte) error {
|
||||
new, err := NewMultiaddr(string(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = *(new.(*multiaddr))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *multiaddr) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(m.String())
|
||||
}
|
||||
|
||||
func (m *multiaddr) UnmarshalJSON(data []byte) error {
|
||||
var v string
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
new, err := NewMultiaddr(v)
|
||||
*m = *(new.(*multiaddr))
|
||||
return err
|
||||
}
|
||||
|
||||
// Protocols returns the list of protocols this Multiaddr has.
|
||||
// will panic in case we access bytes incorrectly.
|
||||
func (m *multiaddr) Protocols() []Protocol {
|
||||
ps := make([]Protocol, 0, 8)
|
||||
b := m.bytes
|
||||
for len(b) > 0 {
|
||||
code, n, err := ReadVarintCode(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
p := ProtocolWithCode(code)
|
||||
if p.Code == 0 {
|
||||
// this is a panic (and not returning err) because this should've been
|
||||
// caught on constructing the Multiaddr
|
||||
panic(fmt.Errorf("no protocol with code %d", b[0]))
|
||||
}
|
||||
ps = append(ps, p)
|
||||
b = b[n:]
|
||||
|
||||
n, size, err := sizeForAddr(p, b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b = b[n+size:]
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
// Encapsulate wraps a given Multiaddr, returning the resulting joined Multiaddr
|
||||
func (m *multiaddr) Encapsulate(o Multiaddr) Multiaddr {
|
||||
mb := m.bytes
|
||||
ob := o.Bytes()
|
||||
|
||||
b := make([]byte, len(mb)+len(ob))
|
||||
copy(b, mb)
|
||||
copy(b[len(mb):], ob)
|
||||
return &multiaddr{bytes: b}
|
||||
}
|
||||
|
||||
// Decapsulate unwraps Multiaddr up until the given Multiaddr is found.
|
||||
func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr {
|
||||
s1 := m.String()
|
||||
s2 := o.String()
|
||||
i := strings.LastIndex(s1, s2)
|
||||
if i < 0 {
|
||||
// if multiaddr not contained, returns a copy.
|
||||
cpy := make([]byte, len(m.bytes))
|
||||
copy(cpy, m.bytes)
|
||||
return &multiaddr{bytes: cpy}
|
||||
}
|
||||
|
||||
if i == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
ma, err := NewMultiaddr(s1[:i])
|
||||
if err != nil {
|
||||
panic("Multiaddr.Decapsulate incorrect byte boundaries.")
|
||||
}
|
||||
return ma
|
||||
}
|
||||
|
||||
var ErrProtocolNotFound = fmt.Errorf("protocol not found in multiaddr")
|
||||
|
||||
func (m *multiaddr) ValueForProtocol(code int) (value string, err error) {
|
||||
err = ErrProtocolNotFound
|
||||
ForEach(m, func(c Component) bool {
|
||||
if c.Protocol().Code == code {
|
||||
value = c.Value()
|
||||
err = nil
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// FilterAddrs is a filter that removes certain addresses, according to the given filters.
|
||||
// If all filters return true, the address is kept.
|
||||
func FilterAddrs(a []Multiaddr, filters ...func(Multiaddr) bool) []Multiaddr {
|
||||
b := make([]Multiaddr, 0, len(a))
|
||||
addrloop:
|
||||
for _, addr := range a {
|
||||
for _, filter := range filters {
|
||||
if !filter(addr) {
|
||||
continue addrloop
|
||||
}
|
||||
}
|
||||
b = append(b, addr)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Contains reports whether addr is contained in addrs.
|
||||
func Contains(addrs []Multiaddr, addr Multiaddr) bool {
|
||||
for _, a := range addrs {
|
||||
if addr.Equal(a) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Unique deduplicates addresses in place, leave only unique addresses.
|
||||
// It doesn't allocate.
|
||||
func Unique(addrs []Multiaddr) []Multiaddr {
|
||||
if len(addrs) == 0 {
|
||||
return addrs
|
||||
}
|
||||
// Use the new slices package here, as the sort function doesn't allocate (sort.Slice does).
|
||||
slices.SortFunc(addrs, func(a, b Multiaddr) int { return bytes.Compare(a.Bytes(), b.Bytes()) })
|
||||
idx := 1
|
||||
for i := 1; i < len(addrs); i++ {
|
||||
if !addrs[i-1].Equal(addrs[i]) {
|
||||
addrs[idx] = addrs[i]
|
||||
idx++
|
||||
}
|
||||
}
|
||||
for i := idx; i < len(addrs); i++ {
|
||||
addrs[i] = nil
|
||||
}
|
||||
return addrs[:idx]
|
||||
}
|
||||
358
vendor/github.com/multiformats/go-multiaddr/net/convert.go
generated
vendored
Normal file
358
vendor/github.com/multiformats/go-multiaddr/net/convert.go
generated
vendored
Normal file
@@ -0,0 +1,358 @@
|
||||
package manet
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
var errIncorrectNetAddr = fmt.Errorf("incorrect network addr conversion")
|
||||
var errNotIP = fmt.Errorf("multiaddr does not start with an IP address")
|
||||
|
||||
// FromNetAddr converts a net.Addr type to a Multiaddr.
|
||||
func FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
return defaultCodecs.FromNetAddr(a)
|
||||
}
|
||||
|
||||
// FromNetAddr converts a net.Addr to Multiaddress.
|
||||
func (cm *CodecMap) FromNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
if a == nil {
|
||||
return nil, fmt.Errorf("nil multiaddr")
|
||||
}
|
||||
p, err := cm.getAddrParser(a.Network())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p(a)
|
||||
}
|
||||
|
||||
// ToNetAddr converts a Multiaddr to a net.Addr
|
||||
// Must be ThinWaist. acceptable protocol stacks are:
|
||||
// /ip{4,6}/{tcp, udp}
|
||||
func ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
||||
return defaultCodecs.ToNetAddr(maddr)
|
||||
}
|
||||
|
||||
// ToNetAddr converts a Multiaddress to a standard net.Addr.
|
||||
func (cm *CodecMap) ToNetAddr(maddr ma.Multiaddr) (net.Addr, error) {
|
||||
protos := maddr.Protocols()
|
||||
final := protos[len(protos)-1]
|
||||
|
||||
p, err := cm.getMaddrParser(final.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p(maddr)
|
||||
}
|
||||
|
||||
// MultiaddrToIPNet converts a multiaddr to an IPNet. Useful for seeing if another IP address is contained within this multiaddr network+mask
|
||||
func MultiaddrToIPNet(m ma.Multiaddr) (*net.IPNet, error) {
|
||||
var ipString string
|
||||
var mask string
|
||||
|
||||
ma.ForEach(m, func(c ma.Component) bool {
|
||||
if c.Protocol().Code == ma.P_IP4 || c.Protocol().Code == ma.P_IP6 {
|
||||
ipString = c.Value()
|
||||
}
|
||||
if c.Protocol().Code == ma.P_IPCIDR {
|
||||
mask = c.Value()
|
||||
}
|
||||
return ipString == "" || mask == ""
|
||||
})
|
||||
|
||||
if ipString == "" {
|
||||
return nil, errors.New("no ip protocol found")
|
||||
}
|
||||
|
||||
if mask == "" {
|
||||
return nil, errors.New("no mask found")
|
||||
}
|
||||
|
||||
_, ipnet, err := net.ParseCIDR(ipString + "/" + string(mask))
|
||||
return ipnet, err
|
||||
}
|
||||
|
||||
func parseBasicNetMaddr(maddr ma.Multiaddr) (net.Addr, error) {
|
||||
network, host, err := DialArgs(maddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
return net.ResolveTCPAddr(network, host)
|
||||
case "udp", "udp4", "udp6":
|
||||
return net.ResolveUDPAddr(network, host)
|
||||
case "ip", "ip4", "ip6":
|
||||
return net.ResolveIPAddr(network, host)
|
||||
case "unix":
|
||||
return net.ResolveUnixAddr(network, host)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("network not supported: %s", network)
|
||||
}
|
||||
|
||||
func FromIPAndZone(ip net.IP, zone string) (ma.Multiaddr, error) {
|
||||
switch {
|
||||
case ip.To4() != nil:
|
||||
return ma.NewComponent("ip4", ip.String())
|
||||
case ip.To16() != nil:
|
||||
ip6, err := ma.NewComponent("ip6", ip.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if zone == "" {
|
||||
return ip6, nil
|
||||
} else {
|
||||
zone, err := ma.NewComponent("ip6zone", zone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return zone.Encapsulate(ip6), nil
|
||||
}
|
||||
default:
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
}
|
||||
|
||||
// FromIP converts a net.IP type to a Multiaddr.
|
||||
func FromIP(ip net.IP) (ma.Multiaddr, error) {
|
||||
return FromIPAndZone(ip, "")
|
||||
}
|
||||
|
||||
// ToIP converts a Multiaddr to a net.IP when possible
|
||||
func ToIP(addr ma.Multiaddr) (net.IP, error) {
|
||||
var ip net.IP
|
||||
ma.ForEach(addr, func(c ma.Component) bool {
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_IP6ZONE:
|
||||
// we can't return these anyways.
|
||||
return true
|
||||
case ma.P_IP6, ma.P_IP4:
|
||||
ip = net.IP(c.RawValue())
|
||||
return false
|
||||
}
|
||||
return false
|
||||
})
|
||||
if ip == nil {
|
||||
return nil, errNotIP
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
// DialArgs is a convenience function that returns network and address as
|
||||
// expected by net.Dial. See https://godoc.org/net#Dial for an overview of
|
||||
// possible return values (we do not support the unixpacket ones yet). Unix
|
||||
// addresses do not, at present, compose.
|
||||
func DialArgs(m ma.Multiaddr) (string, string, error) {
|
||||
zone, network, ip, port, hostname, err := dialArgComponents(m)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// If we have a hostname (dns*), we don't want any fancy ipv6 formatting
|
||||
// logic (zone, brackets, etc.).
|
||||
if hostname {
|
||||
switch network {
|
||||
case "ip", "ip4", "ip6":
|
||||
return network, ip, nil
|
||||
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
|
||||
return network, ip + ":" + port, nil
|
||||
}
|
||||
// Hostname is only true when network is one of the above.
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "ip6":
|
||||
if zone != "" {
|
||||
ip += "%" + zone
|
||||
}
|
||||
fallthrough
|
||||
case "ip4":
|
||||
return network, ip, nil
|
||||
case "tcp4", "udp4":
|
||||
return network, ip + ":" + port, nil
|
||||
case "tcp6", "udp6":
|
||||
if zone != "" {
|
||||
ip += "%" + zone
|
||||
}
|
||||
return network, "[" + ip + "]" + ":" + port, nil
|
||||
case "unix":
|
||||
if runtime.GOOS == "windows" {
|
||||
// convert /c:/... to c:\...
|
||||
ip = filepath.FromSlash(strings.TrimLeft(ip, "/"))
|
||||
}
|
||||
return network, ip, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("%s is not a 'thin waist' address", m)
|
||||
}
|
||||
}
|
||||
|
||||
// dialArgComponents extracts the raw pieces used in dialing a Multiaddr
|
||||
func dialArgComponents(m ma.Multiaddr) (zone, network, ip, port string, hostname bool, err error) {
|
||||
ma.ForEach(m, func(c ma.Component) bool {
|
||||
switch network {
|
||||
case "":
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_IP6ZONE:
|
||||
if zone != "" {
|
||||
err = fmt.Errorf("%s has multiple zones", m)
|
||||
return false
|
||||
}
|
||||
zone = c.Value()
|
||||
return true
|
||||
case ma.P_IP6:
|
||||
network = "ip6"
|
||||
ip = c.Value()
|
||||
return true
|
||||
case ma.P_IP4:
|
||||
if zone != "" {
|
||||
err = fmt.Errorf("%s has ip4 with zone", m)
|
||||
return false
|
||||
}
|
||||
network = "ip4"
|
||||
ip = c.Value()
|
||||
return true
|
||||
case ma.P_DNS:
|
||||
network = "ip"
|
||||
hostname = true
|
||||
ip = c.Value()
|
||||
return true
|
||||
case ma.P_DNS4:
|
||||
network = "ip4"
|
||||
hostname = true
|
||||
ip = c.Value()
|
||||
return true
|
||||
case ma.P_DNS6:
|
||||
network = "ip6"
|
||||
hostname = true
|
||||
ip = c.Value()
|
||||
return true
|
||||
case ma.P_UNIX:
|
||||
network = "unix"
|
||||
ip = c.Value()
|
||||
return false
|
||||
}
|
||||
case "ip":
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_UDP:
|
||||
network = "udp"
|
||||
case ma.P_TCP:
|
||||
network = "tcp"
|
||||
default:
|
||||
return false
|
||||
}
|
||||
port = c.Value()
|
||||
case "ip4":
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_UDP:
|
||||
network = "udp4"
|
||||
case ma.P_TCP:
|
||||
network = "tcp4"
|
||||
default:
|
||||
return false
|
||||
}
|
||||
port = c.Value()
|
||||
case "ip6":
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_UDP:
|
||||
network = "udp6"
|
||||
case ma.P_TCP:
|
||||
network = "tcp6"
|
||||
default:
|
||||
return false
|
||||
}
|
||||
port = c.Value()
|
||||
}
|
||||
// Done.
|
||||
return false
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func parseTCPNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
ac, ok := a.(*net.TCPAddr)
|
||||
if !ok {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
|
||||
// Get IP Addr
|
||||
ipm, err := FromIPAndZone(ac.IP, ac.Zone)
|
||||
if err != nil {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
|
||||
// Get TCP Addr
|
||||
tcpm, err := ma.NewMultiaddr(fmt.Sprintf("/tcp/%d", ac.Port))
|
||||
if err != nil {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
|
||||
// Encapsulate
|
||||
return ipm.Encapsulate(tcpm), nil
|
||||
}
|
||||
|
||||
func parseUDPNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
ac, ok := a.(*net.UDPAddr)
|
||||
if !ok {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
|
||||
// Get IP Addr
|
||||
ipm, err := FromIPAndZone(ac.IP, ac.Zone)
|
||||
if err != nil {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
|
||||
// Get UDP Addr
|
||||
udpm, err := ma.NewMultiaddr(fmt.Sprintf("/udp/%d", ac.Port))
|
||||
if err != nil {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
|
||||
// Encapsulate
|
||||
return ipm.Encapsulate(udpm), nil
|
||||
}
|
||||
|
||||
func parseIPNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
ac, ok := a.(*net.IPAddr)
|
||||
if !ok {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
return FromIPAndZone(ac.IP, ac.Zone)
|
||||
}
|
||||
|
||||
func parseIPPlusNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
ac, ok := a.(*net.IPNet)
|
||||
if !ok {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
return FromIP(ac.IP)
|
||||
}
|
||||
|
||||
func parseUnixNetAddr(a net.Addr) (ma.Multiaddr, error) {
|
||||
ac, ok := a.(*net.UnixAddr)
|
||||
if !ok {
|
||||
return nil, errIncorrectNetAddr
|
||||
}
|
||||
|
||||
path := ac.Name
|
||||
if runtime.GOOS == "windows" {
|
||||
// Convert c:\foobar\... to c:/foobar/...
|
||||
path = filepath.ToSlash(path)
|
||||
}
|
||||
if len(path) == 0 || path[0] != '/' {
|
||||
// convert "" and "c:/..." to "/..."
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
return ma.NewComponent("unix", path)
|
||||
}
|
||||
5
vendor/github.com/multiformats/go-multiaddr/net/doc.go
generated
vendored
Normal file
5
vendor/github.com/multiformats/go-multiaddr/net/doc.go
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// Package manet provides Multiaddr specific versions of common
|
||||
// functions in stdlib's net package. This means wrappers of
|
||||
// standard net symbols like net.Dial and net.Listen, as well
|
||||
// as conversion to/from net.Addr.
|
||||
package manet
|
||||
136
vendor/github.com/multiformats/go-multiaddr/net/ip.go
generated
vendored
Normal file
136
vendor/github.com/multiformats/go-multiaddr/net/ip.go
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
package manet
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Loopback Addresses
|
||||
var (
|
||||
// IP4Loopback is the ip4 loopback multiaddr
|
||||
IP4Loopback = ma.StringCast("/ip4/127.0.0.1")
|
||||
|
||||
// IP6Loopback is the ip6 loopback multiaddr
|
||||
IP6Loopback = ma.StringCast("/ip6/::1")
|
||||
|
||||
// IP4MappedIP6Loopback is the IPv4 Mapped IPv6 loopback address.
|
||||
IP4MappedIP6Loopback = ma.StringCast("/ip6/::ffff:127.0.0.1")
|
||||
)
|
||||
|
||||
// Unspecified Addresses (used for )
|
||||
var (
|
||||
IP4Unspecified = ma.StringCast("/ip4/0.0.0.0")
|
||||
IP6Unspecified = ma.StringCast("/ip6/::")
|
||||
)
|
||||
|
||||
// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols.
|
||||
// This means: /{IP4, IP6}[/{TCP, UDP}]
|
||||
func IsThinWaist(m ma.Multiaddr) bool {
|
||||
m = zoneless(m)
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
p := m.Protocols()
|
||||
|
||||
// nothing? not even a waist.
|
||||
if len(p) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 {
|
||||
return false
|
||||
}
|
||||
|
||||
// only IP? still counts.
|
||||
if len(p) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
switch p[1].Code {
|
||||
case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// IsIPLoopback returns whether a Multiaddr starts with a "Loopback" IP address
|
||||
// This means either /ip4/127.*.*.*/*, /ip6/::1/*, or /ip6/::ffff:127.*.*.*.*/*,
|
||||
// or /ip6zone/<any value>/ip6/<one of the preceding ip6 values>/*
|
||||
func IsIPLoopback(m ma.Multiaddr) bool {
|
||||
m = zoneless(m)
|
||||
c, _ := ma.SplitFirst(m)
|
||||
if c == nil {
|
||||
return false
|
||||
}
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_IP4, ma.P_IP6:
|
||||
return net.IP(c.RawValue()).IsLoopback()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsIP6LinkLocal returns whether a Multiaddr starts with an IPv6 link-local
|
||||
// multiaddress (with zero or one leading zone). These addresses are non
|
||||
// routable.
|
||||
func IsIP6LinkLocal(m ma.Multiaddr) bool {
|
||||
m = zoneless(m)
|
||||
c, _ := ma.SplitFirst(m)
|
||||
if c == nil || c.Protocol().Code != ma.P_IP6 {
|
||||
return false
|
||||
}
|
||||
ip := net.IP(c.RawValue())
|
||||
return ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast()
|
||||
}
|
||||
|
||||
// IsIPUnspecified returns whether a Multiaddr starts with an Unspecified IP address
|
||||
// This means either /ip4/0.0.0.0/* or /ip6/::/*
|
||||
func IsIPUnspecified(m ma.Multiaddr) bool {
|
||||
m = zoneless(m)
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
c, _ := ma.SplitFirst(m)
|
||||
return net.IP(c.RawValue()).IsUnspecified()
|
||||
}
|
||||
|
||||
// If m matches [zone,ip6,...], return [ip6,...]
|
||||
// else if m matches [], [zone], or [zone,...], return nil
|
||||
// else return m
|
||||
func zoneless(m ma.Multiaddr) ma.Multiaddr {
|
||||
head, tail := ma.SplitFirst(m)
|
||||
if head == nil {
|
||||
return nil
|
||||
}
|
||||
if head.Protocol().Code == ma.P_IP6ZONE {
|
||||
if tail == nil {
|
||||
return nil
|
||||
}
|
||||
tailhead, _ := ma.SplitFirst(tail)
|
||||
if tailhead.Protocol().Code != ma.P_IP6 {
|
||||
return nil
|
||||
}
|
||||
return tail
|
||||
} else {
|
||||
return m
|
||||
}
|
||||
}
|
||||
|
||||
var nat64WellKnownPrefix net.IPNet
|
||||
|
||||
func init() {
|
||||
_, np, err := net.ParseCIDR("64:ff9b::/96")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nat64WellKnownPrefix = *np
|
||||
}
|
||||
|
||||
// IsNAT64IPv4ConvertedIPv6Addr returns whether addr is a well-known prefix "64:ff9b::/96" addr
|
||||
// used for NAT64 Translation. See RFC 6052
|
||||
func IsNAT64IPv4ConvertedIPv6Addr(addr ma.Multiaddr) bool {
|
||||
c, _ := ma.SplitFirst(addr)
|
||||
return c != nil && c.Protocol().Code == ma.P_IP6 &&
|
||||
nat64WellKnownPrefix.Contains(net.IP(c.RawValue()))
|
||||
}
|
||||
430
vendor/github.com/multiformats/go-multiaddr/net/net.go
generated
vendored
Normal file
430
vendor/github.com/multiformats/go-multiaddr/net/net.go
generated
vendored
Normal file
@@ -0,0 +1,430 @@
|
||||
// Package manet provides Multiaddr
|
||||
// (https://github.com/multiformats/go-multiaddr) specific versions of common
|
||||
// functions in Go's standard `net` package. This means wrappers of standard
|
||||
// net symbols like `net.Dial` and `net.Listen`, as well as conversion to
|
||||
// and from `net.Addr`.
|
||||
package manet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Conn is the equivalent of a net.Conn object. It is the
|
||||
// result of calling the Dial or Listen functions in this
|
||||
// package, with associated local and remote Multiaddrs.
|
||||
type Conn interface {
|
||||
net.Conn
|
||||
|
||||
// LocalMultiaddr returns the local Multiaddr associated
|
||||
// with this connection
|
||||
LocalMultiaddr() ma.Multiaddr
|
||||
|
||||
// RemoteMultiaddr returns the remote Multiaddr associated
|
||||
// with this connection
|
||||
RemoteMultiaddr() ma.Multiaddr
|
||||
}
|
||||
|
||||
type halfOpen interface {
|
||||
net.Conn
|
||||
CloseRead() error
|
||||
CloseWrite() error
|
||||
}
|
||||
|
||||
func wrap(nconn net.Conn, laddr, raddr ma.Multiaddr) Conn {
|
||||
endpts := maEndpoints{
|
||||
laddr: laddr,
|
||||
raddr: raddr,
|
||||
}
|
||||
// This sucks. However, it's the only way to reliably expose the
|
||||
// underlying methods. This way, users that need access to, e.g.,
|
||||
// CloseRead and CloseWrite, can do so via type assertions.
|
||||
switch nconn := nconn.(type) {
|
||||
case *net.TCPConn:
|
||||
return &struct {
|
||||
*net.TCPConn
|
||||
maEndpoints
|
||||
}{nconn, endpts}
|
||||
case *net.UDPConn:
|
||||
return &struct {
|
||||
*net.UDPConn
|
||||
maEndpoints
|
||||
}{nconn, endpts}
|
||||
case *net.IPConn:
|
||||
return &struct {
|
||||
*net.IPConn
|
||||
maEndpoints
|
||||
}{nconn, endpts}
|
||||
case *net.UnixConn:
|
||||
return &struct {
|
||||
*net.UnixConn
|
||||
maEndpoints
|
||||
}{nconn, endpts}
|
||||
case halfOpen:
|
||||
return &struct {
|
||||
halfOpen
|
||||
maEndpoints
|
||||
}{nconn, endpts}
|
||||
default:
|
||||
return &struct {
|
||||
net.Conn
|
||||
maEndpoints
|
||||
}{nconn, endpts}
|
||||
}
|
||||
}
|
||||
|
||||
// WrapNetConn wraps a net.Conn object with a Multiaddr friendly Conn.
|
||||
//
|
||||
// This function does it's best to avoid "hiding" methods exposed by the wrapped
|
||||
// type. Guarantees:
|
||||
//
|
||||
// - If the wrapped connection exposes the "half-open" closer methods
|
||||
// (CloseWrite, CloseRead), these will be available on the wrapped connection
|
||||
// via type assertions.
|
||||
// - If the wrapped connection is a UnixConn, IPConn, TCPConn, or UDPConn, all
|
||||
// methods on these wrapped connections will be available via type assertions.
|
||||
func WrapNetConn(nconn net.Conn) (Conn, error) {
|
||||
if nconn == nil {
|
||||
return nil, fmt.Errorf("failed to convert nconn.LocalAddr: nil")
|
||||
}
|
||||
|
||||
laddr, err := FromNetAddr(nconn.LocalAddr())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert nconn.LocalAddr: %s", err)
|
||||
}
|
||||
|
||||
raddr, err := FromNetAddr(nconn.RemoteAddr())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert nconn.RemoteAddr: %s", err)
|
||||
}
|
||||
|
||||
return wrap(nconn, laddr, raddr), nil
|
||||
}
|
||||
|
||||
type maEndpoints struct {
|
||||
laddr ma.Multiaddr
|
||||
raddr ma.Multiaddr
|
||||
}
|
||||
|
||||
// LocalMultiaddr returns the local address associated with
|
||||
// this connection
|
||||
func (c *maEndpoints) LocalMultiaddr() ma.Multiaddr {
|
||||
return c.laddr
|
||||
}
|
||||
|
||||
// RemoteMultiaddr returns the remote address associated with
|
||||
// this connection
|
||||
func (c *maEndpoints) RemoteMultiaddr() ma.Multiaddr {
|
||||
return c.raddr
|
||||
}
|
||||
|
||||
// Dialer contains options for connecting to an address. It
|
||||
// is effectively the same as net.Dialer, but its LocalAddr
|
||||
// and RemoteAddr options are Multiaddrs, instead of net.Addrs.
|
||||
type Dialer struct {
|
||||
|
||||
// Dialer is just an embedded net.Dialer, with all its options.
|
||||
net.Dialer
|
||||
|
||||
// LocalAddr is the local address to use when dialing an
|
||||
// address. The address must be of a compatible type for the
|
||||
// network being dialed.
|
||||
// If nil, a local address is automatically chosen.
|
||||
LocalAddr ma.Multiaddr
|
||||
}
|
||||
|
||||
// Dial connects to a remote address, using the options of the
|
||||
// Dialer. Dialer uses an underlying net.Dialer to Dial a
|
||||
// net.Conn, then wraps that in a Conn object (with local and
|
||||
// remote Multiaddrs).
|
||||
func (d *Dialer) Dial(remote ma.Multiaddr) (Conn, error) {
|
||||
return d.DialContext(context.Background(), remote)
|
||||
}
|
||||
|
||||
// DialContext allows to provide a custom context to Dial().
|
||||
func (d *Dialer) DialContext(ctx context.Context, remote ma.Multiaddr) (Conn, error) {
|
||||
// if a LocalAddr is specified, use it on the embedded dialer.
|
||||
if d.LocalAddr != nil {
|
||||
// convert our multiaddr to net.Addr friendly
|
||||
naddr, err := ToNetAddr(d.LocalAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// set the dialer's LocalAddr as naddr
|
||||
d.Dialer.LocalAddr = naddr
|
||||
}
|
||||
|
||||
// get the net.Dial friendly arguments from the remote addr
|
||||
rnet, rnaddr, err := DialArgs(remote)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ok, Dial!
|
||||
var nconn net.Conn
|
||||
switch rnet {
|
||||
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "unix":
|
||||
nconn, err = d.Dialer.DialContext(ctx, rnet, rnaddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized network: %s", rnet)
|
||||
}
|
||||
|
||||
// get local address (pre-specified or assigned within net.Conn)
|
||||
local := d.LocalAddr
|
||||
// This block helps us avoid parsing addresses in transports (such as unix
|
||||
// sockets) that don't have local addresses when dialing out.
|
||||
if local == nil && nconn.LocalAddr().String() != "" {
|
||||
local, err = FromNetAddr(nconn.LocalAddr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return wrap(nconn, local, remote), nil
|
||||
}
|
||||
|
||||
// Dial connects to a remote address. It uses an underlying net.Conn,
|
||||
// then wraps it in a Conn object (with local and remote Multiaddrs).
|
||||
func Dial(remote ma.Multiaddr) (Conn, error) {
|
||||
return (&Dialer{}).Dial(remote)
|
||||
}
|
||||
|
||||
// A Listener is a generic network listener for stream-oriented protocols.
|
||||
// it uses an embedded net.Listener, overriding net.Listener.Accept to
|
||||
// return a Conn and providing Multiaddr.
|
||||
type Listener interface {
|
||||
// Accept waits for and returns the next connection to the listener.
|
||||
// Returns a Multiaddr friendly Conn
|
||||
Accept() (Conn, error)
|
||||
|
||||
// Close closes the listener.
|
||||
// Any blocked Accept operations will be unblocked and return errors.
|
||||
Close() error
|
||||
|
||||
// Multiaddr returns the listener's (local) Multiaddr.
|
||||
Multiaddr() ma.Multiaddr
|
||||
|
||||
// Addr returns the net.Listener's network address.
|
||||
Addr() net.Addr
|
||||
}
|
||||
|
||||
type netListenerAdapter struct {
|
||||
Listener
|
||||
}
|
||||
|
||||
func (nla *netListenerAdapter) Accept() (net.Conn, error) {
|
||||
return nla.Listener.Accept()
|
||||
}
|
||||
|
||||
// NetListener turns this Listener into a net.Listener.
|
||||
//
|
||||
// - Connections returned from Accept implement multiaddr/net Conn.
|
||||
// - Calling WrapNetListener on the net.Listener returned by this function will
|
||||
// return the original (underlying) multiaddr/net Listener.
|
||||
func NetListener(l Listener) net.Listener {
|
||||
return &netListenerAdapter{l}
|
||||
}
|
||||
|
||||
// maListener implements Listener
|
||||
type maListener struct {
|
||||
net.Listener
|
||||
laddr ma.Multiaddr
|
||||
}
|
||||
|
||||
// Accept waits for and returns the next connection to the listener.
|
||||
// Returns a Multiaddr friendly Conn
|
||||
func (l *maListener) Accept() (Conn, error) {
|
||||
nconn, err := l.Listener.Accept()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var raddr ma.Multiaddr
|
||||
// This block protects us in transports (i.e. unix sockets) that don't have
|
||||
// remote addresses for inbound connections.
|
||||
if addr := nconn.RemoteAddr(); addr != nil && addr.String() != "" {
|
||||
raddr, err = FromNetAddr(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert conn.RemoteAddr: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
var laddr ma.Multiaddr
|
||||
if addr := nconn.LocalAddr(); addr != nil && addr.String() != "" {
|
||||
laddr, err = FromNetAddr(addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert conn.LocalAddr: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return wrap(nconn, laddr, raddr), nil
|
||||
}
|
||||
|
||||
// Multiaddr returns the listener's (local) Multiaddr.
|
||||
func (l *maListener) Multiaddr() ma.Multiaddr {
|
||||
return l.laddr
|
||||
}
|
||||
|
||||
// Addr returns the listener's network address.
|
||||
func (l *maListener) Addr() net.Addr {
|
||||
return l.Listener.Addr()
|
||||
}
|
||||
|
||||
// Listen announces on the local network address laddr.
|
||||
// The Multiaddr must be a "ThinWaist" stream-oriented network:
|
||||
// ip4/tcp, ip6/tcp, (TODO: unix, unixpacket)
|
||||
// See Dial for the syntax of laddr.
|
||||
func Listen(laddr ma.Multiaddr) (Listener, error) {
|
||||
|
||||
// get the net.Listen friendly arguments from the remote addr
|
||||
lnet, lnaddr, err := DialArgs(laddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nl, err := net.Listen(lnet, lnaddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// we want to fetch the new multiaddr from the listener, as it may
|
||||
// have resolved to some other value. WrapNetListener does it for us.
|
||||
return WrapNetListener(nl)
|
||||
}
|
||||
|
||||
// WrapNetListener wraps a net.Listener with a manet.Listener.
|
||||
func WrapNetListener(nl net.Listener) (Listener, error) {
|
||||
if nla, ok := nl.(*netListenerAdapter); ok {
|
||||
return nla.Listener, nil
|
||||
}
|
||||
|
||||
laddr, err := FromNetAddr(nl.Addr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &maListener{
|
||||
Listener: nl,
|
||||
laddr: laddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// A PacketConn is a generic packet oriented network connection which uses an
|
||||
// underlying net.PacketConn, wrapped with the locally bound Multiaddr.
|
||||
type PacketConn interface {
|
||||
net.PacketConn
|
||||
|
||||
LocalMultiaddr() ma.Multiaddr
|
||||
|
||||
ReadFromMultiaddr(b []byte) (int, ma.Multiaddr, error)
|
||||
WriteToMultiaddr(b []byte, maddr ma.Multiaddr) (int, error)
|
||||
}
|
||||
|
||||
// maPacketConn implements PacketConn
|
||||
type maPacketConn struct {
|
||||
net.PacketConn
|
||||
laddr ma.Multiaddr
|
||||
}
|
||||
|
||||
var _ PacketConn = (*maPacketConn)(nil)
|
||||
|
||||
// LocalMultiaddr returns the bound local Multiaddr.
|
||||
func (l *maPacketConn) LocalMultiaddr() ma.Multiaddr {
|
||||
return l.laddr
|
||||
}
|
||||
|
||||
func (l *maPacketConn) ReadFromMultiaddr(b []byte) (int, ma.Multiaddr, error) {
|
||||
n, addr, err := l.ReadFrom(b)
|
||||
maddr, _ := FromNetAddr(addr)
|
||||
return n, maddr, err
|
||||
}
|
||||
|
||||
func (l *maPacketConn) WriteToMultiaddr(b []byte, maddr ma.Multiaddr) (int, error) {
|
||||
addr, err := ToNetAddr(maddr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return l.WriteTo(b, addr)
|
||||
}
|
||||
|
||||
// ListenPacket announces on the local network address laddr.
|
||||
// The Multiaddr must be a packet driven network, like udp4 or udp6.
|
||||
// See Dial for the syntax of laddr.
|
||||
func ListenPacket(laddr ma.Multiaddr) (PacketConn, error) {
|
||||
lnet, lnaddr, err := DialArgs(laddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pc, err := net.ListenPacket(lnet, lnaddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We want to fetch the new multiaddr from the listener, as it may
|
||||
// have resolved to some other value. WrapPacketConn does this.
|
||||
return WrapPacketConn(pc)
|
||||
}
|
||||
|
||||
// WrapPacketConn wraps a net.PacketConn with a manet.PacketConn.
|
||||
func WrapPacketConn(pc net.PacketConn) (PacketConn, error) {
|
||||
laddr, err := FromNetAddr(pc.LocalAddr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &maPacketConn{
|
||||
PacketConn: pc,
|
||||
laddr: laddr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs
|
||||
func InterfaceMultiaddrs() ([]ma.Multiaddr, error) {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maddrs := make([]ma.Multiaddr, len(addrs))
|
||||
for i, a := range addrs {
|
||||
maddrs[i], err = FromNetAddr(a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return maddrs, nil
|
||||
}
|
||||
|
||||
// AddrMatch returns the Multiaddrs that match the protocol stack on addr
|
||||
func AddrMatch(match ma.Multiaddr, addrs []ma.Multiaddr) []ma.Multiaddr {
|
||||
|
||||
// we should match transports entirely.
|
||||
p1s := match.Protocols()
|
||||
|
||||
out := make([]ma.Multiaddr, 0, len(addrs))
|
||||
for _, a := range addrs {
|
||||
p2s := a.Protocols()
|
||||
if len(p1s) != len(p2s) {
|
||||
continue
|
||||
}
|
||||
|
||||
match := true
|
||||
for i, p2 := range p2s {
|
||||
if p1s[i].Code != p2.Code {
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if match {
|
||||
out = append(out, a)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
177
vendor/github.com/multiformats/go-multiaddr/net/private.go
generated
vendored
Normal file
177
vendor/github.com/multiformats/go-multiaddr/net/private.go
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
package manet
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// Private4 and Private6 are well-known private networks
|
||||
var Private4, Private6 []*net.IPNet
|
||||
var privateCIDR4 = []string{
|
||||
// localhost
|
||||
"127.0.0.0/8",
|
||||
// private networks
|
||||
"10.0.0.0/8",
|
||||
"100.64.0.0/10",
|
||||
"172.16.0.0/12",
|
||||
"192.168.0.0/16",
|
||||
// link local
|
||||
"169.254.0.0/16",
|
||||
}
|
||||
var privateCIDR6 = []string{
|
||||
// localhost
|
||||
"::1/128",
|
||||
// ULA reserved
|
||||
"fc00::/7",
|
||||
// link local
|
||||
"fe80::/10",
|
||||
}
|
||||
|
||||
// Unroutable4 and Unroutable6 are well known unroutable address ranges
|
||||
var Unroutable4, Unroutable6 []*net.IPNet
|
||||
var unroutableCIDR4 = []string{
|
||||
"0.0.0.0/8",
|
||||
"192.0.0.0/26",
|
||||
"192.0.2.0/24",
|
||||
"192.88.99.0/24",
|
||||
"198.18.0.0/15",
|
||||
"198.51.100.0/24",
|
||||
"203.0.113.0/24",
|
||||
"224.0.0.0/4",
|
||||
"240.0.0.0/4",
|
||||
"255.255.255.255/32",
|
||||
}
|
||||
var unroutableCIDR6 = []string{
|
||||
"ff00::/8",
|
||||
}
|
||||
|
||||
// unResolvableDomains do not resolve to an IP address.
|
||||
// Ref: https://en.wikipedia.org/wiki/Special-use_domain_name#Reserved_domain_names
|
||||
var unResolvableDomains = []string{
|
||||
// Reverse DNS Lookup
|
||||
".in-addr.arpa",
|
||||
".ip6.arpa",
|
||||
|
||||
// RFC 6761: Users MAY assume that queries for "invalid" names will always return NXDOMAIN
|
||||
// responses
|
||||
".invalid",
|
||||
}
|
||||
|
||||
// privateUseDomains are reserved for private use and have no central authority for consistent
|
||||
// address resolution
|
||||
// Ref: https://en.wikipedia.org/wiki/Special-use_domain_name#Reserved_domain_names
|
||||
var privateUseDomains = []string{
|
||||
// RFC 8375: Reserved for home networks
|
||||
".home.arpa",
|
||||
|
||||
// MDNS
|
||||
".local",
|
||||
|
||||
// RFC 6761: No central authority for .test names
|
||||
".test",
|
||||
}
|
||||
|
||||
// RFC 6761: Users may assume that IPv4 and IPv6 address queries for localhost names will
|
||||
// always resolve to the respective IP loopback address
|
||||
const localHostDomain = ".localhost"
|
||||
|
||||
func init() {
|
||||
Private4 = parseCIDR(privateCIDR4)
|
||||
Private6 = parseCIDR(privateCIDR6)
|
||||
Unroutable4 = parseCIDR(unroutableCIDR4)
|
||||
Unroutable6 = parseCIDR(unroutableCIDR6)
|
||||
}
|
||||
|
||||
func parseCIDR(cidrs []string) []*net.IPNet {
|
||||
ipnets := make([]*net.IPNet, len(cidrs))
|
||||
for i, cidr := range cidrs {
|
||||
_, ipnet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ipnets[i] = ipnet
|
||||
}
|
||||
return ipnets
|
||||
}
|
||||
|
||||
// IsPublicAddr returns true if the IP part of the multiaddr is a publicly routable address
|
||||
// or if it's a dns address without a special use domain e.g. .local.
|
||||
func IsPublicAddr(a ma.Multiaddr) bool {
|
||||
isPublic := false
|
||||
ma.ForEach(a, func(c ma.Component) bool {
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_IP6ZONE:
|
||||
return true
|
||||
case ma.P_IP4:
|
||||
ip := net.IP(c.RawValue())
|
||||
isPublic = !inAddrRange(ip, Private4) && !inAddrRange(ip, Unroutable4)
|
||||
case ma.P_IP6:
|
||||
ip := net.IP(c.RawValue())
|
||||
isPublic = !inAddrRange(ip, Private6) && !inAddrRange(ip, Unroutable6)
|
||||
case ma.P_DNS, ma.P_DNS4, ma.P_DNS6, ma.P_DNSADDR:
|
||||
dnsAddr := c.Value()
|
||||
isPublic = true
|
||||
if isSubdomain(dnsAddr, localHostDomain) {
|
||||
isPublic = false
|
||||
return false
|
||||
}
|
||||
for _, ud := range unResolvableDomains {
|
||||
if isSubdomain(dnsAddr, ud) {
|
||||
isPublic = false
|
||||
return false
|
||||
}
|
||||
}
|
||||
for _, pd := range privateUseDomains {
|
||||
if isSubdomain(dnsAddr, pd) {
|
||||
isPublic = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
return isPublic
|
||||
}
|
||||
|
||||
// isSubdomain checks if child is sub domain of parent. It also returns true if child and parent are
|
||||
// the same domain.
|
||||
// Parent must have a "." prefix.
|
||||
func isSubdomain(child, parent string) bool {
|
||||
return strings.HasSuffix(child, parent) || child == parent[1:]
|
||||
}
|
||||
|
||||
// IsPrivateAddr returns true if the IP part of the mutiaddr is in a private network
|
||||
func IsPrivateAddr(a ma.Multiaddr) bool {
|
||||
isPrivate := false
|
||||
ma.ForEach(a, func(c ma.Component) bool {
|
||||
switch c.Protocol().Code {
|
||||
case ma.P_IP6ZONE:
|
||||
return true
|
||||
case ma.P_IP4:
|
||||
isPrivate = inAddrRange(net.IP(c.RawValue()), Private4)
|
||||
case ma.P_IP6:
|
||||
isPrivate = inAddrRange(net.IP(c.RawValue()), Private6)
|
||||
case ma.P_DNS, ma.P_DNS4, ma.P_DNS6, ma.P_DNSADDR:
|
||||
dnsAddr := c.Value()
|
||||
if isSubdomain(dnsAddr, localHostDomain) {
|
||||
isPrivate = true
|
||||
}
|
||||
// We don't check for privateUseDomains because private use domains can
|
||||
// resolve to public IP addresses
|
||||
}
|
||||
return false
|
||||
})
|
||||
return isPrivate
|
||||
}
|
||||
|
||||
func inAddrRange(ip net.IP, ipnets []*net.IPNet) bool {
|
||||
for _, ipnet := range ipnets {
|
||||
if ipnet.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
97
vendor/github.com/multiformats/go-multiaddr/net/registry.go
generated
vendored
Normal file
97
vendor/github.com/multiformats/go-multiaddr/net/registry.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
package manet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// FromNetAddrFunc is a generic function which converts a net.Addr to Multiaddress
|
||||
type FromNetAddrFunc func(a net.Addr) (ma.Multiaddr, error)
|
||||
|
||||
// ToNetAddrFunc is a generic function which converts a Multiaddress to net.Addr
|
||||
type ToNetAddrFunc func(ma ma.Multiaddr) (net.Addr, error)
|
||||
|
||||
var defaultCodecs = NewCodecMap()
|
||||
|
||||
func init() {
|
||||
RegisterFromNetAddr(parseTCPNetAddr, "tcp", "tcp4", "tcp6")
|
||||
RegisterFromNetAddr(parseUDPNetAddr, "udp", "udp4", "udp6")
|
||||
RegisterFromNetAddr(parseIPNetAddr, "ip", "ip4", "ip6")
|
||||
RegisterFromNetAddr(parseIPPlusNetAddr, "ip+net")
|
||||
RegisterFromNetAddr(parseUnixNetAddr, "unix")
|
||||
|
||||
RegisterToNetAddr(parseBasicNetMaddr, "tcp", "udp", "ip6", "ip4", "unix")
|
||||
}
|
||||
|
||||
// CodecMap holds a map of NetCodecs indexed by their Protocol ID
|
||||
// along with parsers for the addresses they use.
|
||||
// It is used to keep a list of supported network address codecs (protocols
|
||||
// which addresses can be converted to and from multiaddresses).
|
||||
type CodecMap struct {
|
||||
addrParsers map[string]FromNetAddrFunc
|
||||
maddrParsers map[string]ToNetAddrFunc
|
||||
lk sync.Mutex
|
||||
}
|
||||
|
||||
// NewCodecMap initializes and returns a CodecMap object.
|
||||
func NewCodecMap() *CodecMap {
|
||||
return &CodecMap{
|
||||
addrParsers: make(map[string]FromNetAddrFunc),
|
||||
maddrParsers: make(map[string]ToNetAddrFunc),
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterFromNetAddr registers a conversion from net.Addr instances to multiaddrs.
|
||||
func RegisterFromNetAddr(from FromNetAddrFunc, networks ...string) {
|
||||
defaultCodecs.RegisterFromNetAddr(from, networks...)
|
||||
}
|
||||
|
||||
// RegisterToNetAddr registers a conversion from multiaddrs to net.Addr instances.
|
||||
func RegisterToNetAddr(to ToNetAddrFunc, protocols ...string) {
|
||||
defaultCodecs.RegisterToNetAddr(to, protocols...)
|
||||
}
|
||||
|
||||
// RegisterFromNetAddr registers a conversion from net.Addr instances to multiaddrs
|
||||
func (cm *CodecMap) RegisterFromNetAddr(from FromNetAddrFunc, networks ...string) {
|
||||
cm.lk.Lock()
|
||||
defer cm.lk.Unlock()
|
||||
|
||||
for _, n := range networks {
|
||||
cm.addrParsers[n] = from
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterToNetAddr registers a conversion from multiaddrs to net.Addr instances
|
||||
func (cm *CodecMap) RegisterToNetAddr(to ToNetAddrFunc, protocols ...string) {
|
||||
cm.lk.Lock()
|
||||
defer cm.lk.Unlock()
|
||||
|
||||
for _, p := range protocols {
|
||||
cm.maddrParsers[p] = to
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *CodecMap) getAddrParser(net string) (FromNetAddrFunc, error) {
|
||||
cm.lk.Lock()
|
||||
defer cm.lk.Unlock()
|
||||
|
||||
parser, ok := cm.addrParsers[net]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown network %v", net)
|
||||
}
|
||||
return parser, nil
|
||||
}
|
||||
|
||||
func (cm *CodecMap) getMaddrParser(name string) (ToNetAddrFunc, error) {
|
||||
cm.lk.Lock()
|
||||
defer cm.lk.Unlock()
|
||||
p, ok := cm.maddrParsers[name]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("network not supported: %s", name)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
83
vendor/github.com/multiformats/go-multiaddr/net/resolve.go
generated
vendored
Normal file
83
vendor/github.com/multiformats/go-multiaddr/net/resolve.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package manet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||
// use the known local interfaces. If ifaceAddr is nil, we request interface addresses
|
||||
// from the network stack. (this is so you can provide a cached value if resolving many addrs)
|
||||
func ResolveUnspecifiedAddress(resolve ma.Multiaddr, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
||||
// split address into its components
|
||||
split := ma.Split(resolve)
|
||||
|
||||
// if first component (ip) is not unspecified, use it as is.
|
||||
if !IsIPUnspecified(split[0]) {
|
||||
return []ma.Multiaddr{resolve}, nil
|
||||
}
|
||||
|
||||
out := make([]ma.Multiaddr, 0, len(ifaceAddrs))
|
||||
for _, ia := range ifaceAddrs {
|
||||
// must match the first protocol to be resolve.
|
||||
if ia.Protocols()[0].Code != resolve.Protocols()[0].Code {
|
||||
continue
|
||||
}
|
||||
|
||||
split[0] = ia
|
||||
joined := ma.Join(split...)
|
||||
out = append(out, joined)
|
||||
}
|
||||
if len(out) < 1 {
|
||||
return nil, fmt.Errorf("failed to resolve: %s", resolve)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ResolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
|
||||
// use the known local interfaces.
|
||||
func ResolveUnspecifiedAddresses(unspecAddrs, ifaceAddrs []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
||||
// todo optimize: only fetch these if we have a "any" addr.
|
||||
if len(ifaceAddrs) < 1 {
|
||||
var err error
|
||||
ifaceAddrs, err = interfaceAddresses()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var outputAddrs []ma.Multiaddr
|
||||
for _, a := range unspecAddrs {
|
||||
// unspecified?
|
||||
resolved, err := ResolveUnspecifiedAddress(a, ifaceAddrs)
|
||||
if err != nil {
|
||||
continue // optimistic. if we can't resolve anything, we'll know at the bottom.
|
||||
}
|
||||
outputAddrs = append(outputAddrs, resolved...)
|
||||
}
|
||||
|
||||
if len(outputAddrs) < 1 {
|
||||
return nil, fmt.Errorf("failed to specify addrs: %s", unspecAddrs)
|
||||
}
|
||||
return outputAddrs, nil
|
||||
}
|
||||
|
||||
// interfaceAddresses returns a list of addresses associated with local machine
|
||||
// Note: we do not return link local addresses. IP loopback is ok, because we
|
||||
// may be connecting to other nodes in the same machine.
|
||||
func interfaceAddresses() ([]ma.Multiaddr, error) {
|
||||
maddrs, err := InterfaceMultiaddrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out []ma.Multiaddr
|
||||
for _, a := range maddrs {
|
||||
if IsIP6LinkLocal(a) {
|
||||
continue
|
||||
}
|
||||
out = append(out, a)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
23
vendor/github.com/multiformats/go-multiaddr/package.json
generated
vendored
Normal file
23
vendor/github.com/multiformats/go-multiaddr/package.json
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"author": "multiformats",
|
||||
"bugs": {
|
||||
"url": "https://github.com/multiformats/go-multiaddr/issues"
|
||||
},
|
||||
"gx": {
|
||||
"dvcsimport": "github.com/multiformats/go-multiaddr"
|
||||
},
|
||||
"gxDependencies": [
|
||||
{
|
||||
"hash": "QmerPMzPk1mJVowm8KgmoknWa4yCYvvugMPsgWmDNUvDLW",
|
||||
"name": "go-multihash",
|
||||
"version": "1.0.9"
|
||||
}
|
||||
],
|
||||
"gxVersion": "0.9.0",
|
||||
"language": "go",
|
||||
"license": "MIT",
|
||||
"name": "go-multiaddr",
|
||||
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
|
||||
"version": "1.4.1"
|
||||
}
|
||||
|
||||
102
vendor/github.com/multiformats/go-multiaddr/protocol.go
generated
vendored
Normal file
102
vendor/github.com/multiformats/go-multiaddr/protocol.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// These are special sizes
|
||||
const (
|
||||
LengthPrefixedVarSize = -1
|
||||
)
|
||||
|
||||
// Protocol is a Multiaddr protocol description structure.
|
||||
type Protocol struct {
|
||||
// Name is the string representation of the protocol code. E.g., ip4,
|
||||
// ip6, tcp, udp, etc.
|
||||
Name string
|
||||
|
||||
// Code is the protocol's multicodec (a normal, non-varint number).
|
||||
Code int
|
||||
|
||||
// VCode is a precomputed varint encoded version of Code.
|
||||
VCode []byte
|
||||
|
||||
// Size is the size of the argument to this protocol.
|
||||
//
|
||||
// * Size == 0 means this protocol takes no argument.
|
||||
// * Size > 0 means this protocol takes a constant sized argument.
|
||||
// * Size < 0 means this protocol takes a variable length, varint
|
||||
// prefixed argument.
|
||||
Size int // a size of -1 indicates a length-prefixed variable size
|
||||
|
||||
// Path indicates a path protocol (e.g., unix). When parsing multiaddr
|
||||
// strings, path protocols consume the remainder of the address instead
|
||||
// of stopping at the next forward slash.
|
||||
//
|
||||
// Size must be LengthPrefixedVarSize.
|
||||
Path bool
|
||||
|
||||
// Transcoder converts between the byte representation and the string
|
||||
// representation of this protocol's argument (if any).
|
||||
//
|
||||
// This should only be non-nil if Size != 0
|
||||
Transcoder Transcoder
|
||||
}
|
||||
|
||||
var protocolsByName = map[string]Protocol{}
|
||||
var protocolsByCode = map[int]Protocol{}
|
||||
|
||||
// Protocols is the list of multiaddr protocols supported by this module.
|
||||
var Protocols = []Protocol{}
|
||||
|
||||
func AddProtocol(p Protocol) error {
|
||||
if _, ok := protocolsByName[p.Name]; ok {
|
||||
return fmt.Errorf("protocol by the name %q already exists", p.Name)
|
||||
}
|
||||
|
||||
if _, ok := protocolsByCode[p.Code]; ok {
|
||||
return fmt.Errorf("protocol code %d already taken by %q", p.Code, p.Code)
|
||||
}
|
||||
|
||||
if p.Size != 0 && p.Transcoder == nil {
|
||||
return fmt.Errorf("protocols with arguments must define transcoders")
|
||||
}
|
||||
if p.Path && p.Size >= 0 {
|
||||
return fmt.Errorf("path protocols must have variable-length sizes")
|
||||
}
|
||||
|
||||
Protocols = append(Protocols, p)
|
||||
protocolsByName[p.Name] = p
|
||||
protocolsByCode[p.Code] = p
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProtocolWithName returns the Protocol description with given string name.
|
||||
func ProtocolWithName(s string) Protocol {
|
||||
return protocolsByName[s]
|
||||
}
|
||||
|
||||
// ProtocolWithCode returns the Protocol description with given protocol code.
|
||||
func ProtocolWithCode(c int) Protocol {
|
||||
return protocolsByCode[c]
|
||||
}
|
||||
|
||||
// ProtocolsWithString returns a slice of protocols matching given string.
|
||||
func ProtocolsWithString(s string) ([]Protocol, error) {
|
||||
s = strings.Trim(s, "/")
|
||||
sp := strings.Split(s, "/")
|
||||
if len(sp) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
t := make([]Protocol, len(sp))
|
||||
for i, name := range sp {
|
||||
p := ProtocolWithName(name)
|
||||
if p.Code == 0 {
|
||||
return nil, fmt.Errorf("no protocol with name: %s", name)
|
||||
}
|
||||
t[i] = p
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
325
vendor/github.com/multiformats/go-multiaddr/protocols.go
generated
vendored
Normal file
325
vendor/github.com/multiformats/go-multiaddr/protocols.go
generated
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
package multiaddr
|
||||
|
||||
// You **MUST** register your multicodecs with
|
||||
// https://github.com/multiformats/multicodec before adding them here.
|
||||
const (
|
||||
P_IP4 = 4
|
||||
P_TCP = 6
|
||||
P_DNS = 53 // 4 or 6
|
||||
P_DNS4 = 54
|
||||
P_DNS6 = 55
|
||||
P_DNSADDR = 56
|
||||
P_UDP = 273
|
||||
P_DCCP = 33
|
||||
P_IP6 = 41
|
||||
P_IP6ZONE = 42
|
||||
P_IPCIDR = 43
|
||||
P_QUIC = 460
|
||||
P_QUIC_V1 = 461
|
||||
P_WEBTRANSPORT = 465
|
||||
P_CERTHASH = 466
|
||||
P_SCTP = 132
|
||||
P_CIRCUIT = 290
|
||||
P_UDT = 301
|
||||
P_UTP = 302
|
||||
P_UNIX = 400
|
||||
P_P2P = 421
|
||||
P_IPFS = P_P2P // alias for backwards compatibility
|
||||
P_HTTP = 480
|
||||
P_HTTPS = 443 // deprecated alias for /tls/http
|
||||
P_ONION = 444 // also for backwards compatibility
|
||||
P_ONION3 = 445
|
||||
P_GARLIC64 = 446
|
||||
P_GARLIC32 = 447
|
||||
P_P2P_WEBRTC_DIRECT = 276 // Deprecated. use webrtc-direct instead
|
||||
P_TLS = 448
|
||||
P_SNI = 449
|
||||
P_NOISE = 454
|
||||
P_WS = 477
|
||||
P_WSS = 478 // deprecated alias for /tls/ws
|
||||
P_PLAINTEXTV2 = 7367777
|
||||
P_WEBRTC_DIRECT = 280
|
||||
P_WEBRTC = 281
|
||||
)
|
||||
|
||||
var (
|
||||
protoIP4 = Protocol{
|
||||
Name: "ip4",
|
||||
Code: P_IP4,
|
||||
VCode: CodeToVarint(P_IP4),
|
||||
Size: 32,
|
||||
Path: false,
|
||||
Transcoder: TranscoderIP4,
|
||||
}
|
||||
protoTCP = Protocol{
|
||||
Name: "tcp",
|
||||
Code: P_TCP,
|
||||
VCode: CodeToVarint(P_TCP),
|
||||
Size: 16,
|
||||
Path: false,
|
||||
Transcoder: TranscoderPort,
|
||||
}
|
||||
protoDNS = Protocol{
|
||||
Code: P_DNS,
|
||||
Size: LengthPrefixedVarSize,
|
||||
Name: "dns",
|
||||
VCode: CodeToVarint(P_DNS),
|
||||
Transcoder: TranscoderDns,
|
||||
}
|
||||
protoDNS4 = Protocol{
|
||||
Code: P_DNS4,
|
||||
Size: LengthPrefixedVarSize,
|
||||
Name: "dns4",
|
||||
VCode: CodeToVarint(P_DNS4),
|
||||
Transcoder: TranscoderDns,
|
||||
}
|
||||
protoDNS6 = Protocol{
|
||||
Code: P_DNS6,
|
||||
Size: LengthPrefixedVarSize,
|
||||
Name: "dns6",
|
||||
VCode: CodeToVarint(P_DNS6),
|
||||
Transcoder: TranscoderDns,
|
||||
}
|
||||
protoDNSADDR = Protocol{
|
||||
Code: P_DNSADDR,
|
||||
Size: LengthPrefixedVarSize,
|
||||
Name: "dnsaddr",
|
||||
VCode: CodeToVarint(P_DNSADDR),
|
||||
Transcoder: TranscoderDns,
|
||||
}
|
||||
protoUDP = Protocol{
|
||||
Name: "udp",
|
||||
Code: P_UDP,
|
||||
VCode: CodeToVarint(P_UDP),
|
||||
Size: 16,
|
||||
Path: false,
|
||||
Transcoder: TranscoderPort,
|
||||
}
|
||||
protoDCCP = Protocol{
|
||||
Name: "dccp",
|
||||
Code: P_DCCP,
|
||||
VCode: CodeToVarint(P_DCCP),
|
||||
Size: 16,
|
||||
Path: false,
|
||||
Transcoder: TranscoderPort,
|
||||
}
|
||||
protoIP6 = Protocol{
|
||||
Name: "ip6",
|
||||
Code: P_IP6,
|
||||
VCode: CodeToVarint(P_IP6),
|
||||
Size: 128,
|
||||
Transcoder: TranscoderIP6,
|
||||
}
|
||||
protoIPCIDR = Protocol{
|
||||
Name: "ipcidr",
|
||||
Code: P_IPCIDR,
|
||||
VCode: CodeToVarint(P_IPCIDR),
|
||||
Size: 8,
|
||||
Transcoder: TranscoderIPCIDR,
|
||||
}
|
||||
// these require varint
|
||||
protoIP6ZONE = Protocol{
|
||||
Name: "ip6zone",
|
||||
Code: P_IP6ZONE,
|
||||
VCode: CodeToVarint(P_IP6ZONE),
|
||||
Size: LengthPrefixedVarSize,
|
||||
Path: false,
|
||||
Transcoder: TranscoderIP6Zone,
|
||||
}
|
||||
protoSCTP = Protocol{
|
||||
Name: "sctp",
|
||||
Code: P_SCTP,
|
||||
VCode: CodeToVarint(P_SCTP),
|
||||
Size: 16,
|
||||
Transcoder: TranscoderPort,
|
||||
}
|
||||
|
||||
protoCIRCUIT = Protocol{
|
||||
Code: P_CIRCUIT,
|
||||
Size: 0,
|
||||
Name: "p2p-circuit",
|
||||
VCode: CodeToVarint(P_CIRCUIT),
|
||||
}
|
||||
|
||||
protoONION2 = Protocol{
|
||||
Name: "onion",
|
||||
Code: P_ONION,
|
||||
VCode: CodeToVarint(P_ONION),
|
||||
Size: 96,
|
||||
Transcoder: TranscoderOnion,
|
||||
}
|
||||
protoONION3 = Protocol{
|
||||
Name: "onion3",
|
||||
Code: P_ONION3,
|
||||
VCode: CodeToVarint(P_ONION3),
|
||||
Size: 296,
|
||||
Transcoder: TranscoderOnion3,
|
||||
}
|
||||
protoGARLIC64 = Protocol{
|
||||
Name: "garlic64",
|
||||
Code: P_GARLIC64,
|
||||
VCode: CodeToVarint(P_GARLIC64),
|
||||
Size: LengthPrefixedVarSize,
|
||||
Transcoder: TranscoderGarlic64,
|
||||
}
|
||||
protoGARLIC32 = Protocol{
|
||||
Name: "garlic32",
|
||||
Code: P_GARLIC32,
|
||||
VCode: CodeToVarint(P_GARLIC32),
|
||||
Size: LengthPrefixedVarSize,
|
||||
Transcoder: TranscoderGarlic32,
|
||||
}
|
||||
protoUTP = Protocol{
|
||||
Name: "utp",
|
||||
Code: P_UTP,
|
||||
VCode: CodeToVarint(P_UTP),
|
||||
}
|
||||
protoUDT = Protocol{
|
||||
Name: "udt",
|
||||
Code: P_UDT,
|
||||
VCode: CodeToVarint(P_UDT),
|
||||
}
|
||||
protoQUIC = Protocol{
|
||||
Name: "quic",
|
||||
Code: P_QUIC,
|
||||
VCode: CodeToVarint(P_QUIC),
|
||||
}
|
||||
protoQUICV1 = Protocol{
|
||||
Name: "quic-v1",
|
||||
Code: P_QUIC_V1,
|
||||
VCode: CodeToVarint(P_QUIC_V1),
|
||||
}
|
||||
protoWEBTRANSPORT = Protocol{
|
||||
Name: "webtransport",
|
||||
Code: P_WEBTRANSPORT,
|
||||
VCode: CodeToVarint(P_WEBTRANSPORT),
|
||||
}
|
||||
protoCERTHASH = Protocol{
|
||||
Name: "certhash",
|
||||
Code: P_CERTHASH,
|
||||
VCode: CodeToVarint(P_CERTHASH),
|
||||
Size: LengthPrefixedVarSize,
|
||||
Transcoder: TranscoderCertHash,
|
||||
}
|
||||
protoHTTP = Protocol{
|
||||
Name: "http",
|
||||
Code: P_HTTP,
|
||||
VCode: CodeToVarint(P_HTTP),
|
||||
}
|
||||
protoHTTPS = Protocol{
|
||||
Name: "https",
|
||||
Code: P_HTTPS,
|
||||
VCode: CodeToVarint(P_HTTPS),
|
||||
}
|
||||
protoP2P = Protocol{
|
||||
Name: "p2p",
|
||||
Code: P_P2P,
|
||||
VCode: CodeToVarint(P_P2P),
|
||||
Size: LengthPrefixedVarSize,
|
||||
Transcoder: TranscoderP2P,
|
||||
}
|
||||
protoUNIX = Protocol{
|
||||
Name: "unix",
|
||||
Code: P_UNIX,
|
||||
VCode: CodeToVarint(P_UNIX),
|
||||
Size: LengthPrefixedVarSize,
|
||||
Path: true,
|
||||
Transcoder: TranscoderUnix,
|
||||
}
|
||||
protoP2P_WEBRTC_DIRECT = Protocol{
|
||||
Name: "p2p-webrtc-direct",
|
||||
Code: P_P2P_WEBRTC_DIRECT,
|
||||
VCode: CodeToVarint(P_P2P_WEBRTC_DIRECT),
|
||||
}
|
||||
protoTLS = Protocol{
|
||||
Name: "tls",
|
||||
Code: P_TLS,
|
||||
VCode: CodeToVarint(P_TLS),
|
||||
}
|
||||
protoSNI = Protocol{
|
||||
Name: "sni",
|
||||
Size: LengthPrefixedVarSize,
|
||||
Code: P_SNI,
|
||||
VCode: CodeToVarint(P_SNI),
|
||||
Transcoder: TranscoderDns,
|
||||
}
|
||||
protoNOISE = Protocol{
|
||||
Name: "noise",
|
||||
Code: P_NOISE,
|
||||
VCode: CodeToVarint(P_NOISE),
|
||||
}
|
||||
protoPlaintextV2 = Protocol{
|
||||
Name: "plaintextv2",
|
||||
Code: P_PLAINTEXTV2,
|
||||
VCode: CodeToVarint(P_PLAINTEXTV2),
|
||||
}
|
||||
protoWS = Protocol{
|
||||
Name: "ws",
|
||||
Code: P_WS,
|
||||
VCode: CodeToVarint(P_WS),
|
||||
}
|
||||
protoWSS = Protocol{
|
||||
Name: "wss",
|
||||
Code: P_WSS,
|
||||
VCode: CodeToVarint(P_WSS),
|
||||
}
|
||||
protoWebRTCDirect = Protocol{
|
||||
Name: "webrtc-direct",
|
||||
Code: P_WEBRTC_DIRECT,
|
||||
VCode: CodeToVarint(P_WEBRTC_DIRECT),
|
||||
}
|
||||
protoWebRTC = Protocol{
|
||||
Name: "webrtc",
|
||||
Code: P_WEBRTC,
|
||||
VCode: CodeToVarint(P_WEBRTC),
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
for _, p := range []Protocol{
|
||||
protoIP4,
|
||||
protoTCP,
|
||||
protoDNS,
|
||||
protoDNS4,
|
||||
protoDNS6,
|
||||
protoDNSADDR,
|
||||
protoUDP,
|
||||
protoDCCP,
|
||||
protoIP6,
|
||||
protoIP6ZONE,
|
||||
protoIPCIDR,
|
||||
protoSCTP,
|
||||
protoCIRCUIT,
|
||||
protoONION2,
|
||||
protoONION3,
|
||||
protoGARLIC64,
|
||||
protoGARLIC32,
|
||||
protoUTP,
|
||||
protoUDT,
|
||||
protoQUIC,
|
||||
protoQUICV1,
|
||||
protoWEBTRANSPORT,
|
||||
protoCERTHASH,
|
||||
protoHTTP,
|
||||
protoHTTPS,
|
||||
protoP2P,
|
||||
protoUNIX,
|
||||
protoP2P_WEBRTC_DIRECT,
|
||||
protoTLS,
|
||||
protoSNI,
|
||||
protoNOISE,
|
||||
protoWS,
|
||||
protoWSS,
|
||||
protoPlaintextV2,
|
||||
protoWebRTCDirect,
|
||||
protoWebRTC,
|
||||
} {
|
||||
if err := AddProtocol(p); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// explicitly set both of these
|
||||
protocolsByName["p2p"] = protoP2P
|
||||
protocolsByName["ipfs"] = protoP2P
|
||||
}
|
||||
393
vendor/github.com/multiformats/go-multiaddr/transcoders.go
generated
vendored
Normal file
393
vendor/github.com/multiformats/go-multiaddr/transcoders.go
generated
vendored
Normal file
@@ -0,0 +1,393 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multibase"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
)
|
||||
|
||||
type Transcoder interface {
|
||||
// Validates and encodes to bytes a multiaddr that's in the string representation.
|
||||
StringToBytes(string) ([]byte, error)
|
||||
// Validates and decodes to a string a multiaddr that's in the bytes representation.
|
||||
BytesToString([]byte) (string, error)
|
||||
// Validates bytes when parsing a multiaddr that's already in the bytes representation.
|
||||
ValidateBytes([]byte) error
|
||||
}
|
||||
|
||||
func NewTranscoderFromFunctions(
|
||||
s2b func(string) ([]byte, error),
|
||||
b2s func([]byte) (string, error),
|
||||
val func([]byte) error,
|
||||
) Transcoder {
|
||||
return twrp{s2b, b2s, val}
|
||||
}
|
||||
|
||||
type twrp struct {
|
||||
strtobyte func(string) ([]byte, error)
|
||||
bytetostr func([]byte) (string, error)
|
||||
validbyte func([]byte) error
|
||||
}
|
||||
|
||||
func (t twrp) StringToBytes(s string) ([]byte, error) {
|
||||
return t.strtobyte(s)
|
||||
}
|
||||
func (t twrp) BytesToString(b []byte) (string, error) {
|
||||
return t.bytetostr(b)
|
||||
}
|
||||
|
||||
func (t twrp) ValidateBytes(b []byte) error {
|
||||
if t.validbyte == nil {
|
||||
return nil
|
||||
}
|
||||
return t.validbyte(b)
|
||||
}
|
||||
|
||||
var TranscoderIP4 = NewTranscoderFromFunctions(ip4StB, ip4BtS, nil)
|
||||
var TranscoderIP6 = NewTranscoderFromFunctions(ip6StB, ip6BtS, nil)
|
||||
var TranscoderIP6Zone = NewTranscoderFromFunctions(ip6zoneStB, ip6zoneBtS, ip6zoneVal)
|
||||
var TranscoderIPCIDR = NewTranscoderFromFunctions(ipcidrStB, ipcidrBtS, nil)
|
||||
|
||||
func ipcidrBtS(b []byte) (string, error) {
|
||||
if len(b) != 1 {
|
||||
return "", fmt.Errorf("invalid length (should be == 1)")
|
||||
}
|
||||
return strconv.Itoa(int(b[0])), nil
|
||||
}
|
||||
|
||||
func ipcidrStB(s string) ([]byte, error) {
|
||||
ipMask, err := strconv.ParseUint(s, 10, 8)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []byte{byte(uint8(ipMask))}, nil
|
||||
}
|
||||
|
||||
func ip4StB(s string) ([]byte, error) {
|
||||
i := net.ParseIP(s).To4()
|
||||
if i == nil {
|
||||
return nil, fmt.Errorf("failed to parse ip4 addr: %s", s)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func ip6zoneStB(s string) ([]byte, error) {
|
||||
if len(s) == 0 {
|
||||
return nil, fmt.Errorf("empty ip6zone")
|
||||
}
|
||||
if strings.Contains(s, "/") {
|
||||
return nil, fmt.Errorf("IPv6 zone ID contains '/': %s", s)
|
||||
}
|
||||
return []byte(s), nil
|
||||
}
|
||||
|
||||
func ip6zoneBtS(b []byte) (string, error) {
|
||||
if len(b) == 0 {
|
||||
return "", fmt.Errorf("invalid length (should be > 0)")
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
func ip6zoneVal(b []byte) error {
|
||||
if len(b) == 0 {
|
||||
return fmt.Errorf("invalid length (should be > 0)")
|
||||
}
|
||||
// Not supported as this would break multiaddrs.
|
||||
if bytes.IndexByte(b, '/') >= 0 {
|
||||
return fmt.Errorf("IPv6 zone ID contains '/': %s", string(b))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ip6StB(s string) ([]byte, error) {
|
||||
i := net.ParseIP(s).To16()
|
||||
if i == nil {
|
||||
return nil, fmt.Errorf("failed to parse ip6 addr: %s", s)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func ip6BtS(b []byte) (string, error) {
|
||||
ip := net.IP(b)
|
||||
if ip4 := ip.To4(); ip4 != nil {
|
||||
// Go fails to prepend the `::ffff:` part.
|
||||
return "::ffff:" + ip4.String(), nil
|
||||
}
|
||||
return ip.String(), nil
|
||||
}
|
||||
|
||||
func ip4BtS(b []byte) (string, error) {
|
||||
return net.IP(b).String(), nil
|
||||
}
|
||||
|
||||
var TranscoderPort = NewTranscoderFromFunctions(portStB, portBtS, nil)
|
||||
|
||||
func portStB(s string) ([]byte, error) {
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse port addr: %s", err)
|
||||
}
|
||||
if i >= 65536 {
|
||||
return nil, fmt.Errorf("failed to parse port addr: %s", "greater than 65536")
|
||||
}
|
||||
b := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(b, uint16(i))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func portBtS(b []byte) (string, error) {
|
||||
i := binary.BigEndian.Uint16(b)
|
||||
return strconv.Itoa(int(i)), nil
|
||||
}
|
||||
|
||||
var TranscoderOnion = NewTranscoderFromFunctions(onionStB, onionBtS, nil)
|
||||
|
||||
func onionStB(s string) ([]byte, error) {
|
||||
addr := strings.Split(s, ":")
|
||||
if len(addr) != 2 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s does not contain a port number", s)
|
||||
}
|
||||
|
||||
// onion address without the ".onion" substring
|
||||
if len(addr[0]) != 16 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s not a Tor onion address", s)
|
||||
}
|
||||
onionHostBytes, err := base32.StdEncoding.DecodeString(strings.ToUpper(addr[0]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode base32 onion addr: %s %s", s, err)
|
||||
}
|
||||
|
||||
// onion port number
|
||||
i, err := strconv.Atoi(addr[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s", err)
|
||||
}
|
||||
if i >= 65536 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s", "port greater than 65536")
|
||||
}
|
||||
if i < 1 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s", "port less than 1")
|
||||
}
|
||||
|
||||
onionPortBytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(onionPortBytes, uint16(i))
|
||||
bytes := []byte{}
|
||||
bytes = append(bytes, onionHostBytes...)
|
||||
bytes = append(bytes, onionPortBytes...)
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
func onionBtS(b []byte) (string, error) {
|
||||
addr := strings.ToLower(base32.StdEncoding.EncodeToString(b[0:10]))
|
||||
port := binary.BigEndian.Uint16(b[10:12])
|
||||
return addr + ":" + strconv.Itoa(int(port)), nil
|
||||
}
|
||||
|
||||
var TranscoderOnion3 = NewTranscoderFromFunctions(onion3StB, onion3BtS, nil)
|
||||
|
||||
func onion3StB(s string) ([]byte, error) {
|
||||
addr := strings.Split(s, ":")
|
||||
if len(addr) != 2 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s does not contain a port number", s)
|
||||
}
|
||||
|
||||
// onion address without the ".onion" substring
|
||||
if len(addr[0]) != 56 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s not a Tor onionv3 address. len == %d", s, len(addr[0]))
|
||||
}
|
||||
onionHostBytes, err := base32.StdEncoding.DecodeString(strings.ToUpper(addr[0]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode base32 onion addr: %s %s", s, err)
|
||||
}
|
||||
|
||||
// onion port number
|
||||
i, err := strconv.Atoi(addr[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s", err)
|
||||
}
|
||||
if i >= 65536 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s", "port greater than 65536")
|
||||
}
|
||||
if i < 1 {
|
||||
return nil, fmt.Errorf("failed to parse onion addr: %s", "port less than 1")
|
||||
}
|
||||
|
||||
onionPortBytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(onionPortBytes, uint16(i))
|
||||
bytes := []byte{}
|
||||
bytes = append(bytes, onionHostBytes[0:35]...)
|
||||
bytes = append(bytes, onionPortBytes...)
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
func onion3BtS(b []byte) (string, error) {
|
||||
addr := strings.ToLower(base32.StdEncoding.EncodeToString(b[0:35]))
|
||||
port := binary.BigEndian.Uint16(b[35:37])
|
||||
str := addr + ":" + strconv.Itoa(int(port))
|
||||
return str, nil
|
||||
}
|
||||
|
||||
var TranscoderGarlic64 = NewTranscoderFromFunctions(garlic64StB, garlic64BtS, garlic64Validate)
|
||||
|
||||
// i2p uses an alternate character set for base64 addresses. This returns an appropriate encoder.
|
||||
var garlicBase64Encoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~")
|
||||
|
||||
func garlic64StB(s string) ([]byte, error) {
|
||||
// i2p base64 address will be between 516 and 616 characters long, depending on
|
||||
// certificate type
|
||||
if len(s) < 516 || len(s) > 616 {
|
||||
return nil, fmt.Errorf("failed to parse garlic addr: %s not an i2p base64 address. len: %d", s, len(s))
|
||||
}
|
||||
garlicHostBytes, err := garlicBase64Encoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode base64 i2p addr: %s %s", s, err)
|
||||
}
|
||||
|
||||
return garlicHostBytes, nil
|
||||
}
|
||||
|
||||
func garlic64BtS(b []byte) (string, error) {
|
||||
if err := garlic64Validate(b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
addr := garlicBase64Encoding.EncodeToString(b)
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func garlic64Validate(b []byte) error {
|
||||
// A garlic64 address will always be greater than 386 bytes long when encoded.
|
||||
if len(b) < 386 {
|
||||
return fmt.Errorf("failed to validate garlic addr: %s not an i2p base64 address. len: %d", b, len(b))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var TranscoderGarlic32 = NewTranscoderFromFunctions(garlic32StB, garlic32BtS, garlic32Validate)
|
||||
|
||||
var garlicBase32Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
||||
|
||||
func garlic32StB(s string) ([]byte, error) {
|
||||
// an i2p base32 address with a length of greater than 55 characters is
|
||||
// using an Encrypted Leaseset v2. all other base32 addresses will always be
|
||||
// exactly 52 characters
|
||||
if len(s) < 55 && len(s) != 52 {
|
||||
return nil, fmt.Errorf("failed to parse garlic addr: %s not a i2p base32 address. len: %d", s, len(s))
|
||||
}
|
||||
for len(s)%8 != 0 {
|
||||
s += "="
|
||||
}
|
||||
garlicHostBytes, err := garlicBase32Encoding.DecodeString(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode base32 garlic addr: %s, err: %v len: %v", s, err, len(s))
|
||||
}
|
||||
return garlicHostBytes, nil
|
||||
}
|
||||
|
||||
func garlic32BtS(b []byte) (string, error) {
|
||||
if err := garlic32Validate(b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimRight(garlicBase32Encoding.EncodeToString(b), "="), nil
|
||||
}
|
||||
|
||||
func garlic32Validate(b []byte) error {
|
||||
// an i2p base64 for an Encrypted Leaseset v2 will be at least 35 bytes
|
||||
// long other than that, they will be exactly 32 bytes
|
||||
if len(b) < 35 && len(b) != 32 {
|
||||
return fmt.Errorf("failed to validate garlic addr: %s not an i2p base32 address. len: %d", b, len(b))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var TranscoderP2P = NewTranscoderFromFunctions(p2pStB, p2pBtS, p2pVal)
|
||||
|
||||
// The encoded peer ID can either be a CID of a key or a raw multihash (identity
|
||||
// or sha256-256).
|
||||
func p2pStB(s string) ([]byte, error) {
|
||||
// check if the address is a base58 encoded sha256 or identity multihash
|
||||
if strings.HasPrefix(s, "Qm") || strings.HasPrefix(s, "1") {
|
||||
m, err := mh.FromB58String(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse p2p addr: %s %s", s, err)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// check if the address is a CID
|
||||
c, err := cid.Decode(s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse p2p addr: %s %s", s, err)
|
||||
}
|
||||
|
||||
if ty := c.Type(); ty == cid.Libp2pKey {
|
||||
return c.Hash(), nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("failed to parse p2p addr: %s has the invalid codec %d", s, ty)
|
||||
}
|
||||
}
|
||||
|
||||
func p2pVal(b []byte) error {
|
||||
_, err := mh.Cast(b)
|
||||
return err
|
||||
}
|
||||
|
||||
func p2pBtS(b []byte) (string, error) {
|
||||
m, err := mh.Cast(b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return m.B58String(), nil
|
||||
}
|
||||
|
||||
var TranscoderUnix = NewTranscoderFromFunctions(unixStB, unixBtS, nil)
|
||||
|
||||
func unixStB(s string) ([]byte, error) {
|
||||
return []byte(s), nil
|
||||
}
|
||||
|
||||
func unixBtS(b []byte) (string, error) {
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
var TranscoderDns = NewTranscoderFromFunctions(dnsStB, dnsBtS, dnsVal)
|
||||
|
||||
func dnsVal(b []byte) error {
|
||||
if bytes.IndexByte(b, '/') >= 0 {
|
||||
return fmt.Errorf("domain name %q contains a slash", string(b))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func dnsStB(s string) ([]byte, error) {
|
||||
return []byte(s), nil
|
||||
}
|
||||
|
||||
func dnsBtS(b []byte) (string, error) {
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
var TranscoderCertHash = NewTranscoderFromFunctions(certHashStB, certHashBtS, nil)
|
||||
|
||||
func certHashStB(s string) ([]byte, error) {
|
||||
_, data, err := multibase.Decode(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := mh.Decode(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func certHashBtS(b []byte) (string, error) {
|
||||
return multibase.Encode(multibase.Base64url, b)
|
||||
}
|
||||
180
vendor/github.com/multiformats/go-multiaddr/util.go
generated
vendored
Normal file
180
vendor/github.com/multiformats/go-multiaddr/util.go
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
package multiaddr
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Split returns the sub-address portions of a multiaddr.
|
||||
func Split(m Multiaddr) []Multiaddr {
|
||||
if _, ok := m.(*Component); ok {
|
||||
return []Multiaddr{m}
|
||||
}
|
||||
var addrs []Multiaddr
|
||||
ForEach(m, func(c Component) bool {
|
||||
addrs = append(addrs, &c)
|
||||
return true
|
||||
})
|
||||
return addrs
|
||||
}
|
||||
|
||||
// Join returns a combination of addresses.
|
||||
func Join(ms ...Multiaddr) Multiaddr {
|
||||
switch len(ms) {
|
||||
case 0:
|
||||
// empty multiaddr, unfortunately, we have callers that rely on
|
||||
// this contract.
|
||||
return &multiaddr{}
|
||||
case 1:
|
||||
return ms[0]
|
||||
}
|
||||
|
||||
length := 0
|
||||
bs := make([][]byte, len(ms))
|
||||
for i, m := range ms {
|
||||
bs[i] = m.Bytes()
|
||||
length += len(bs[i])
|
||||
}
|
||||
|
||||
bidx := 0
|
||||
b := make([]byte, length)
|
||||
for _, mb := range bs {
|
||||
bidx += copy(b[bidx:], mb)
|
||||
}
|
||||
return &multiaddr{bytes: b}
|
||||
}
|
||||
|
||||
// Cast re-casts a byte slice as a multiaddr. will panic if it fails to parse.
|
||||
func Cast(b []byte) Multiaddr {
|
||||
m, err := NewMultiaddrBytes(b)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("multiaddr failed to parse: %s", err))
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// StringCast like Cast, but parses a string. Will also panic if it fails to parse.
|
||||
func StringCast(s string) Multiaddr {
|
||||
m, err := NewMultiaddr(s)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("multiaddr failed to parse: %s", err))
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// SplitFirst returns the first component and the rest of the multiaddr.
|
||||
func SplitFirst(m Multiaddr) (*Component, Multiaddr) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
b := m.Bytes()
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
n, c, err := readComponent(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(b) == n {
|
||||
return &c, nil
|
||||
}
|
||||
return &c, &multiaddr{b[n:]}
|
||||
}
|
||||
|
||||
// SplitLast returns the rest of the multiaddr and the last component.
|
||||
func SplitLast(m Multiaddr) (Multiaddr, *Component) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
return nil, c
|
||||
}
|
||||
|
||||
b := m.Bytes()
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var (
|
||||
c Component
|
||||
err error
|
||||
offset int
|
||||
)
|
||||
for {
|
||||
var n int
|
||||
n, c, err = readComponent(b[offset:])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if len(b) == n+offset {
|
||||
// Reached end
|
||||
if offset == 0 {
|
||||
// Only one component
|
||||
return nil, &c
|
||||
}
|
||||
return &multiaddr{b[:offset]}, &c
|
||||
}
|
||||
offset += n
|
||||
}
|
||||
}
|
||||
|
||||
// SplitFunc splits the multiaddr when the callback first returns true. The
|
||||
// component on which the callback first returns will be included in the
|
||||
// *second* multiaddr.
|
||||
func SplitFunc(m Multiaddr, cb func(Component) bool) (Multiaddr, Multiaddr) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
if cb(*c) {
|
||||
return nil, m
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
b := m.Bytes()
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var (
|
||||
c Component
|
||||
err error
|
||||
offset int
|
||||
)
|
||||
for offset < len(b) {
|
||||
var n int
|
||||
n, c, err = readComponent(b[offset:])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if cb(c) {
|
||||
break
|
||||
}
|
||||
offset += n
|
||||
}
|
||||
switch offset {
|
||||
case 0:
|
||||
return nil, m
|
||||
case len(b):
|
||||
return m, nil
|
||||
default:
|
||||
return &multiaddr{b[:offset]}, &multiaddr{b[offset:]}
|
||||
}
|
||||
}
|
||||
|
||||
// ForEach walks over the multiaddr, component by component.
|
||||
//
|
||||
// This function iterates over components *by value* to avoid allocating.
|
||||
func ForEach(m Multiaddr, cb func(c Component) bool) {
|
||||
// Shortcut if we already have a component
|
||||
if c, ok := m.(*Component); ok {
|
||||
cb(*c)
|
||||
return
|
||||
}
|
||||
|
||||
b := m.Bytes()
|
||||
for len(b) > 0 {
|
||||
n, c, err := readComponent(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !cb(c) {
|
||||
return
|
||||
}
|
||||
b = b[n:]
|
||||
}
|
||||
}
|
||||
27
vendor/github.com/multiformats/go-multiaddr/varint.go
generated
vendored
Normal file
27
vendor/github.com/multiformats/go-multiaddr/varint.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/multiformats/go-varint"
|
||||
)
|
||||
|
||||
// CodeToVarint converts an integer to a varint-encoded []byte
|
||||
func CodeToVarint(num int) []byte {
|
||||
if num < 0 || num > math.MaxInt32 {
|
||||
panic("invalid code")
|
||||
}
|
||||
return varint.ToUvarint(uint64(num))
|
||||
}
|
||||
|
||||
func ReadVarintCode(b []byte) (int, int, error) {
|
||||
code, n, err := varint.FromUvarint(b)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if code > math.MaxInt32 {
|
||||
// we only allow 32bit codes.
|
||||
return 0, 0, varint.ErrOverflow
|
||||
}
|
||||
return int(code), n, err
|
||||
}
|
||||
3
vendor/github.com/multiformats/go-multiaddr/version.json
generated
vendored
Normal file
3
vendor/github.com/multiformats/go-multiaddr/version.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "v0.12.0"
|
||||
}
|
||||
Reference in New Issue
Block a user