"veyron/runtimes/google/rt": Servers must use Runtime's current identity
Prior to this CL, the runtime would allow servers to be created with
an arbitrary identity specified using a veyron2.LocalID option. This
can result in multiple identities (PrivateIDs) being used by servers
running under the same process. We would instead like all servers
running under the same process to use the current identity of the process's
runtime. This would allow us to define "claiming" a device as
simply changing the identity of the device's node manager's runtime.
Specifically, this CL makes the following changes:
1) Forbids veyron2.LocalID from being a option that can be used while
creating Servers or stream Listeners.
2) Provide a default option to all created servers that conveys the identity
currently used by the runtime, i.e. if at any point the runtime's identity
changes then all servers would seamlessly start using the new identity.
Change-Id: I3ebeb0a03a431b482916492a00bf138eec71cb3b
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 2a6d4d8..2db5072 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -208,7 +208,7 @@
func startServer(t *testing.T, serverID security.PrivateID, sm stream.Manager, mt naming.MountTable, ts interface{}) ipc.Server {
vlog.VI(1).Info("InternalNewServer")
- server, err := InternalNewServer(InternalNewContext(), sm, mt, veyron2.LocalID(serverID))
+ server, err := InternalNewServer(InternalNewContext(), sm, mt, listenerID(serverID))
if err != nil {
t.Errorf("InternalNewServer failed: %v", err)
}
@@ -769,7 +769,7 @@
{[]ipc.ServerOpt{veyron2.PublishFirst, veyron2.EndpointRewriteOpt("example.com")}, []string{"example.com"}},
}
for i, c := range cases {
- server, err := InternalNewServer(InternalNewContext(), sm, mt, append([]ipc.ServerOpt{veyron2.LocalID(serverID)}, c.opts...)...)
+ server, err := InternalNewServer(InternalNewContext(), sm, mt, append([]ipc.ServerOpt{listenerID(serverID)}, c.opts...)...)
if err != nil {
t.Errorf("InternalNewServer failed: %v", err)
continue
@@ -907,7 +907,7 @@
t.Fatal(err)
}
defer client.Close()
- server, err := InternalNewServer(InternalNewContext(), sm, mt, veyron2.LocalID(serverID))
+ server, err := InternalNewServer(InternalNewContext(), sm, mt, listenerID(serverID))
if err != nil {
t.Fatal(err)
}
@@ -992,7 +992,7 @@
mt := newMountTable()
id := loadIdentityFromFile(argv[1])
isecurity.TrustIdentityProviders(id)
- server, err := InternalNewServer(InternalNewContext(), mgr, mt, veyron2.LocalID(id))
+ server, err := InternalNewServer(InternalNewContext(), mgr, mt, listenerID(id))
if err != nil {
vlog.Fatalf("InternalNewServer failed: %v", err)
}
diff --git a/runtimes/google/ipc/stream/manager/manager_test.go b/runtimes/google/ipc/stream/manager/manager_test.go
index 558b5ef..943a667 100644
--- a/runtimes/google/ipc/stream/manager/manager_test.go
+++ b/runtimes/google/ipc/stream/manager/manager_test.go
@@ -126,7 +126,7 @@
// VCSecurityLevel is intentionally not provided to Listen - to test
// default behavior.
- ln, ep, err := server.Listen("tcp", "localhost:0", veyron2.LocalID(serverID))
+ ln, ep, err := server.Listen("tcp", "localhost:0", vc.ListenerID(serverID))
if err != nil {
t.Fatal(err)
}
@@ -287,7 +287,7 @@
}
func TestSessionTicketCache(t *testing.T) {
- serverID := veyron2.LocalID(security.FakePrivateID("TestSessionTicketCacheServer"))
+ serverID := vc.ListenerID(security.FakePrivateID("TestSessionTicketCacheServer"))
server := InternalNew(naming.FixedRoutingID(0x55555555))
_, ep, err := server.Listen("tcp", "localhost:0", serverID)
if err != nil {
@@ -314,7 +314,7 @@
// Have the server read from each flow and write to rchan.
rchan := make(chan string)
- ln, ep, err := server.Listen("tcp", "localhost:0", veyron2.LocalID(security.FakePrivateID("server")))
+ ln, ep, err := server.Listen("tcp", "localhost:0", vc.ListenerID(security.FakePrivateID("server")))
if err != nil {
t.Fatal(err)
}
@@ -465,7 +465,7 @@
func runServer(argv []string) {
server := InternalNew(naming.FixedRoutingID(0x55555555))
- _, ep, err := server.Listen("tcp", argv[0], veyron2.LocalID(security.FakePrivateID("server")))
+ _, ep, err := server.Listen("tcp", argv[0], vc.ListenerID(security.FakePrivateID("server")))
if err != nil {
fmt.Println(err)
return
diff --git a/runtimes/google/ipc/stream/proxy/proxy.go b/runtimes/google/ipc/stream/proxy/proxy.go
index 6f343d3..bab175e 100644
--- a/runtimes/google/ipc/stream/proxy/proxy.go
+++ b/runtimes/google/ipc/stream/proxy/proxy.go
@@ -5,7 +5,6 @@
"fmt"
"net"
"sync"
-
"veyron/runtimes/google/ipc/stream/id"
"veyron/runtimes/google/ipc/stream/message"
"veyron/runtimes/google/ipc/stream/vc"
@@ -14,8 +13,6 @@
"veyron/runtimes/google/lib/bqueue/drrqueue"
"veyron/runtimes/google/lib/iobuf"
"veyron/runtimes/google/lib/upcqueue"
-
- "veyron2"
"veyron2/naming"
"veyron2/security"
"veyron2/verror"
@@ -44,15 +41,13 @@
// process encapsulates the physical network connection and the routing table
// associated with the process at the other end of the network connection.
type process struct {
- Conn net.Conn
- Queue *upcqueue.T
-
+ Conn net.Conn
+ Queue *upcqueue.T
mu sync.RWMutex
routingTable map[id.VC]*destination
nextVCI id.VC
servers map[id.VC]*vc.VC // servers wishing to be proxied create a VC that terminates at the proxy
-
- BQ bqueue.T // Flow control for messages sent on behalf of servers.
+ BQ bqueue.T // Flow control for messages sent on behalf of servers.
}
// destination is an entry in the routingtable of a process.
@@ -100,7 +95,6 @@
proxyLog().Infof("Started proxying server: %v", server)
return nil
}
-
func (m *servermap) Remove(server *server) {
key := server.RoutingID()
m.mu.Lock()
@@ -110,7 +104,6 @@
}
m.mu.Unlock()
}
-
func (m *servermap) Process(rid naming.RoutingID) *process {
m.mu.Lock()
defer m.mu.Unlock()
@@ -119,7 +112,6 @@
}
return nil
}
-
func (m *servermap) List() []string {
m.mu.Lock()
defer m.mu.Unlock()
@@ -151,7 +143,6 @@
go proxy.listenLoop()
return proxy, nil
}
-
func (p *Proxy) listenLoop() {
proxyLog().Infof("Proxy listening on (%q, %q): %v", p.ln.Addr().Network(), p.ln.Addr(), p.Endpoint())
for {
@@ -172,7 +163,6 @@
go p.readLoop(process)
}
}
-
func writeLoop(process *process) {
defer processLog().Infof("Exited writeLoop for %v", process)
defer process.Close()
@@ -190,7 +180,6 @@
}
}
}
-
func serverVCsLoop(process *process) {
for {
w, bufs, err := process.BQ.Get(nil)
@@ -211,13 +200,11 @@
releaseBufs(0, bufs)
}
}
-
func releaseBufs(start int, bufs []*iobuf.Slice) {
for i := start; i < len(bufs); i++ {
bufs[i].Release()
}
}
-
func queueDataMessages(bufs []*iobuf.Slice, vc *vc.VC, fid id.Flow, q *upcqueue.T) {
for ix, b := range bufs {
m := &message.Data{VCI: vc.VCI(), Flow: fid}
@@ -235,14 +222,12 @@
}
}
}
-
func (p *Proxy) startProcess(process *process) {
p.mu.Lock()
p.processes[process] = struct{}{}
p.mu.Unlock()
processLog().Infof("Started process %v", process)
}
-
func (p *Proxy) stopProcess(process *process) {
process.Close()
p.mu.Lock()
@@ -250,14 +235,11 @@
p.mu.Unlock()
processLog().Infof("Stopped process %v", process)
}
-
func (p *Proxy) readLoop(process *process) {
p.startProcess(process)
defer p.stopProcess(process)
-
reader := iobuf.NewReader(iobuf.NewPool(0), process.Conn)
defer reader.Close()
-
for {
msg, err := message.ReadFrom(reader)
if err != nil {
@@ -326,12 +308,12 @@
if naming.Compare(dstrid, p.rid) || naming.Compare(dstrid, naming.NullRoutingID) {
// VC that terminates at the proxy.
// See protocol.vdl for details on the protocol between the server and the proxy.
- vc := process.NewServerVC(m)
+ vcObj := process.NewServerVC(m)
// route counters after creating the VC so counters to vc are not lost.
p.routeCounters(process, m.Counters)
- if vc != nil {
- server := &server{Process: process, VC: vc}
- go p.runServer(server, vc.HandshakeAcceptedVC(veyron2.LocalID(p.id)))
+ if vcObj != nil {
+ server := &server{Process: process, VC: vcObj}
+ go p.runServer(server, vcObj.HandshakeAcceptedVC(vc.ListenerID(p.id)))
}
break
}
@@ -364,7 +346,6 @@
}
}
}
-
func (p *Proxy) runServer(server *server, c <-chan vc.HandshakeResult) {
hr := <-c
if hr.Error != nil {
@@ -379,7 +360,6 @@
}
defer server.Close(nil)
server.Process.InitVCI(server.VC.VCI())
-
var request Request
var response Response
if err := vom.NewDecoder(conn).Decode(&request); err != nil {
@@ -414,7 +394,6 @@
// Wait for this flow to be closed.
<-conn.Closed()
}
-
func (p *Proxy) routeCounters(process *process, counters message.Counters) {
// Since each VC can be routed to a different process, split up the
// Counters into one message per VC.
@@ -436,7 +415,6 @@
}
}
}
-
func startRoutingVC(srcVCI, dstVCI id.VC, srcProcess, dstProcess *process) {
dstProcess.AddRoute(dstVCI, &destination{VCI: srcVCI, Process: srcProcess})
srcProcess.AddRoute(srcVCI, &destination{VCI: dstVCI, Process: dstProcess})
@@ -458,24 +436,20 @@
process.Close()
}
}
-
func (p *process) String() string {
r := p.Conn.RemoteAddr()
return fmt.Sprintf("(%s, %s)", r.Network(), r)
}
-
func (p *process) Route(vci id.VC) *destination {
p.mu.RLock()
defer p.mu.RUnlock()
return p.routingTable[vci]
}
-
func (p *process) AddRoute(vci id.VC, d *destination) {
p.mu.Lock()
p.routingTable[vci] = d
p.mu.Unlock()
}
-
func (p *process) InitVCI(vci id.VC) {
p.mu.Lock()
if p.nextVCI <= vci {
@@ -483,7 +457,6 @@
}
p.mu.Unlock()
}
-
func (p *process) AllocVCI() id.VC {
p.mu.Lock()
ret := p.nextVCI
@@ -491,13 +464,11 @@
p.mu.Unlock()
return ret
}
-
func (p *process) RemoveRoute(vci id.VC) {
p.mu.Lock()
delete(p.routingTable, vci)
p.mu.Unlock()
}
-
func (p *process) SendCloseVC(vci id.VC, err error) {
var estr string
if err != nil {
@@ -505,7 +476,6 @@
}
p.Queue.Put(&message.CloseVC{VCI: vci, Error: estr})
}
-
func (p *process) Close() {
p.mu.Lock()
rt := p.routingTable
@@ -514,7 +484,6 @@
vc.Close("net.Conn is closing")
}
p.mu.Unlock()
-
for _, d := range rt {
d.Process.SendCloseVC(d.VCI, errProcessVanished)
}
@@ -522,13 +491,11 @@
p.Queue.Close()
p.Conn.Close()
}
-
func (p *process) ServerVC(vci id.VC) *vc.VC {
p.mu.Lock()
defer p.mu.Unlock()
return p.servers[vci]
}
-
func (p *process) NewServerVC(m *message.OpenVC) *vc.VC {
p.mu.Lock()
defer p.mu.Unlock()
@@ -548,7 +515,6 @@
proxyLog().Infof("Registered VC %v from server on process %v", vc, p)
return vc
}
-
func (p *process) RemoveServerVC(vci id.VC) *vc.VC {
p.mu.Lock()
defer p.mu.Unlock()
@@ -567,7 +533,6 @@
processLog().Infof("Failed to send OpenFlow(%+v) on process %v: %v", msg, p, err)
}
}
-
func (p *process) AddReceiveBuffers(vci id.VC, fid id.Flow, bytes uint) {
if bytes == 0 {
return
@@ -578,7 +543,6 @@
processLog().Infof("Failed to send AddReceiveBuffers(%+v) on process %v: %v", msg, p, err)
}
}
-
func (p *process) NewWriter(vci id.VC, fid id.Flow) (bqueue.Writer, error) {
return p.BQ.NewWriter(packIDs(vci, fid), 0, vc.DefaultBytesBufferedPerFlow)
}
@@ -588,11 +552,9 @@
func processLog() vlog.InfoLog { return vlog.VI(2) }
func vcLog() vlog.InfoLog { return vlog.VI(3) }
func msgLog() vlog.InfoLog { return vlog.VI(4) }
-
func packIDs(vci id.VC, fid id.Flow) bqueue.ID {
return bqueue.ID(message.MakeCounterID(vci, fid))
}
-
func unpackIDs(b bqueue.ID) (id.VC, id.Flow) {
cid := message.CounterID(b)
return cid.VCI(), cid.Flow()
diff --git a/runtimes/google/ipc/stream/proxy/proxy_test.go b/runtimes/google/ipc/stream/proxy/proxy_test.go
index c2ceb14..c28e618 100644
--- a/runtimes/google/ipc/stream/proxy/proxy_test.go
+++ b/runtimes/google/ipc/stream/proxy/proxy_test.go
@@ -10,8 +10,8 @@
_ "veyron/lib/testutil"
"veyron/runtimes/google/ipc/stream/manager"
"veyron/runtimes/google/ipc/stream/proxy"
+ "veyron/runtimes/google/ipc/stream/vc"
- "veyron2"
"veyron2/ipc/stream"
"veyron2/naming"
"veyron2/security"
@@ -142,7 +142,7 @@
server := manager.InternalNew(naming.FixedRoutingID(0x5555555555555555))
defer server.Shutdown()
serverID := security.FakePrivateID("server")
- ln, ep, err := server.Listen(proxy.Endpoint().Network(), proxy.Endpoint().String(), veyron2.LocalID(serverID))
+ ln, ep, err := server.Listen(proxy.Endpoint().Network(), proxy.Endpoint().String(), vc.ListenerID(serverID))
if err != nil {
t.Fatal(err)
}
diff --git a/runtimes/google/ipc/stream/vc/vc.go b/runtimes/google/ipc/stream/vc/vc.go
index f41ce67..f213412 100644
--- a/runtimes/google/ipc/stream/vc/vc.go
+++ b/runtimes/google/ipc/stream/vc/vc.go
@@ -90,6 +90,29 @@
Helper Helper
}
+// ListenerIDOpt is the interface for providing an identity to an ipc.StreamListener.
+type ListenerIDOpt interface {
+ stream.ListenerOpt
+ // Identity returns the identity to be used by the ipc.StreamListener.
+ Identity() security.PrivateID
+}
+
+// listenerIDOpt implements ListenerIDOpt.
+type listenerIDOpt struct {
+ id security.PrivateID
+}
+
+func (opt *listenerIDOpt) Identity() security.PrivateID {
+ return opt.id
+}
+
+func (*listenerIDOpt) IPCStreamListenerOpt() {}
+
+// ListenerID provides an implementation of ListenerIDOpt with a fixed identity.
+func ListenerID(id security.PrivateID) ListenerIDOpt {
+ return &listenerIDOpt{id}
+}
+
// InternalNew creates a new VC, which implements the stream.VC interface.
//
// As the name suggests, this method is intended for use only within packages
@@ -411,8 +434,8 @@
var securityLevel veyron2.VCSecurityLevel
for _, o := range opts {
switch v := o.(type) {
- case veyron2.LocalIDOpt:
- localID = v.PrivateID
+ case ListenerIDOpt:
+ localID = v.Identity()
case veyron2.VCSecurityLevel:
securityLevel = v
}
diff --git a/runtimes/google/ipc/stream/vc/vc_test.go b/runtimes/google/ipc/stream/vc/vc_test.go
index 03b8bd3..91d22ea 100644
--- a/runtimes/google/ipc/stream/vc/vc_test.go
+++ b/runtimes/google/ipc/stream/vc/vc_test.go
@@ -277,7 +277,7 @@
go clientH.pipeLoop(serverH.VC)
go serverH.pipeLoop(clientH.VC)
- c := serverH.VC.HandshakeAcceptedVC(security, veyron2.LocalID(serverID))
+ c := serverH.VC.HandshakeAcceptedVC(security, vc.ListenerID(serverID))
if err := clientH.VC.HandshakeDialedVC(security, veyron2.LocalID(clientID)); err != nil {
panic(err)
}
diff --git a/runtimes/google/ipc/stream/vif/vif_test.go b/runtimes/google/ipc/stream/vif/vif_test.go
index 1038db9..47538f1 100644
--- a/runtimes/google/ipc/stream/vif/vif_test.go
+++ b/runtimes/google/ipc/stream/vif/vif_test.go
@@ -18,6 +18,7 @@
"testing"
_ "veyron/lib/testutil"
+ "veyron/runtimes/google/ipc/stream/vc"
"veyron/runtimes/google/ipc/stream/vif"
iversion "veyron/runtimes/google/ipc/version"
"veyron2"
@@ -428,7 +429,7 @@
if client, err = vif.InternalNewDialedVIF(c1, naming.FixedRoutingID(0xc), clientVersions); err != nil {
panic(err)
}
- serverID := veyron2.LocalID(security.FakePrivateID("server"))
+ serverID := vc.ListenerID(security.FakePrivateID("server"))
if server, err = vif.InternalNewAcceptedVIF(c2, naming.FixedRoutingID(0x5), serverVersions, serverID); err != nil {
panic(err)
}
diff --git a/runtimes/google/ipc/testutil_test.go b/runtimes/google/ipc/testutil_test.go
index 7d6bba3..e726013 100644
--- a/runtimes/google/ipc/testutil_test.go
+++ b/runtimes/google/ipc/testutil_test.go
@@ -5,6 +5,8 @@
"testing"
_ "veyron/lib/testutil"
+
+ "veyron2/security"
"veyron2/verror"
)
@@ -35,3 +37,20 @@
}
}
}
+
+// listenerIDOpt implements vc.ListenerIDOpt and veyron2/ipc.ServerOpt.
+type listenerIDOpt struct {
+ id security.PrivateID
+}
+
+func (opt *listenerIDOpt) Identity() security.PrivateID {
+ return opt.id
+}
+
+func (*listenerIDOpt) IPCStreamListenerOpt() {}
+
+func (*listenerIDOpt) IPCServerOpt() {}
+
+func listenerID(id security.PrivateID) *listenerIDOpt {
+ return &listenerIDOpt{id}
+}
diff --git a/runtimes/google/rt/ipc.go b/runtimes/google/rt/ipc.go
index 5945ded..417f861 100644
--- a/runtimes/google/rt/ipc.go
+++ b/runtimes/google/rt/ipc.go
@@ -14,7 +14,7 @@
func (rt *vrt) NewClient(opts ...ipc.ClientOpt) (ipc.Client, error) {
sm := rt.sm
mt := rt.mt
- id := rt.id
+ cIDOpt := veyron2.LocalID(rt.id.Identity())
var otherOpts []ipc.ClientOpt
for _, opt := range opts {
switch topt := opt.(type) {
@@ -23,13 +23,13 @@
case veyron2.MountTableOpt:
mt = topt.MountTable
case veyron2.LocalIDOpt:
- id = topt
+ cIDOpt = topt
default:
otherOpts = append(otherOpts, opt)
}
}
- if id.PrivateID != nil {
- otherOpts = append(otherOpts, id)
+ if cIDOpt.PrivateID != nil {
+ otherOpts = append(otherOpts, cIDOpt)
}
return iipc.InternalNewClient(sm, mt, otherOpts...)
}
@@ -52,7 +52,6 @@
sm := rt.sm
mt := rt.mt
- idSpecified := false
var otherOpts []ipc.ServerOpt
for _, opt := range opts {
switch topt := opt.(type) {
@@ -60,16 +59,12 @@
sm = topt
case veyron2.MountTableOpt:
mt = topt
- case veyron2.LocalIDOpt:
- idSpecified = true
- otherOpts = append(otherOpts, opt)
default:
otherOpts = append(otherOpts, opt)
}
}
- if !idSpecified && rt.id.PrivateID != nil {
- otherOpts = append(otherOpts, rt.id)
- }
+ // Add the option that provides the identity currently used by the runtime.
+ otherOpts = append(otherOpts, rt.id)
ctx := rt.NewContext()
return iipc.InternalNewServer(ctx, sm, mt, otherOpts...)
diff --git a/runtimes/google/rt/rt.go b/runtimes/google/rt/rt.go
index 19d4871..8c3c18f 100644
--- a/runtimes/google/rt/rt.go
+++ b/runtimes/google/rt/rt.go
@@ -24,7 +24,7 @@
mt naming.MountTable
rid naming.RoutingID
signals chan os.Signal
- id veyron2.LocalIDOpt
+ id *currentIDOpt
client ipc.Client
mgmt *mgmtImpl
}
@@ -64,12 +64,13 @@
// development. We restrict it to localhost to avoid annoying firewall
// warnings and to provide a modicum of security.
rt.httpServer = "127.0.0.1:0"
+ rt.id = ¤tIDOpt{}
mtRoots := []string{}
for _, o := range opts {
switch v := o.(type) {
case veyron2.LocalIDOpt:
- rt.id = v
+ rt.id.setIdentity(v.PrivateID)
case veyron2.ProductOpt:
rt.product = v.T
case veyron2.MountTableRoots:
@@ -114,7 +115,7 @@
return err
}
- if rt.client, err = rt.NewClient(rt.id); err != nil {
+ if rt.client, err = rt.NewClient(veyron2.LocalID(rt.id.Identity())); err != nil {
return err
}
diff --git a/runtimes/google/rt/security.go b/runtimes/google/rt/security.go
index 8971464..b25b95d 100644
--- a/runtimes/google/rt/security.go
+++ b/runtimes/google/rt/security.go
@@ -4,6 +4,7 @@
"fmt"
"os"
"os/user"
+ "sync"
isecurity "veyron/runtimes/google/security"
@@ -11,31 +12,61 @@
"veyron2/vlog"
)
+// currentIDOpt is an option that can be used to pass the identity currently used
+// by the runtime to an ipc.Server or ipc.StreamListener.
+type currentIDOpt struct {
+ id security.PrivateID
+ mu sync.RWMutex
+}
+
+func (id *currentIDOpt) Identity() security.PrivateID {
+ id.mu.RLock()
+ defer id.mu.RUnlock()
+ return id.id
+}
+
+func (id *currentIDOpt) setIdentity(newID security.PrivateID) {
+ // TODO(ataly): Whenever setIdentity is invoked on the identity currently used by
+ // the runtime, the following changes must also be performed:
+ // * the identity provider of the new identity must be tursted.
+ // * the default client used by the runtime must also be replaced with
+ // a client using the new identity.
+ id.mu.Lock()
+ defer id.mu.Unlock()
+ id.id = newID
+}
+
+func (*currentIDOpt) IPCServerOpt() {}
+
+func (*currentIDOpt) IPCStreamListenerOpt() {}
+
func (rt *vrt) NewIdentity(name string) (security.PrivateID, error) {
return isecurity.NewPrivateID(name)
}
func (rt *vrt) Identity() security.PrivateID {
- return rt.id.PrivateID
+ return rt.id.Identity()
}
func (rt *vrt) initIdentity() error {
- if rt.id.PrivateID == nil {
+ if rt.id.Identity() == nil {
+ var id security.PrivateID
var err error
if file := os.Getenv("VEYRON_IDENTITY"); len(file) > 0 {
- if rt.id.PrivateID, err = loadIdentityFromFile(file); err != nil {
+ if id, err = loadIdentityFromFile(file); err != nil {
return fmt.Errorf("Could not load identity from %q: %v", file, err)
}
} else {
name := defaultIdentityName()
vlog.VI(2).Infof("No identity provided to the runtime, minting one for %q", name)
- if rt.id.PrivateID, err = rt.NewIdentity(name); err != nil {
+ if id, err = rt.NewIdentity(name); err != nil {
return fmt.Errorf("Could not create new identity: %v", err)
}
}
+ rt.id.setIdentity(id)
}
// Always trust our own identity providers.
- trustIdentityProviders(rt.id.PrivateID)
+ trustIdentityProviders(rt.id.Identity())
return nil
}