rpc/stream/vif: reuse vif auth in vc
This change allows to reuse VIF authentication in VCs when the peer
is the same as VIF - i.e., non-through-proxy connection.
Details:
o During a VIF setup, peers exchange their endpoint and save VIF
authentication, which can be used in the following VCs.
o During vif.Dial(), re-use the VIF authentication when
- a principal given to vif.InternalNewDialedVIF() and one given to
vif.Dial() are same, and
- two remote endpoints are same or the given endpoint is null
which means a direct connection with hostname and port
- a server verifies a signature for reusing the VIF authentication
that are sent from a client.
o When reusing VIF auth
- a dialed VC creates a new public and private key, but uses
a server's public key which were exchanged during VIF setup.
The VC sends the new public key to the server, but skips
all authentication except running server authorizer.
- a accepted VC creates a new crypter using the VIF's public and
private key pair with a new public key from the client.
The server doesn't send a SetupVC response and skips the
authentication.
RPC Setup Benchmark: (in GCE)
o OLD: RPC Connection 30.27 ms/rpc
o NEW: RPC Connection 14.02 ms/rpc
Agent Benchmark: (in GCE)
benchmark old ns/op new ns/op delta
BenchmarkSignNoAgent-4 936403 932508 -0.42%
BenchmarkSignCachedAgent-4 5309176 1764895 -66.76%
BenchmarkSignUncachedAgent-4 5381638 1758834 -67.32%
BenchmarkDefaultNoAgent-4 137 140 +2.19%
BenchmarkDefaultCachedAgent-4 44.7 45.2 +1.12%
BenchmarkDefaultUncachedAgent-4 7828080 3846960 -50.86%
BenchmarkRecognizedNegativeNoAgent-4 34227 36651 +7.08%
BenchmarkRecognizedNegativeCachedAgent-4 33353 35574 +6.66%
BenchmarkRecognizedNegativeUncachedAgent-4 4291997 944295 -78.00%
BenchmarkRecognizedNoAgent-4 13485 14271 +5.83%
BenchmarkRecognizedCachedAgent-4 13031 13456 +3.26%
BenchmarkRecognizedUncachedAgent-4 4016690 785538 -80.44%
MultiPart: 2/2
Change-Id: Ida0c8f65a7b0083d8b75e59af45202c6276964d6
diff --git a/runtime/internal/rpc/stream/manager/manager_test.go b/runtime/internal/rpc/stream/manager/manager_test.go
index bce2bab..2c20fcb 100644
--- a/runtime/internal/rpc/stream/manager/manager_test.go
+++ b/runtime/internal/rpc/stream/manager/manager_test.go
@@ -65,6 +65,7 @@
server := InternalNew(naming.FixedRoutingID(0x55555555))
client := InternalNew(naming.FixedRoutingID(0xcccccccc))
pclient := testutil.NewPrincipal("client")
+ pclient2 := testutil.NewPrincipal("client2")
pserver := testutil.NewPrincipal("server")
ln, ep, err := server.Listen(protocol, "127.0.0.1:0", pserver, pserver.BlessingStore().Default())
@@ -141,8 +142,10 @@
if err := writeLine(clientF2, lotsOfData); err == nil {
t.Errorf("Should not be able to Dial or Write after the Listener is closed")
}
- // Opening a new VC should fail fast.
- if _, err := client.Dial(ep, pclient); err == nil {
+ // Opening a new VC should fail fast. Note that we need to use a different
+ // principal since the client doesn't expect a response from a server
+ // when re-using VIF authentication.
+ if _, err := client.Dial(ep, pclient2); err == nil {
t.Errorf("Should not be able to Dial after listener is closed")
}
}
@@ -458,12 +461,11 @@
if err != nil {
t.Fatal(err)
}
+ errch := make(chan error)
go func() {
for {
_, err := ln.Accept()
- if err != nil {
- return
- }
+ errch <- err
}
}()
@@ -475,6 +477,10 @@
if f == nil || err != nil {
t.Fatalf("vc.Connect failed: (%v, %v)", f, err)
}
+ // Wait until the server accepts the flow or fails.
+ if err = <-errch; err != nil {
+ t.Fatalf("ln.Accept failed: %v", err)
+ }
// Trigger the idle timers.
triggerTimers()
@@ -664,6 +670,7 @@
func testServerRestartDuringClientLifetime(t *testing.T, protocol string) {
client := InternalNew(naming.FixedRoutingID(0xcccccccc))
pclient := testutil.NewPrincipal("client")
+ pclient2 := testutil.NewPrincipal("client2")
sh, err := modules.NewShell(nil, nil, testing.Verbose(), t)
if err != nil {
t.Fatalf("unexpected error: %s", err)
@@ -683,8 +690,10 @@
}
h.Shutdown(nil, os.Stderr)
- // A new VC cannot be created since the server is dead
- if _, err := client.Dial(ep, pclient); err == nil {
+ // A new VC cannot be created since the server is dead. Note that we need to
+ // use a different principal since the client doesn't expect a response from
+ // a server when re-using VIF authentication.
+ if _, err := client.Dial(ep, pclient2); err == nil {
t.Fatal("Expected client.Dial to fail since server is dead")
}
@@ -953,12 +962,12 @@
errCh := make(chan error, 10)
for i := 0; i < 10; i++ {
go func() {
- _, err = client.Dial(nep, testutil.NewPrincipal("client"))
+ _, err := client.Dial(nep, testutil.NewPrincipal("client"))
errCh <- err
}()
}
for i := 0; i < 10; i++ {
- if err = <-errCh; err != nil {
+ if err := <-errCh; err != nil {
t.Fatal(err)
}
}