Skip to content
Snippets Groups Projects
Commit c11a0a19 authored by Jonah Husson's avatar Jonah Husson
Browse files

Update cmd broadcast for superchannels

parent ad51cc3e
No related branches found
No related tags found
3 merge requests!510Release,!229Make the payload returned by NewSizedBroadcast include the extra padding so...,!207WIP: Client Restructure
......@@ -23,7 +23,7 @@ const (
)
// MaxAsymmetricPayloadSize returns the maximum size for an asymmetric broadcast payload
func (bc *broadcastClient) MaxAsymmetricPayloadSize() int {
func (bc *broadcastClient) maxAsymmetricPayload() int {
return bc.maxParts() * bc.channel.MaxAsymmetricPayloadSize()
}
......@@ -42,9 +42,9 @@ func (bc *broadcastClient) BroadcastAsymmetric(pk multicastRSA.PrivateKey, paylo
return 0, ephemeral.Id{}, errors.New(errNetworkHealth)
}
if len(payload) != bc.MaxAsymmetricPayloadSize() {
if len(payload) != bc.maxAsymmetricPayload() {
return 0, ephemeral.Id{},
errors.Errorf(errPayloadSize, len(payload), bc.MaxAsymmetricPayloadSize())
errors.Errorf(errPayloadSize, len(payload), bc.maxAsymmetricPayload())
}
numParts := bc.maxParts()
......
......@@ -73,7 +73,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) {
// Send broadcast from each client
for i := range clients {
payload := make([]byte, clients[i].MaxAsymmetricPayloadSize())
payload := make([]byte, clients[i].MaxPayloadSize())
copy(payload,
fmt.Sprintf("Hello from client %d of %d.", i, len(clients)))
......@@ -112,7 +112,7 @@ func Test_asymmetricClient_Smoke(t *testing.T) {
clients[i].Stop()
}
payload := make([]byte, clients[0].MaxAsymmetricPayloadSize())
payload := make([]byte, clients[0].MaxPayloadSize())
copy(payload, "This message should not get through.")
// Start waiting on channels and error if anything is received
......
......@@ -98,3 +98,14 @@ func (bc *broadcastClient) verifyID() bool {
}
return bc.channel.ReceptionID.Cmp(gen)
}
func (bc *broadcastClient) MaxPayloadSize() int {
switch bc.param.Method {
case Symmetric:
return bc.maxSymmetricPayload()
case Asymmetric:
return bc.maxAsymmetricPayload()
default:
return -1
}
}
......@@ -26,11 +26,8 @@ type ListenerFunc func(payload []byte,
receptionID receptionID.EphemeralIdentity, round rounds.Round)
type Channel interface {
// MaxSymmetricPayloadSize returns the maximum size for a symmetric broadcast payload.
MaxSymmetricPayloadSize() int
// MaxAsymmetricPayloadSize returns the maximum size for an asymmetric broadcast payload.
MaxAsymmetricPayloadSize() int
// MaxPayloadSize returns the maximum size for a broadcast payload. Different math depending on broadcast method.
MaxPayloadSize() int
// Get returns the underlying crypto.Channel
Get() crypto.Channel
......@@ -41,7 +38,7 @@ type Channel interface {
id.Round, ephemeral.Id, error)
// BroadcastAsymmetric broadcasts an asymmetric payload to the channel. The payload size must be
// equal to MaxPayloadSize.
// equal to MaxPayloadSize & private key for channel must be passed in
BroadcastAsymmetric(pk multicastRSA.PrivateKey, payload []byte, cMixParams cmix.CMIXParams) (
id.Round, ephemeral.Id, error)
......
......@@ -30,7 +30,7 @@ const (
)
// MaxSymmetricPayloadSize returns the maximum size for a broadcasted payload.
func (bc *broadcastClient) MaxSymmetricPayloadSize() int {
func (bc *broadcastClient) maxSymmetricPayload() int {
return bc.net.GetMaxMessageLength()
}
......@@ -48,9 +48,9 @@ func (bc *broadcastClient) Broadcast(payload []byte, cMixParams cmix.CMIXParams)
return 0, ephemeral.Id{}, errors.New(errNetworkHealth)
}
if len(payload) != bc.MaxSymmetricPayloadSize() {
if len(payload) != bc.maxSymmetricPayload() {
return 0, ephemeral.Id{},
errors.Errorf(errPayloadSize, len(payload), bc.MaxSymmetricPayloadSize())
errors.Errorf(errPayloadSize, len(payload), bc.maxSymmetricPayload())
}
// Encrypt payload
......
......@@ -18,9 +18,9 @@ import (
// singleCmd is the single-use subcommand that allows for sending and responding
// to single-use messages.
var symmetricCmd = &cobra.Command{
Use: "symmetric",
Short: "Send symmetric broadcast messages",
var broadcastCmd = &cobra.Command{
Use: "broadcast",
Short: "Send broadcast messages",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
client := initClient()
......@@ -44,21 +44,23 @@ var symmetricCmd = &cobra.Command{
})
waitUntilConnected(connected)
// Create new symmetric or load from path if exists
path, err := utils.ExpandPath(viper.GetString("path"))
var symmetric *crypto.Symmetric
/* Set up underlying crypto broadcast.Channel */
var channel *crypto.Channel
var pk *rsa.PrivateKey
keyPath := viper.GetString("keyPath")
path, err := utils.ExpandPath(viper.GetString("chanPath"))
if utils.Exists(path) {
// Load symmetric from path
symmBytes, err := utils.ReadFile(path)
cBytes, err := utils.ReadFile(path)
if err != nil {
jww.FATAL.Panicf("Failed to read channel from file at %s: %+v", path, err)
}
symmetric, err = crypto.UnmarshalSymmetric(symmBytes)
channel, err = crypto.UnmarshalChannel(cBytes)
if err != nil {
jww.FATAL.Panicf("Failed to unmarshal channel data %+v: %+v", cBytes, err)
}
} else {
// New symmetric
// Load in broadcast channel info
name := viper.GetString("name")
desc := viper.GetString("description")
if name == "" {
......@@ -67,52 +69,80 @@ var symmetricCmd = &cobra.Command{
jww.FATAL.Panicf("description cannot be empty")
}
var pubKey *rsa.PublicKey
var salt, pubKeyBytes []byte
var channel *crypto.Channel
if viper.GetBool("new") {
privKey, err := rsa.GenerateKey(client.GetRng().GetStream(), rsa.DefaultRSABitLen)
// Create a new broadcast channel
channel, pk, err = crypto.NewChannel(name, desc, client.GetRng().GetStream())
if err != nil {
// TODO
}
if keyPath != "" {
err = utils.WriteFile(path, rsa.CreatePrivateKeyPem(pk), os.ModePerm, os.ModeDir)
if err != nil {
// TODO
}
} else {
fmt.Printf("Private key generated for channel: %+v", rsa.CreatePrivateKeyPem(pk))
}
pubKey = privKey.GetPublic()
pubKeyBytes = rsa.CreatePublicKeyPem(pubKey)
} else {
// Read rest of info from config & build object manually
pubKeyBytes := []byte(viper.GetString("rsaPub"))
pubKey, err = rsa.LoadPublicKeyFromPem(pubKeyBytes)
pubKey, err := rsa.LoadPublicKeyFromPem(pubKeyBytes)
if err != nil {
// TODO
}
salt := []byte(viper.GetString("salt"))
rid, err := crypto.NewChannelID(name, desc, salt, pubKeyBytes)
if err != nil {
// TODO
}
salt = []byte(viper.GetString("salt"))
}
rid, err := crypto.NewSymmetricID(name, desc, salt, pubKeyBytes)
if err != nil {
channel = &crypto.Channel{
ReceptionID: rid,
Name: name,
Description: desc,
Salt: salt,
RsaPubKey: pubKey,
}
}
// Load key if it's there
if keyPath != "" {
if ep, err := utils.ExpandPath(keyPath); err == nil {
keyBytes, err := utils.ReadFile(ep)
if err != nil {
// TODO
}
pk, err = rsa.LoadPrivateKeyFromPem(keyBytes)
if err != nil {
// TODO
}
} else {
// TODO
}
symmetric = &crypto.Symmetric{
ReceptionID: rid,
Name: name,
Description: desc,
Salt: salt,
RsaPubKey: pubKey,
}
}
symmBytes, err := symmetric.Marshal()
// Save channel to disk
cBytes, err := channel.Marshal()
if err != nil {
// TODO
}
// Write to file if there
if path != "" {
err = utils.WriteFile(path, symmBytes, os.ModePerm, os.ModeDir)
err = utils.WriteFile(path, cBytes, os.ModePerm, os.ModeDir)
if err != nil {
// TODO
}
} else {
fmt.Printf("Symmetric marshalled: %+v", symmBytes)
fmt.Printf("Channel marshalled: %+v", cBytes)
}
}
/* Broadcast client setup */
// Create receiver callback
receiveChan := make(chan []byte, 100)
cb := func(payload []byte,
......@@ -121,24 +151,56 @@ var symmetricCmd = &cobra.Command{
receiveChan <- payload
}
// Connect to symmetric broadcast channel
scl := broadcast.NewSymmetricClient(*symmetric, cb, client.GetNetworkInterface(), client.GetRng())
// Select broadcast method
var method broadcast.Method
symmetric := viper.GetBool("symmetric")
asymmetric := viper.GetBool("asymmetric")
if symmetric && asymmetric {
jww.FATAL.Panicf("Cannot simultaneously broadcast symmetric & asymmetric")
}
if symmetric {
method = broadcast.Symmetric
} else if asymmetric {
method = broadcast.Asymmetric
}
// Connect to broadcast channel
bcl, err := broadcast.NewBroadcastChannel(*channel, cb, client.GetNetworkInterface(), client.GetRng(), broadcast.Param{Method: method})
/* Create properly sized broadcast message */
message := viper.GetString("broadcast")
fmt.Println(message)
// Send a broadcast over the channel
var broadcastMessage []byte
if message != "" {
broadcastMessage, err := broadcast.NewSizedBroadcast(scl.MaxPayloadSize(), []byte(message))
broadcastMessage, err = broadcast.NewSizedBroadcast(bcl.MaxPayloadSize(), []byte(message))
if err != nil {
jww.ERROR.Printf("Failed to create sized broadcast: %+v", err)
}
rid, eid, err := scl.Broadcast(broadcastMessage, cmix.GetDefaultCMIXParams())
}
/* Broadcast message to the channel */
switch method {
case broadcast.Symmetric:
rid, eid, err := bcl.Broadcast(broadcastMessage, cmix.GetDefaultCMIXParams())
if err != nil {
jww.ERROR.Printf("Failed to send symmetric broadcast message: %+v", err)
}
jww.INFO.Printf("Sent symmetric broadcast message to %s over round %d", eid, rid)
case broadcast.Asymmetric:
if pk == nil {
jww.FATAL.Panicf("CANNOT SEND ASYMMETRIC BROADCAST WITHOUT PRIVATE KEY")
}
rid, eid, err := bcl.BroadcastAsymmetric(pk, broadcastMessage, cmix.GetDefaultCMIXParams())
if err != nil {
jww.ERROR.Printf("Failed to send asymmetric broadcast message: %+v", err)
}
jww.INFO.Printf("Sent asymmetric broadcast message to %s over round %d", eid, rid)
default:
jww.WARN.Printf("Unknown broadcast type (this should not happen)")
}
// Receive messages over the channel
/* Receive broadcast messages over the channel */
waitSecs := viper.GetUint("waitTimeout")
expectedCnt := viper.GetUint("receiveCount")
waitTimeout := time.Duration(waitSecs) * time.Second
......@@ -166,7 +228,7 @@ var symmetricCmd = &cobra.Command{
}
jww.INFO.Printf("Received %d/%d Messages!", receivedCount, expectedCnt)
scl.Stop()
bcl.Stop()
err = client.StopNetworkFollower()
if err != nil {
jww.WARN.Printf(
......@@ -178,33 +240,45 @@ var symmetricCmd = &cobra.Command{
func init() {
// Single-use subcommand options
symmetricCmd.Flags().StringP("name", "", "",
broadcastCmd.Flags().StringP("name", "", "",
"Symmetric channel name")
_ = viper.BindPFlag("name", symmetricCmd.Flags().Lookup("name"))
_ = viper.BindPFlag("name", broadcastCmd.Flags().Lookup("name"))
symmetricCmd.Flags().StringP("rsaPub", "", "",
broadcastCmd.Flags().StringP("rsaPub", "", "",
"Symmetric channel rsa pub key")
_ = viper.BindPFlag("rsaPub", symmetricCmd.Flags().Lookup("rsaPub"))
_ = viper.BindPFlag("rsaPub", broadcastCmd.Flags().Lookup("rsaPub"))
symmetricCmd.Flags().StringP("salt", "", "",
broadcastCmd.Flags().StringP("salt", "", "",
"Symmetric channel salt")
_ = viper.BindPFlag("salt", symmetricCmd.Flags().Lookup("salt"))
_ = viper.BindPFlag("salt", broadcastCmd.Flags().Lookup("salt"))
symmetricCmd.Flags().StringP("description", "", "",
broadcastCmd.Flags().StringP("description", "", "",
"Symmetric channel description")
_ = viper.BindPFlag("description", symmetricCmd.Flags().Lookup("description"))
_ = viper.BindPFlag("description", broadcastCmd.Flags().Lookup("description"))
symmetricCmd.Flags().StringP("path", "", "",
broadcastCmd.Flags().StringP("chanPath", "", "",
"Symmetric channel output path")
_ = viper.BindPFlag("path", symmetricCmd.Flags().Lookup("path"))
_ = viper.BindPFlag("chanPath", broadcastCmd.Flags().Lookup("chanPath"))
symmetricCmd.Flags().BoolP("new", "", false,
broadcastCmd.Flags().StringP("keyPath", "", "",
"Symmetric channel private key output path")
_ = viper.BindPFlag("keyPath", broadcastCmd.Flags().Lookup("keyPath"))
broadcastCmd.Flags().BoolP("new", "", false,
"Create new symmetric channel")
_ = viper.BindPFlag("new", symmetricCmd.Flags().Lookup("new"))
_ = viper.BindPFlag("new", broadcastCmd.Flags().Lookup("new"))
symmetricCmd.Flags().StringP("broadcast", "", "",
broadcastCmd.Flags().StringP("broadcast", "", "",
"Message to send via symmetric broadcast")
_ = viper.BindPFlag("broadcast", symmetricCmd.Flags().Lookup("broadcast"))
_ = viper.BindPFlag("broadcast", broadcastCmd.Flags().Lookup("broadcast"))
broadcastCmd.Flags().BoolP("symmetric", "", false,
"Set broadcast method to symmetric")
_ = viper.BindPFlag("symmetric", broadcastCmd.Flags().Lookup("symmetric"))
broadcastCmd.Flags().BoolP("asymmetric", "", false,
"Set broadcast method to asymmetric")
_ = viper.BindPFlag("asymmetric", broadcastCmd.Flags().Lookup("asymmetric"))
rootCmd.AddCommand(symmetricCmd)
rootCmd.AddCommand(broadcastCmd)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment