func (cash *connectionAwaitServerHandshake) start() (bool, error) { topology := cash.connectionManager.Topology() helloFromServer := cash.makeHelloFromServer(topology) if err := cash.send(server.SegToBytes(helloFromServer)); err != nil { return cash.connectionAwaitHandshake.maybeRestartConnection(err) } if seg, err := cash.readAndDecryptOne(); err == nil { hello := msgs.ReadRootHelloFromServer(seg) if verified, remoteTopology := cash.verifyTopology(topology, &hello); verified { cash.Lock() cash.established = true cash.remoteHost = hello.LocalHost() ns := hello.Namespace() cash.remoteBootCount = binary.BigEndian.Uint32(ns[4:8]) cash.remoteRMId = common.RMId(binary.BigEndian.Uint32(ns[8:12])) cash.combinedTieBreak = cash.combinedTieBreak ^ hello.TieBreak() cash.remoteTopology = remoteTopology cash.Unlock() cash.nextState(nil) return false, nil } else { return cash.connectionAwaitHandshake.maybeRestartConnection(fmt.Errorf("Unequal remote topology")) } } else { return cash.connectionAwaitHandshake.maybeRestartConnection(err) } }
func (cash *connectionAwaitServerHandshake) start() (bool, error) { seg := capn.NewBuffer(nil) hello := msgs.NewRootHelloFromClient(seg) hello.SetUsername(cash.username) hello.SetPassword(cash.password) cash.username = "" cash.password = nil buf := new(bytes.Buffer) if _, err := seg.WriteTo(buf); err != nil { return false, err } if err := cash.send(buf.Bytes()); err != nil { return false, err } if seg, err := cash.readAndDecryptOne(); err == nil { server := msgs.ReadRootHelloFromServer(seg) root := server.Root() if len(root.Id()) != common.KeyLen { return false, fmt.Errorf("Root object VarUUId is of wrong length!") } cash.lock.Lock() cash.rootVUUId = common.MakeVarUUId(root.Id()) cash.namespace = make([]byte, common.KeyLen) copy(cash.namespace[8:], server.Namespace()) cash.serverHost = server.LocalHost() cash.rmId = common.RMId(binary.BigEndian.Uint32(cash.namespace[16:20])) cash.lock.Unlock() cash.nextState() return false, nil } else { return false, err } }