forked from TrueCloudLab/frostfs-node
[#549] network/Address: Add TLS
There is no TLS protocol support in `go-multiaddr` library, but there is public function that can register any protocol that can be implemented outside the library. Also `TLSEnabled` function for parsing TLS protocol from `network.Address` was added. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
33bef46f31
commit
f267fbc56a
4 changed files with 191 additions and 0 deletions
|
@ -31,6 +31,22 @@ type LocalAddressSource interface {
|
||||||
LocalAddress() *Address
|
LocalAddress() *Address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encapsulate wraps this Address around another. For example:
|
||||||
|
//
|
||||||
|
// /ip4/1.2.3.4 encapsulate /tcp/80 = /ip4/1.2.3.4/tcp/80
|
||||||
|
//
|
||||||
|
func (a *Address) Encapsulate(addr *Address) {
|
||||||
|
a.ma = a.ma.Encapsulate(addr.ma)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decapsulate removes an Address wrapping. For example:
|
||||||
|
//
|
||||||
|
// /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80
|
||||||
|
//
|
||||||
|
func (a *Address) Decapsulate(addr *Address) {
|
||||||
|
a.ma = a.ma.Decapsulate(addr.ma)
|
||||||
|
}
|
||||||
|
|
||||||
// String returns multiaddr string
|
// String returns multiaddr string
|
||||||
func (a Address) String() string {
|
func (a Address) String() string {
|
||||||
return a.ma.String()
|
return a.ma.String()
|
||||||
|
|
|
@ -82,6 +82,66 @@ func TestAddress_HostAddrString(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddress_Encapsulate(t *testing.T) {
|
||||||
|
ma1, ma2 := "/dns4/neofs.bigcorp.com/tcp/8080", "/tls"
|
||||||
|
|
||||||
|
testcases := []struct {
|
||||||
|
ma1 multiaddr.Multiaddr
|
||||||
|
ma2 multiaddr.Multiaddr
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
buildMultiaddr(ma1, t),
|
||||||
|
buildMultiaddr(ma2, t),
|
||||||
|
ma1 + ma2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
buildMultiaddr(ma2, t),
|
||||||
|
buildMultiaddr(ma1, t),
|
||||||
|
ma2 + ma1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testcase := range testcases {
|
||||||
|
addr1 := &Address{testcase.ma1}
|
||||||
|
addr2 := &Address{testcase.ma2}
|
||||||
|
|
||||||
|
addr1.Encapsulate(addr2)
|
||||||
|
|
||||||
|
require.Equal(t, addr1.String(), testcase.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddress_Decapsulate(t *testing.T) {
|
||||||
|
ma1, ma2 := "/dns4/neofs.bigcorp.com/tcp/8080", "/tls"
|
||||||
|
|
||||||
|
testcases := []struct {
|
||||||
|
ma1 multiaddr.Multiaddr
|
||||||
|
ma2 multiaddr.Multiaddr
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
buildMultiaddr(ma1+ma2, t),
|
||||||
|
buildMultiaddr(ma2, t),
|
||||||
|
ma1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
buildMultiaddr(ma2+ma1, t),
|
||||||
|
buildMultiaddr(ma1, t),
|
||||||
|
ma2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testcase := range testcases {
|
||||||
|
addr1 := &Address{testcase.ma1}
|
||||||
|
addr2 := &Address{testcase.ma2}
|
||||||
|
|
||||||
|
addr1.Decapsulate(addr2)
|
||||||
|
|
||||||
|
require.Equal(t, addr1.String(), testcase.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func buildMultiaddr(s string, t *testing.T) multiaddr.Multiaddr {
|
func buildMultiaddr(s string, t *testing.T) multiaddr.Multiaddr {
|
||||||
ma, err := multiaddr.NewMultiaddr(s)
|
ma, err := multiaddr.NewMultiaddr(s)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
67
pkg/network/tls.go
Normal file
67
pkg/network/tls.go
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/multiformats/go-multiaddr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// There is implementation of TLS protocol for
|
||||||
|
// github.com/multiformats/go-multiaddr library in this file.
|
||||||
|
//
|
||||||
|
// After addition TLS protocol via `multiaddr.AddProtocol` function
|
||||||
|
// the library is ready to parse "tls" protocol with empty body, e.g.:
|
||||||
|
//
|
||||||
|
// "/dns4/localhost/tcp/8080/tls"
|
||||||
|
|
||||||
|
const (
|
||||||
|
tlsProtocolName = "tls"
|
||||||
|
|
||||||
|
// tlsProtocolCode is chosen according to its draft version's code in
|
||||||
|
// original multiaddr repository: https://github.com/multiformats/multicodec.
|
||||||
|
tlsProtocolCode = 0x01c0
|
||||||
|
)
|
||||||
|
|
||||||
|
// tls var is used for (un)wrapping other multiaddrs around TLS multiaddr.
|
||||||
|
var tls multiaddr.Multiaddr
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
tlsProtocol := multiaddr.Protocol{
|
||||||
|
Name: tlsProtocolName,
|
||||||
|
Code: tlsProtocolCode,
|
||||||
|
Size: 0,
|
||||||
|
VCode: multiaddr.CodeToVarint(tlsProtocolCode),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := multiaddr.AddProtocol(tlsProtocol)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("could not add 'TLS' protocol to multiadd library: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
tls, err = multiaddr.NewMultiaddr("/" + tlsProtocolName)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("could not init 'TLS' protocol with multiadd library: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TLSEnabled searches for wrapped TLS protocol in multiaddr.
|
||||||
|
func (a Address) TLSEnabled() bool {
|
||||||
|
for _, protoc := range a.ma.Protocols() {
|
||||||
|
if protoc.Code == tlsProtocolCode {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTLS encapsulates a Address if there is no TLS yet.
|
||||||
|
func (a *Address) AddTLS() {
|
||||||
|
// not need to add TLS if it is
|
||||||
|
// already included
|
||||||
|
if a.TLSEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
a.ma = a.ma.Encapsulate(tls)
|
||||||
|
}
|
48
pkg/network/tls_test.go
Normal file
48
pkg/network/tls_test.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAddress_TLSEnabled(t *testing.T) {
|
||||||
|
testCases := [...]struct {
|
||||||
|
input string
|
||||||
|
wantTLS bool
|
||||||
|
}{
|
||||||
|
{"/dns4/localhost/tcp/8080", false},
|
||||||
|
{"/dns4/localhost/tcp/8080/tls", true},
|
||||||
|
{"/tls/dns4/localhost/tcp/8080", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
addr := Address{
|
||||||
|
ma: buildMultiaddr(test.input, t),
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, test.wantTLS, addr.TLSEnabled(), test.input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddress_AddTLS(t *testing.T) {
|
||||||
|
input, tls := "/dns4/localhost/tcp/8080", tls.String()
|
||||||
|
|
||||||
|
testCases := [...]struct {
|
||||||
|
input string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{input, input + tls},
|
||||||
|
{input + tls, input + tls},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
addr := Address{
|
||||||
|
ma: buildMultiaddr(test.input, t),
|
||||||
|
}
|
||||||
|
|
||||||
|
addr.AddTLS()
|
||||||
|
|
||||||
|
require.Equal(t, test.want, addr.String(), test.input)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue