package garage import ( "crypto/ed25519" "encoding/hex" "fmt" "net" "strconv" ) // Peer describes all information necessary to connect to a given garage node. type Peer struct { IP string RPCPort int S3APIPort int } // RPCPeerKey deterministically generates a public/private keys which can // be used as a garage node key. // // DANGER: This function will deterministically produce public/private keys // given some arbitrary input. This is NEVER what you want. It's only being used // in cryptic-net for a very specific purpose for which I think it's ok and is // very necessary, and people are probably _still_ going to yell at me. // func (p Peer) RPCPeerKey() (pubKey, privKey []byte) { input := []byte(net.JoinHostPort(p.IP, strconv.Itoa(p.RPCPort))) // Append the length of the input to the input, so that the input "foo" // doesn't generate the same key as the input "foofoo". input = strconv.AppendInt(input, int64(len(input)), 10) pubKey, privKey, err := ed25519.GenerateKey(NewInfiniteReader(input)) if err != nil { panic(err) } return pubKey, privKey } // RPCPeerID returns the peer ID of the garage node for use in communicating // over RPC. // // DANGER: See warning on RPCPeerKey. func (p Peer) RPCPeerID() string { pubKey, _ := p.RPCPeerKey() return hex.EncodeToString(pubKey) } // RPCAddr returns the address of the peer's RPC port. func (p Peer) RPCAddr() string { return net.JoinHostPort(p.IP, strconv.Itoa(p.RPCPort)) } // RPCPeerAddr returns the full peer address (e.g. "id@ip:port") of the garage // node for use in communicating over RPC. // // DANGER: See warning on RPCPeerKey. func (p Peer) RPCPeerAddr() string { return fmt.Sprintf("%s@%s", p.RPCPeerID(), p.RPCAddr()) } // S3APIAddr returns the address of the peer's S3 API port. func (p Peer) S3APIAddr() string { return net.JoinHostPort(p.IP, strconv.Itoa(p.S3APIPort)) }