-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
move go-conn-security-multistream here #1460
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
6df7572
initial commit
Stebalien 5859069
type assert transport
Stebalien cae1231
add tests
Stebalien fc8c4a8
complete rename
Stebalien e858613
go fmt
Stebalien 5a60c83
fix tests for go-conn-security refactor
Stebalien 085f98a
block while writing
Stebalien 1de116d
Merge pull request #10 from libp2p/fix/block-while-writing
Stebalien c86093d
migrate to consolidated types (#12)
raulk 3dade04
chore(dep): update
Stebalien da4a5cb
Merge pull request #19 from libp2p/chore/update-deps
Stebalien bd0110c
Implement support for simultaneous open (#14)
vyzo f70302a
fix go vet
marten-seemann 3779514
fix staticcheck
marten-seemann d0442a2
Merge pull request #33 from libp2p/fix-linters
marten-seemann b63c8ff
use the new SecureTransport and SecureMuxer interfaces (#36)
marten-seemann fc9539f
move go-conn-security-multistream here
marten-seemann de5875f
switch from github.com/libp2p/go-conn-security-multistream to p2p/net…
marten-seemann File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package csms | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"net" | ||
|
||
"github.com/libp2p/go-libp2p-core/peer" | ||
"github.com/libp2p/go-libp2p-core/sec" | ||
mss "github.com/multiformats/go-multistream" | ||
) | ||
|
||
// SSMuxer is a multistream stream security transport multiplexer. | ||
// | ||
// SSMuxer is safe to use without initialization. However, it's not safe to move | ||
// after use. | ||
type SSMuxer struct { | ||
mux mss.MultistreamMuxer | ||
tpts map[string]sec.SecureTransport | ||
OrderPreference []string | ||
} | ||
|
||
var _ sec.SecureMuxer = (*SSMuxer)(nil) | ||
|
||
// AddTransport adds a stream security transport to this multistream muxer. | ||
// | ||
// This method is *not* thread-safe. It should be called only when initializing | ||
// the SSMuxer. | ||
func (sm *SSMuxer) AddTransport(path string, transport sec.SecureTransport) { | ||
if sm.tpts == nil { | ||
sm.tpts = make(map[string]sec.SecureTransport, 1) | ||
} | ||
|
||
sm.mux.AddHandler(path, nil) | ||
sm.tpts[path] = transport | ||
sm.OrderPreference = append(sm.OrderPreference, path) | ||
} | ||
|
||
// SecureInbound secures an inbound connection using this multistream | ||
// multiplexed stream security transport. | ||
func (sm *SSMuxer) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, bool, error) { | ||
tpt, _, err := sm.selectProto(ctx, insecure, true) | ||
if err != nil { | ||
return nil, false, err | ||
} | ||
sconn, err := tpt.SecureInbound(ctx, insecure, p) | ||
return sconn, true, err | ||
} | ||
|
||
// SecureOutbound secures an outbound connection using this multistream | ||
// multiplexed stream security transport. | ||
func (sm *SSMuxer) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, bool, error) { | ||
tpt, server, err := sm.selectProto(ctx, insecure, false) | ||
if err != nil { | ||
return nil, false, err | ||
} | ||
|
||
var sconn sec.SecureConn | ||
if server { | ||
sconn, err = tpt.SecureInbound(ctx, insecure, p) | ||
if err != nil { | ||
return nil, false, fmt.Errorf("failed to secure inbound connection: %s", err) | ||
} | ||
// ensure the correct peer connected to us | ||
if sconn.RemotePeer() != p { | ||
sconn.Close() | ||
log.Printf("Handshake failed to properly authenticate peer. Authenticated %s, expected %s.", sconn.RemotePeer(), p) | ||
return nil, false, fmt.Errorf("unexpected peer") | ||
} | ||
} else { | ||
sconn, err = tpt.SecureOutbound(ctx, insecure, p) | ||
} | ||
|
||
return sconn, server, err | ||
} | ||
|
||
func (sm *SSMuxer) selectProto(ctx context.Context, insecure net.Conn, server bool) (sec.SecureTransport, bool, error) { | ||
var proto string | ||
var err error | ||
var iamserver bool | ||
done := make(chan struct{}) | ||
go func() { | ||
defer close(done) | ||
if server { | ||
iamserver = true | ||
proto, _, err = sm.mux.Negotiate(insecure) | ||
} else { | ||
proto, iamserver, err = mss.SelectWithSimopenOrFail(sm.OrderPreference, insecure) | ||
} | ||
}() | ||
|
||
select { | ||
case <-done: | ||
if err != nil { | ||
return nil, false, err | ||
} | ||
if tpt, ok := sm.tpts[proto]; ok { | ||
return tpt, iamserver, nil | ||
} | ||
return nil, false, fmt.Errorf("selected unknown security transport") | ||
case <-ctx.Done(): | ||
// We *must* do this. We have outstanding work on the connection | ||
// and it's no longer safe to use. | ||
insecure.Close() | ||
<-done // wait to stop using the connection. | ||
return nil, false, ctx.Err() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package csms | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"sync" | ||
"testing" | ||
|
||
"github.com/libp2p/go-libp2p-core/peer" | ||
"github.com/libp2p/go-libp2p-core/sec" | ||
"github.com/libp2p/go-libp2p-core/sec/insecure" | ||
tnet "github.com/libp2p/go-libp2p-testing/net" | ||
sst "github.com/libp2p/go-libp2p-testing/suites/sec" | ||
) | ||
|
||
type TransportAdapter struct { | ||
mux *SSMuxer | ||
} | ||
|
||
func (sm *TransportAdapter) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { | ||
sconn, _, err := sm.mux.SecureInbound(ctx, insecure, p) | ||
return sconn, err | ||
} | ||
|
||
func (sm *TransportAdapter) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { | ||
sconn, _, err := sm.mux.SecureOutbound(ctx, insecure, p) | ||
return sconn, err | ||
} | ||
|
||
func TestCommonProto(t *testing.T) { | ||
idA := tnet.RandIdentityOrFatal(t) | ||
idB := tnet.RandIdentityOrFatal(t) | ||
|
||
var at, bt SSMuxer | ||
|
||
atInsecure := insecure.NewWithIdentity(idA.ID(), idA.PrivateKey()) | ||
btInsecure := insecure.NewWithIdentity(idB.ID(), idB.PrivateKey()) | ||
at.AddTransport("/plaintext/1.0.0", atInsecure) | ||
bt.AddTransport("/plaintext/1.1.0", btInsecure) | ||
bt.AddTransport("/plaintext/1.0.0", btInsecure) | ||
sst.SubtestRW(t, &TransportAdapter{mux: &at}, &TransportAdapter{mux: &bt}, idA.ID(), idB.ID()) | ||
} | ||
|
||
func TestNoCommonProto(t *testing.T) { | ||
idA := tnet.RandIdentityOrFatal(t) | ||
idB := tnet.RandIdentityOrFatal(t) | ||
|
||
var at, bt SSMuxer | ||
atInsecure := insecure.NewWithIdentity(idA.ID(), idA.PrivateKey()) | ||
btInsecure := insecure.NewWithIdentity(idB.ID(), idB.PrivateKey()) | ||
|
||
at.AddTransport("/plaintext/1.0.0", atInsecure) | ||
bt.AddTransport("/plaintext/1.1.0", btInsecure) | ||
|
||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
a, b := net.Pipe() | ||
|
||
var wg sync.WaitGroup | ||
wg.Add(2) | ||
go func() { | ||
defer wg.Done() | ||
defer a.Close() | ||
_, _, err := at.SecureInbound(ctx, a, "") | ||
if err == nil { | ||
t.Error("connection should have failed") | ||
} | ||
}() | ||
|
||
go func() { | ||
defer wg.Done() | ||
defer b.Close() | ||
_, _, err := bt.SecureOutbound(ctx, b, "peerA") | ||
if err == nil { | ||
t.Error("connection should have failed") | ||
} | ||
}() | ||
wg.Wait() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to rename to something sane.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe even have a multistream package? Or an upgraders package? Not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have an upgrader. Can't think of something sensible for this package right now. Let's rename this later.