/** * Returns AcceptorNotLive if the node does not have an open acceptor. */ func NewRegNode(node *xn.Node, commsKey, sigKey *rsa.PrivateKey) ( q *RegNode, err error) { var acc xt.AcceptorI if node == nil { err = NilNode // We would prefer that the node's name be xlReg and that its // LFS default to /var/app/xlReg. } else { acc = node.GetAcceptor(0) if acc == nil { err = xm.AcceptorNotLive } if err == nil { stopCh := make(chan bool, 1) stoppedCh := make(chan bool, 1) q = &RegNode{ Acc: acc, StopCh: stopCh, StoppedCh: stoppedCh, ckPriv: commsKey, skPriv: sigKey, Node: *node, } } } return }
func NewMessagingNode(n *xn.Node, stopCh, stoppedCh chan bool) ( mn *MessagingNode, err error) { var k int if n == nil { err = NilNode } if err == nil { if k = n.SizePeers(); k == 0 { err = NoPeers } } tcpAcc := n.GetAcceptor(0).(*xt.TcpAcceptor) if err == nil && tcpAcc == nil { err = AcceptorNotLive } if err == nil && stopCh == nil { err = NilControlCh } if err == nil { mn = &MessagingNode{ Acc: tcpAcc, K: k, StopCh: stopCh, StoppedCh: stoppedCh, Node: *n, } } return }
func (s *XLSuite) makeALocalEndPoint(c *C, node *xn.Node) { addr := fmt.Sprintf("127.0.0.1:0") ep, err := xt.NewTcpEndPoint(addr) c.Assert(err, IsNil) c.Assert(ep, Not(IsNil)) ndx, err := node.AddEndPoint(ep) c.Assert(err, IsNil) c.Assert(ndx, Equals, 0) // it's the only one }
func MakeHelloMsg(n *xn.Node) (m *XLatticeMsg, err error) { var ck, sk, salt, sig []byte cmd := XLatticeMsg_Hello id := n.GetNodeID().Value() ck, err = xc.RSAPubKeyToWire(n.GetCommsPublicKey()) if err == nil { sk, err = xc.RSAPubKeyToWire(n.GetSigPublicKey()) } if err == nil { sysRNG := xr.MakeSystemRNG() salt = make([]byte, 8) sysRNG.NextBytes(salt) chunks := [][]byte{id, ck, sk, salt} sig, err = n.Sign(chunks) } if err == nil { m = &XLatticeMsg{ Op: &cmd, MsgN: &ONE, ID: id, CommsKey: ck, SigKey: sk, Salt: salt, Sig: sig, } } return }
// Given contact information for a registry and the name of a cluster, // the client joins the cluster, collects information on the other members, // and terminates when it has info on the entire membership. func NewMemberMaker( node *xn.Node, attrs uint64, regName string, regID *xi.NodeID, regEnd xt.EndPointI, regCK, regSK *rsa.PublicKey, clusterName string, clusterAttrs uint64, clusterID *xi.NodeID, size, epCount uint32, endPoints []xt.EndPointI) ( mm *MemberMaker, err error) { var ( cm *xcl.ClusterMember isAdmin = (attrs & xcl.ATTR_ADMIN) != 0 regPeer *xn.Peer ) // sanity checks on parameter list if node == nil { err = MissingNode } else { if regName == "" || regID == nil || regEnd == nil || regCK == nil { err = MissingServerInfo } if err == nil { // DEBUG fmt.Printf("NemMemberMaker: regEnd is %s\n", regEnd.String()) // END if (attrs & xcl.ATTR_SOLO) == uint64(0) { if clusterName == "" { err = MissingClusterNameOrID if err == nil && size < uint32(1) { // err = ClusterMustHaveTwo err = ClusterMustHaveMember } } if err == nil { // if the client is an admin client epCount applies // to the cluster if epCount < uint32(1) { epCount = uint32(1) } if !isAdmin { // XXX There is some confusion here: we don't require // that all members have the same number of endpoints actualEPCount := uint32(len(endPoints)) if actualEPCount == 0 { err = MemberMustHaveEndPoint } else if epCount > actualEPCount { epCount = actualEPCount } for i := 0; i < int(epCount); i++ { _, err = node.AddEndPoint(endPoints[i]) } } } } } } if err == nil { var ctor xt.ConnectorI var ctors []xt.ConnectorI ctor, err = xt.NewTcpConnector(regEnd) if err == nil { ctors = append(ctors, ctor) regPeer, err = xn.NewPeer(regName, regID, regCK, regSK, nil, ctors) if err == nil { _, err = node.AddPeer(regPeer) } } } if err == nil { cm = &xcl.ClusterMember{ // Attrs gets negotiated ClusterName: clusterName, ClusterAttrs: clusterAttrs, ClusterID: clusterID, ClusterMaxSize: size, EPCount: epCount, // Members added on the fly Members: make([]*xcl.MemberInfo, size), Node: *node, } mm = &MemberMaker{ ProposedAttrs: attrs, DoneCh: make(chan error, 1), RegPeer: regPeer, ClusterMember: *cm, } } return }
func (h *InHandler) handleHello(n *xn.Node) (err error) { var ( m *XLatticeMsg msgN uint64 id, ck, sk, sig, salt []byte peer *xn.Peer ) m, err = h.readMsg() // message must be a Hello if err == nil { if m.GetOp() != XLatticeMsg_Hello { err = MissingHello } } if err == nil { // the message is a hello; is its NodeID that of a known peer? id = m.GetID() if id == nil { // DEBUG fmt.Printf("handleHello: message has no ID field\n") // END err = NilPeer } else { peer, err = n.FindPeer(id) if err == nil { if peer == nil { err = xn.NotAKnownPeer } else { h.Peer = peer } } } } // On any error up to here silently close the connection and delete // the handler. if err != nil { h.Cnx.Close() h = nil return } // message is a hello from a known peer ------------------------- // MsgN must be 1 msgN = m.GetMsgN() h.MsgN = msgN ck = m.GetCommsKey() // comms key as byte slice sk = m.GetSigKey() // sig key as byte slice salt = m.GetSalt() sig = m.GetSig() // digital signature var serCK, serSK []byte if h.MsgN != 1 { err = ExpectedMsgOne } if err == nil { peerID := peer.GetNodeID().Value() if !bytes.Equal(id, peerID) { fmt.Println("NOT SAME NODE ID") // XXX should log err = NotExpectedNodeID } } if err == nil { serCK, err = xc.RSAPubKeyToWire(peer.GetCommsPublicKey()) if err == nil { if !bytes.Equal(serCK, ck) { fmt.Println("NOT SAME COMMS KEY") // XXX should log err = NotExpectedCommsKey } } } if err == nil { serSK, err = xc.RSAPubKeyToWire(peer.GetSigPublicKey()) if err == nil { if !bytes.Equal(serSK, sk) { fmt.Println("NOT SAME SIG KEY") // XXX should log err = NotExpectedSigKey } } } if err == nil { sigPubKey := peer.GetSigPublicKey() d := sha1.New() d.Write(id) d.Write(ck) d.Write(sk) d.Write(salt) hash := d.Sum(nil) err = rsa.VerifyPKCS1v15(sigPubKey, cr.SHA1, hash, sig) } if err == nil { // Everything is good; so Ack, leaving cnx open. h.Peer.MarkUp() // we consider the peer live h.Peer.LastContact() err = h.simpleAck(msgN) } else { // Send the text of the error to the peer; the send itself // may of course cause an error, but we will ignore that. // The peer is NOT marked as up. h.errorReply(err) } return }
/** * Parse a serialized RegNode, returning one with an open acceptor. */ func ParseRegNodeFromStrings(ss []string) ( rn *RegNode, rest []string, err error) { var ( line string node *xn.Node ckPriv *rsa.PrivateKey skPriv *rsa.PrivateKey ) rest = ss line, err = xc.NextNBLine(&rest) if (err == nil) && (line != "regNode {") { err = MissingRegNodeLine } else { node, rest, err = xn.ParseFromStrings(rest) if err == nil { line, err = xc.NextNBLine(&rest) if err == nil { parts := strings.Split(line, ": ") if parts[0] == "ckPriv" && parts[1] == "-----BEGIN -----" { ckPriv, err = xn.ExpectRSAPrivateKey(&rest) } else { err = MissingPrivateKey } if err == nil { line, err = xc.NextNBLine(&rest) if err == nil { parts := strings.Split(line, ": ") if parts[0] == "skPriv" && parts[1] == "-----BEGIN -----" { skPriv, err = xn.ExpectRSAPrivateKey(&rest) } else { err = MissingPrivateKey } if err == nil { line, err = xc.NextNBLine(&rest) if (err == nil) && (line != "}") { err = MissingClosingBrace } if err == nil { // Try to open the acceptor. err = node.OpenAcc() if err == nil { rn, err = NewRegNode(node, ckPriv, skPriv) } } } } } } } } return }
func NewEphServer() (ms *EphServer, err error) { // Create an XLattice node with quasi-random parameters including // low-quality keys and an endPoint in 127.0.0.1, localhost. var ( ckPriv, skPriv *rsa.PrivateKey rn *RegNode ep *xt.TcpEndPoint node *xn.Node reg *Registry server *RegServer ) rng := xr.MakeSimpleRNG() name := rng.NextFileName(16) idBuf := make([]byte, xu.SHA1_BIN_LEN) rng.NextBytes(idBuf) lfs := "tmp/" + hex.EncodeToString(idBuf) id, err := xi.New(nil) if err == nil { // XXX cheap keys, too weak for any serious use ckPriv, err = rsa.GenerateKey(rand.Reader, 1024) if err == nil { skPriv, err = rsa.GenerateKey(rand.Reader, 1024) } } if err == nil { ep, err = xt.NewTcpEndPoint("127.0.0.1:0") eps := []xt.EndPointI{ep} if err == nil { node, err = xn.New(name, id, lfs, ckPriv, skPriv, nil, eps, nil) if err == nil { err = node.OpenAcc() // so acceptors are now live if err == nil { rn, err = NewRegNode(node, ckPriv, skPriv) if err == nil { // DEBUG if rn == nil { fmt.Println("regNode is NIL!\n") } else { fmt.Printf("eph server listening on %s\n", rn.GetAcceptor(0).String()) } // END // a registry with no clusters and no logger opt := &RegOptions{ EndPoint: ep, // not used Ephemeral: true, GlobalEndPoint: node.GetEndPoint(0), Lfs: lfs, // redundant (is in node's BaseNode) Logger: nil, K: DEFAULT_K, M: DEFAULT_M, } reg, err = NewRegistry(nil, rn, opt) if err == nil { server, err = NewRegServer(reg, true, 1) if err == nil { ms = &EphServer{ acc: rn.GetAcceptor(0), Server: server, } } } } } } } } return }
func setup(opt *reg.RegOptions) (rs *reg.RegServer, err error) { // If LFS/.xlattice/reg.config exists, we load that. Otherwise we // create a node. In either case we force the node to listen on // the designated port var ( e []xt.EndPointI node *xn.Node pathToConfigFile string rn *reg.RegNode ckPriv, skPriv *rsa.PrivateKey ) logger := opt.Logger verbose := opt.Verbose greetings := fmt.Sprintf("xlReg v%s %s start run\n", reg.VERSION, reg.VERSION_DATE) if verbose { fmt.Print(greetings) } logger.Print(greetings) pathToConfigFile = path.Join(path.Join(opt.Lfs, ".xlattice"), "reg.config") found, err := xf.PathExists(pathToConfigFile) if err == nil { if found { logger.Printf("Loading existing reg config from %s\n", pathToConfigFile) // The registry node already exists. Parse it and we are done. var data []byte data, err = ioutil.ReadFile(pathToConfigFile) if err == nil { rn, _, err = reg.ParseRegNode(string(data)) } } else { logger.Println("No config file found, creating new registry.") // We need to create a registry node from scratch. nodeID, _ := xi.New(nil) ep, err := xt.NewTcpEndPoint(opt.Address + ":" + opt.Port) if err == nil { e = []xt.EndPointI{ep} ckPriv, err = rsa.GenerateKey(rand.Reader, 2048) if err == nil { skPriv, err = rsa.GenerateKey(rand.Reader, 2048) } if err == nil { node, err = xn.New("xlReg", nodeID, opt.Lfs, ckPriv, skPriv, nil, e, nil) if err == nil { node.OpenAcc() // XXX needs a complementary close if err == nil { // DEBUG fmt.Printf("XLattice node successfully created\n") fmt.Printf(" listening on %s\n", ep.String()) // END rn, err = reg.NewRegNode(node, ckPriv, skPriv) if err == nil { // DEBUG fmt.Printf("regNode successfully created\n") // END err = xf.MkdirsToFile(pathToConfigFile, 0700) if err == nil { err = ioutil.WriteFile(pathToConfigFile, []byte(rn.String()), 0400) // DEBUG } else { fmt.Printf("error writing config file: %v\n", err.Error()) } // END -------------- // DEBUG } else { fmt.Printf("error creating regNode: %v\n", err.Error()) // END } } } } } } } if err == nil { var r *reg.Registry r, err = reg.NewRegistry(nil, // nil = clusters so far rn, opt) // regNode, options if err == nil { logger.Printf("Registry name: %s\n", rn.GetName()) logger.Printf(" ID: %s\n", rn.GetNodeID().String()) } if err == nil { var verbosity int if opt.Verbose { verbosity++ } rs, err = reg.NewRegServer(r, opt.Testing, verbosity) } } if err != nil { logger.Printf("ERROR: %s\n", err.Error()) } return }