diff --git a/api/client.go b/api/client.go index 44ad2643ccb1d3a2cfd167ae6e0ee1207f81afb3..64c474d6910aaae6e3239693de67285462686803 100644 --- a/api/client.go +++ b/api/client.go @@ -42,13 +42,14 @@ import ( ) type Client struct { - storage globals.Storage - session user.Session - commManager *io.CommManager - ndf *ndf.NetworkDefinition - topology *circuit.Circuit - opStatus OperationProgressCallback - rekeyChan chan struct{} + storage globals.Storage + session user.Session + commManager *io.CommManager + ndf *ndf.NetworkDefinition + topology *circuit.Circuit + opStatus OperationProgressCallback + rekeyChan chan struct{} + registrationVersion string } var noNDFErr = errors.New("Failed to get ndf from permissioning: rpc error: code = Unknown desc = Permissioning server does not have an ndf to give to client") @@ -143,9 +144,9 @@ func requestNdf(cl *Client) error { return errMsg } - cl.ndf = newNDf - - cl.commManager.UpdateNDF(newNDf) + if newNDf != nil { + cl.ndf = newNDf + } return nil } @@ -174,7 +175,7 @@ func NewClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinit cl := new(Client) cl.storage = store - cl.commManager = io.NewCommManager(ndfJSON) + cl.commManager = io.NewCommManager() cl.ndf = ndfJSON //build the topology nodeIDs := make([]*id.Node, len(cl.ndf.Nodes)) @@ -197,11 +198,8 @@ func NewClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinit return cl, nil } -// DisableTLS makes the client run with TLS disabled -// Must be called before Connect -func (cl *Client) DisableTLS() { - globals.Log.INFO.Println("Running client without tls") - cl.commManager.DisableTLS() +func (cl *Client) GetRegistrationVersion() string { // on client + return cl.registrationVersion } //GetNDF returns the clients ndf @@ -211,10 +209,10 @@ func (cl *Client) GetNDF() *ndf.NetworkDefinition { // Checks version and connects to gateways using TLS filepaths to create // credential information for connection establishment -func (cl *Client) Connect() error { - //Connect to permissioning +func (cl *Client) InitNetwork() error { + //InitNetwork to permissioning if cl.ndf.Registration.Address != "" { - isConnected, err := cl.commManager.ConnectToPermissioning() + isConnected, err := cl.commManager.AddPermissioningHost(&cl.ndf.Registration) if err != nil { return err @@ -223,11 +221,13 @@ func (cl *Client) Connect() error { err = errors.New("Couldn't connect to permissioning") return err } - //Check if versioning is up to date - err = cl.commManager.UpdateRemoteVersion() + //Get remote version and update + ver, err := cl.commManager.GetRemoteVersion() if err != nil { return err } + cl.registrationVersion = ver + //Request a new ndf from err = requestNdf(cl) if err != nil { @@ -247,14 +247,14 @@ func (cl *Client) Connect() error { cl.topology = circuit.New(nodeIDs) // Only check the version if we got a remote version // The remote version won't have been populated if we didn't connect to permissioning - if cl.commManager.GetRegistrationVersion() != "" { - ok, err := cl.commManager.CheckVersion() + if cl.GetRegistrationVersion() != "" { + ok, err := globals.CheckVersion(cl.GetRegistrationVersion()) if err != nil { return err } if !ok { err = errors.Errorf("Couldn't connect to gateways: Versions incompatible; Local version: %v; remote version: %v", globals.SEMVER, - cl.commManager.GetRegistrationVersion()) + cl.GetRegistrationVersion()) return err } } else { @@ -262,7 +262,7 @@ func (cl *Client) Connect() error { "registration server, because it's not populated. Do you have " + "access to the registration server?") } - return cl.commManager.ConnectToGateways() + return cl.commManager.AddGatewayHosts(cl.ndf) } func (cl *Client) SetOperationProgressCallback(rpc OperationProgressCallback) { @@ -406,7 +406,7 @@ func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode, nick, } // RegisterWithUDB uses the account's email to register with the UDB for -// User discovery. Must be called after Register and Connect. +// User discovery. Must be called after Register and InitNetwork. // It will fail if the user has already registered with UDB func (cl *Client) RegisterWithUDB(timeout time.Duration) error { @@ -632,15 +632,25 @@ func (cl *Client) Login(password string) (string, error) { // Logs in user and sets session on client object // returns the nickname or error if login fails func (cl *Client) StartMessageReceiver() error { + transmitGateway := id.NewNodeFromBytes(cl.ndf.Nodes[0].ID).NewGateway() + transmissionHost, ok := cl.commManager.Comms.GetHost(transmitGateway.String()) + if !ok { + return errors.New("Failed to retrieve host for transmission") + } // Initialize UDB and nickname "bot" stuff here - bots.InitBots(cl.session, cl.commManager, cl.topology, id.NewUserFromBytes(cl.ndf.UDB.ID)) + bots.InitBots(cl.session, cl.commManager, cl.topology, id.NewUserFromBytes(cl.ndf.UDB.ID), transmissionHost) // Initialize Rekey listeners rekey.InitRekey(cl.session, cl.commManager, cl.topology, cl.rekeyChan) pollWaitTimeMillis := 1000 * time.Millisecond // TODO Don't start the message receiver if it's already started. // Should be a pretty rare occurrence except perhaps for mobile. - go cl.commManager.MessageReceiver(cl.session, pollWaitTimeMillis, cl.rekeyChan) + receptionGateway := id.NewNodeFromBytes(cl.ndf.Nodes[len(cl.ndf.Nodes)-1].ID).NewGateway() + receptionHost, ok := cl.commManager.Comms.GetHost(receptionGateway.String()) + if !ok { + return errors.New("Failed to retrieve host for transmission") + } + go cl.commManager.MessageReceiver(cl.session, pollWaitTimeMillis, cl.rekeyChan, receptionHost) return nil } @@ -648,10 +658,15 @@ func (cl *Client) StartMessageReceiver() error { // Send prepares and sends a message to the cMix network // FIXME: We need to think through the message interface part. func (cl *Client) Send(message parse.MessageInterface) error { + transmitGateway := id.NewNodeFromBytes(cl.ndf.Nodes[0].ID).NewGateway() + host, ok := cl.commManager.Comms.GetHost(transmitGateway.String()) + if !ok { + return errors.New("Failed to retrieve host for transmission") + } // FIXME: There should (at least) be a version of this that takes a byte array recipientID := message.GetRecipient() cryptoType := message.GetCryptoType() - return cl.commManager.SendMessage(cl.session, cl.topology, recipientID, cryptoType, message.Pack()) + return cl.commManager.SendMessage(cl.session, cl.topology, recipientID, cryptoType, message.Pack(), host) } // DisableBlockingTransmission turns off blocking transmission, for @@ -704,7 +719,7 @@ func (cl *Client) Logout() error { // Stop reception runner goroutine close(cl.session.GetQuitChan()) - cl.commManager.Disconnect() + cl.commManager.Comms.DisconnectAll() errStore := cl.session.StoreSession() @@ -733,11 +748,6 @@ func GetLocalVersion() string { return globals.SEMVER } -// Returns the compatible version of client, according to permissioning -func (cl *Client) GetRemoteVersion() string { - return cl.commManager.GetRegistrationVersion() -} - type SearchCallback interface { Callback(userID, pubKey []byte, err error) } @@ -836,7 +846,7 @@ func (cl *Client) LookupNick(user *id.User, go func() { nick, err := bots.LookupNick(user) if err != nil { - globals.Log.INFO.Printf("Lookup for nickname for user %s failed", user) + globals.Log.INFO.Printf("Lookup for nickname for user %+v failed", user) } cb.Callback(nick, err) }() diff --git a/api/client_test.go b/api/client_test.go index 3688d2a3454d3e4bbd8902c1e4dc911480236c48..18d6a19285c5eef41fcbfb345352610540377217 100644 --- a/api/client_test.go +++ b/api/client_test.go @@ -43,9 +43,8 @@ func TestRegistrationGob(t *testing.T) { if err != nil { t.Error(err) } - testClient.DisableTLS() - err = testClient.Connect() + err = testClient.InitNetwork() if err != nil { t.Error(err) } @@ -83,9 +82,8 @@ func TestClient_Register(t *testing.T) { if err != nil { t.Error(err) } - testClient.DisableTLS() - err = testClient.Connect() + err = testClient.InitNetwork() if err != nil { t.Error(err) } @@ -480,9 +478,8 @@ func TestClient_precannedRegister(t *testing.T) { if err != nil { t.Error(err) } - testClient.DisableTLS() - err = testClient.Connect() + err = testClient.InitNetwork() if err != nil { t.Error(err) } @@ -507,9 +504,8 @@ func TestClient_sendRegistrationMessage(t *testing.T) { if err != nil { t.Error(err) } - testClient.DisableTLS() - err = testClient.Connect() + err = testClient.InitNetwork() if err != nil { t.Error(err) } @@ -541,9 +537,8 @@ func TestClient_requestNonce(t *testing.T) { if err != nil { t.Error(err) } - testClient.DisableTLS() - err = testClient.Connect() + err = testClient.InitNetwork() if err != nil { t.Error(err) } @@ -571,8 +566,8 @@ func TestClient_confirmNonce(t *testing.T) { if err != nil { t.Error(err) } - testClient.DisableTLS() - err = testClient.Connect() + + err = testClient.InitNetwork() if err != nil { t.Error(err) } diff --git a/api/mockserver.go b/api/mockserver.go index 6fea077f4d1a47fb761384a20c33de9e4d376abf..076b854fddfc22410836bad0174c3bb6efe4a3d5 100644 --- a/api/mockserver.go +++ b/api/mockserver.go @@ -23,6 +23,8 @@ import ( "time" ) +var def *ndf.NetworkDefinition + const InvalidClientVersion = "1.1.0" // APIMessage are an implementation of the interface in bindings and API @@ -110,7 +112,8 @@ func (s *MockRegistration) RegisterNode(ID []byte, func (s *MockRegistration) GetUpdatedNDF(clientNdfHash []byte) ([]byte, error) { - ndfData := buildMockNDF() + ndfData := def + ndfJson, _ := json.Marshal(ndfData) return ndfJson, nil } diff --git a/api/mockserver_test.go b/api/mockserver_test.go index ac7d4aae32f471367aa103a9627a192fd943d846..fa70228f054ecf44a86b557582204d5ac61b2b7f 100644 --- a/api/mockserver_test.go +++ b/api/mockserver_test.go @@ -48,6 +48,7 @@ func TestMain(m *testing.M) { // Set logging params jww.SetLogThreshold(jww.LevelTrace) jww.SetStdoutThreshold(jww.LevelTrace) + os.Exit(testMainWrapper(m)) } @@ -59,10 +60,9 @@ func TestRegister_ValidPrecannedRegCodeReturnsZeroID(t *testing.T) { if err != nil { t.Errorf("Failed to initialize dummy client: %s", err.Error()) } - client.DisableTLS() - // Connect to gateways and reg server - err = client.Connect() + // InitNetwork to gateways and reg server + err = client.InitNetwork() if err != nil { t.Errorf("Client failed of connect: %+v", err) @@ -91,10 +91,9 @@ func TestRegister_ValidRegParams___(t *testing.T) { if err != nil { t.Errorf("Failed to initialize dummy client: %s", err.Error()) } - client.DisableTLS() - // Connect to gateways and reg server - err = client.Connect() + // InitNetwork to gateways and reg server + err = client.InitNetwork() if err != nil { t.Errorf("Client failed of connect: %+v", err) @@ -127,9 +126,8 @@ func TestRegister_InvalidPrecannedRegCodeReturnsError(t *testing.T) { if err != nil { t.Errorf("Failed to initialize dummy client: %s", err.Error()) } - client.DisableTLS() - // Connect to gateways and reg server - err = client.Connect() + // InitNetwork to gateways and reg server + err = client.InitNetwork() if err != nil { t.Errorf("Client failed of connect: %+v", err) @@ -153,10 +151,9 @@ func TestRegister_DeletedUserReturnsErr(t *testing.T) { if err != nil { t.Errorf("Failed to initialize dummy client: %s", err.Error()) } - client.DisableTLS() - // Connect to gateways and reg server - err = client.Connect() + // InitNetwork to gateways and reg server + err = client.InitNetwork() if err != nil { t.Errorf("Client failed of connect: %+v", err) @@ -185,10 +182,9 @@ func TestSend(t *testing.T) { if err != nil { t.Errorf("Failed to initialize dummy client: %s", err.Error()) } - client.DisableTLS() - // Connect to gateways and reg server - err = client.Connect() + // InitNetwork to gateways and reg server + err = client.InitNetwork() if err != nil { t.Errorf("Client failed of connect: %+v", err) @@ -263,9 +259,8 @@ func TestLogout(t *testing.T) { if err != nil { t.Errorf("Failed to initialize dummy client: %s", err.Error()) } - client.DisableTLS() - // Connect to gateways and reg server - err = client.Connect() + // InitNetwork to gateways and reg server + err = client.InitNetwork() if err != nil { t.Errorf("Client failed of connect: %+v", err) diff --git a/api/private.go b/api/private.go index eea749ccbb0c08f75d44d2492da33378c63dd234..90514ab145393bbedbd1ebf17b37d08283c76b0e 100644 --- a/api/private.go +++ b/api/private.go @@ -70,7 +70,7 @@ func (cl *Client) precannedRegister(registrationCode, nick string, // It sends a registration message and returns the registration signature func (cl *Client) sendRegistrationMessage(registrationCode string, publicKeyRSA *rsa.PublicKey) ([]byte, error) { - connected, err := cl.commManager.ConnectToPermissioning() + connected, err := cl.commManager.AddPermissioningHost(&cl.ndf.Registration) if err != nil { return nil, errors.Wrap(err, "Couldn't connect to permissioning to send registration message") } diff --git a/bindings/client.go b/bindings/client.go index fa7ef94b86ed9dff5bd5bffedd45fc667902e49a..76fa89d66dbb93efccffb1dedc7435c7003a4ec4 100644 --- a/bindings/client.go +++ b/bindings/client.go @@ -81,13 +81,6 @@ func NewClient(storage Storage, locA, locB string, ndfStr, ndfPubKey string, return &Client{client: cl}, err } -// DisableTLS makes the client run with tls disabled -// Must be called before Connect -func (cl *Client) DisableTLS() { - globals.Log.INFO.Printf("Binding call: DisableTLS()") - cl.client.DisableTLS() -} - func (cl *Client) EnableDebugLogs() { globals.Log.INFO.Printf("Binding call: EnableDebugLogs()") globals.Log.SetStdoutThreshold(jwalterweatherman.LevelDebug) @@ -98,8 +91,8 @@ func (cl *Client) EnableDebugLogs() { // using tls filepaths to create credential information // for connection establishment func (cl *Client) Connect() error { - globals.Log.INFO.Printf("Binding call: Connect()") - return cl.client.Connect() + globals.Log.INFO.Printf("Binding call: InitNetwork()") + return cl.client.InitNetwork() } // Sets a callback which receives a strings describing the current status of @@ -141,7 +134,7 @@ func (cl *Client) RegisterWithNodes() error { } // Register with UDB uses the account's email to register with the UDB for -// User discovery. Must be called after Register and Connect. +// User discovery. Must be called after Register and InitNetwork. // It will fail if the user has already registered with UDB func (cl *Client) RegisterWithUDB(timeoutMS int) error { globals.Log.INFO.Printf("Binding call: RegisterWithUDB()\n") @@ -248,7 +241,7 @@ func GetLocalVersion() string { // client release version returned here. func (cl *Client) GetRemoteVersion() string { globals.Log.INFO.Printf("Binding call: GetRemoteVersion()\n") - return cl.client.GetRemoteVersion() + return cl.GetRemoteVersion() } // Turns off blocking transmission so multiple messages can be sent diff --git a/bindings/client_test.go b/bindings/client_test.go index c1093c35f9c60ff2fc55f1b833011c742c406ac5..ca984ec784f7d1314432f4bed0be8c1851646da1 100644 --- a/bindings/client_test.go +++ b/bindings/client_test.go @@ -13,7 +13,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "gitlab.com/elixxir/client/api" "gitlab.com/elixxir/client/cmixproto" "gitlab.com/elixxir/client/globals" "gitlab.com/elixxir/client/parse" @@ -36,72 +35,40 @@ const GWsStartPort = 7900 const RegPort = 5000 const ValidRegCode = "UAV6IWD6" -var RegHandler = api.MockRegistration{} +var RegHandler = MockRegistration{} var RegComms *registration.Comms var GWComms [NumGWs]*gateway.Comms var def *ndf.NetworkDefinition -//Variables ported to get mock permissioning server running -var nodeId *id.Node -var permComms *registration.Comms - -type mockPermission struct { +type MockRegistration struct { } -func (i *mockPermission) RegisterUser(registrationCode, test string) (hash []byte, err error) { +func (i *MockRegistration) RegisterUser(registrationCode, test string) (hash []byte, err error) { return nil, nil } -func (i *mockPermission) RegisterNode(ID []byte, ServerAddr, ServerTlsCert, +func (i *MockRegistration) RegisterNode(ID []byte, ServerAddr, ServerTlsCert, GatewayAddr, GatewayTlsCert, RegistrationCode string) error { return nil } -func (i *mockPermission) GetCurrentClientVersion() (string, error) { - return "0.0.0", nil +func (i *MockRegistration) GetCurrentClientVersion() (string, error) { + return "0.1.0", nil } -func (i *mockPermission) GetUpdatedNDF(clientNdfHash []byte) ([]byte, error) { - ndfData := buildMockNDF() - ndfJson, _ := json.Marshal(ndfData) +func (i *MockRegistration) GetUpdatedNDF(clientNdfHash []byte) ([]byte, error) { + ndfJson, _ := json.Marshal(def) return ndfJson, nil } -func buildMockNDF() ndf.NetworkDefinition { - - ExampleJSON := `{"Timestamp":"2019-06-04T20:48:48-07:00","gateways":[{"Address":"0.0.0.0:7900","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"},{"Address":"0.0.0.0:7901","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"},{"Address":"0.0.0.0:7902","Tls_certificate":"-----BEGIN CERTIFICATE-----\nMIIDgTCCAmmgAwIBAgIJAKLdZ8UigIAeMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEaMBgGA1UEAwwRZ2F0ZXdheSou\nY21peC5yaXAwHhcNMTkwMzA1MTgzNTU0WhcNMjkwMzAyMTgzNTU0WjBvMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJQ2xhcmVtb250\nMRswGQYDVQQKDBJQcml2YXRlZ3JpdHkgQ29ycC4xGjAYBgNVBAMMEWdhdGV3YXkq\nLmNtaXgucmlwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9+AaxwDP\nxHbhLmn4HoZu0oUM48Qufc6T5XEZTrpMrqJAouXk+61Jc0EFH96/sbj7VyvnXPRo\ngIENbk2Y84BkB9SkRMIXya/gh9dOEDSgnvj/yg24l3bdKFqBMKiFg00PYB30fU+A\nbe3OI/le0I+v++RwH2AV0BMq+T6PcAGjCC1Q1ZB0wP9/VqNMWq5lbK9wD46IQiSi\n+SgIQeE7HoiAZXrGO0Y7l9P3+VRoXjRQbqfn3ETNL9ZvQuarwAYC9Ix5MxUrS5ag\nOmfjc8bfkpYDFAXRXmdKNISJmtCebX2kDrpP8Bdasx7Fzsx59cEUHCl2aJOWXc7R\n5m3juOVL1HUxjQIDAQABoyAwHjAcBgNVHREEFTATghFnYXRld2F5Ki5jbWl4LnJp\ncDANBgkqhkiG9w0BAQUFAAOCAQEAMu3xoc2LW2UExAAIYYWEETggLNrlGonxteSu\njuJjOR+ik5SVLn0lEu22+z+FCA7gSk9FkWu+v9qnfOfm2Am+WKYWv3dJ5RypW/hD\nNXkOYxVJNYFxeShnHohNqq4eDKpdqSxEcuErFXJdLbZP1uNs4WIOKnThgzhkpuy7\ntZRosvOF1X5uL1frVJzHN5jASEDAa7hJNmQ24kh+ds/Ge39fGD8pK31CWhnIXeDo\nvKD7wivi/gSOBtcRWWLvU8SizZkS3hgTw0lSOf5geuzvasCEYlqrKFssj6cTzbCB\nxy3ra3WazRTNTW4TmkHlCUC9I3oWTTxw5iQxF/I2kQQnwR7L3w==\n-----END CERTIFICATE-----"}],"nodes":[{"Id":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAERwUmUlL9YP\nq6MSn+bUr6qNZPsVYoQAo8nTjZWiuSjJa2XWnh7sftnISWkwkiiRxo7qfq3sAiD5\nB8+tM6kONeICBXukldXJerxoVBspYa+RiPuDWy2pwGRDBpfty3QqJOpu5g2ThYFJ\nD5Xu0yCuX8ZJRj33nliI8dQgKdQQva6p2VuXzyRT8LwXMfRwLuSB6Schc9mF8C\nkWCb4m0ujlEKe1xKoKt2zG9b1o7XyaVhxguSUAuEznifMzsEUfuONJOy+XoQELex\nF0wvLzNzABcyxkM3lx52uG41mKgJiV6Z0ZyuBRvt+V3VL/38tPn9lsTaFi8N6/IH\nRyy0bWP5s44=\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5900","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"},{"Id":[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAFbADcqA8KQh\nxzgylW6VS1dYYelO5DjPZVVSjfdcbj1twu4ZHDNZLOexpv4nGY8xS6vesELXcVOR\n/CHXgh/3byBZYm0zkrBi/FsJJ3nP2uZ1+QCRldI2KzqcLOWH/CAYj8koork9k1Dp\nFq7rMSDgw4pktqvFj9Eev8dSZuRnoCfZbt/6vxi1r30AYAjDYOwcysqcVyUa1tPa\nLEh3JksttXUCd5cvfqatWedTs5Vxo7ICW1toGBHABYvSJkwK0YFfi5RLw+Oda1sA\njJ+aLcIxQjrpoRC2alXCdwmZXVb+O6zluQctw6LJjt4J704ueSvR4VNNhr0uLYGW\nk7e+WoQCS98=\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5901","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"},{"Id":[3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNTCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAQCN19tTnkS3\nitBQXXR/h8OKl+rliFBLgO6h6GvZL4yQDZFtBAOmkrs3wLoDroJRGCeqz/IUb+JF\njslEr/mpm2kcmK77hr535dq7HsWz1fFl9YyGTaOH055FLSV9QEPAV9j3zWADdQ1v\nuSQll+QfWi6lIibWV4HNQ2ywRFoOY8OBLCJB90UXLeJpaPanpqiM8hjda2VGRDbi\nIixEE2lCOWITydiz2DmvXrLhVGF49+g5MDwbWO65dmasCe//Ff6Z4bJ6n049xv\nVtac8nX6FO3eBsV5d+rG6HZXSG3brCKRCSKYCTX1IkTSiutYxYqvwaluoCjOakh0\nKkqvQ8IeVZ+B\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5902","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDAeFwOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDhDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfsWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSEtJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uAm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9bJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEAAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIfU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2qvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4cyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1RtgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E56m52PyzMNV+2N21IPppKwA==-----END CERTIFICATE-----"}],"registration":{"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBAAlELnrXLG0s\n4yAAn7IsVWwY7swDnbBcsIF2cnef4tjm/nNwrFKp5AxYqgeXCiJM8VkyJrotWG50\nnXQwMCR6BsvYrlVt/RmQvR8BSrir62uSLK7hMKm7dXnFvtyFtjp91UwTRbIjxhUQ\nGYnhAzrkCDWo1m54ysqXEGlrVwvRXrCAXiLKPiTEIS+B4GFH9W26SwBxhFLNYSUk\nZZ7+4qwMf9aTu7kIpXTP3hNIyRCjtuZvo5SnymtbLARwTP943hW8MOj0+Ege+m1P\ntey6rkMUGQ86cgK9/7+7Jb+EwW5UxdQtFPUFeNKdQ6zDPS6qbliecUrsc12tdgeg\nhQyuMbyKUuo=\n-----END PUBLIC KEY-----\n","Address":"0.0.0.0:5000","Tls_certificate":"-----BEGIN CERTIFICATE-----MIIDkDCCAnigAwIBAgIJAJnjosuSsP7gMA0GCSqGSIb3DQEBBQUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEfMB0GA1UEAwwWcmVnaXN0cmF0aW9uKi5jbWl4LnJpcDAeFwOTAzMDUyMTQ5NTZaFw0yOTAzMDIyMTQ5NTZaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEfMB0GA1UEAwwWcmVnaXN0cmF0aW9uKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOQKvqjdh35o+MECBhCwopJzPlQNmq2iPbewRNtI02bUNK3kLQUbFlYdzNGZS4GYXGc5O+jdi8Slx82r1kdjz5PPCNFBARIsOP/L8r3DGeW+yeJdgBZjm1s3ylkamt4Ajiq/bNjysS6L/WSOp+sVumDxtBEzO/UTU1O6QRnzUphLaiWENmErGvsH0CZVq38Ia58k/QjCAzpUcYi4j2l1fb07xqFcQD8H6SmUM297UyQosDrp8ukdIo31Koxr4XDnnNNsYStC26tzHMeKuJ2Wl+3YzsSyflfM2YEcKE31sqB9DS36UkJ8J84eLsHNImGg3WodFAviDB67+jXDbB30NkMCAwEAAaMlMCMwIQYDVR0RBBowGIIWcmVnaXN0cmF0aW9uKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAF9mNzk+g+o626Rllt3f3/1qIyYQrYJ0BjSWCKYEFMCgZ4JibAJjAvIajhVYERtltffM+YKcdE2kTpdzJ0YJuUnRfuv6sVnXlVVugUUnd4IOigmjbCdM32k170CYMm0aiwGxl4FrNa8ei7AIax/s1n+sqWq3HeW5LXjnoVb+s3HeCWIuLfcgrurfye8FnNhy14HFzxVYYefIKmL+DPlcGGGm/PPYt3u4a2+rP3xaihc65dTa0u5tf/XPXtPxTDPFj2JeQDFxo7QRREbPD89CtYnwuP937CrkvCKrL0GkW1FViXKqZY9F5uhxrvLIpzhbNrs/EbtweY35XGLDCCMkg==-----END CERTIFICATE-----"},"udb":{"Id":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3],"Dsa_public_key":"-----BEGIN PUBLIC KEY-----\nMIIDNDCCAiwCggEBAJ22+1lRtmu2/h4UDx0s5VAjdBYf1lON8WSCGGQvC1xIyPek\nGq36GHMkuHZ0+hgisA8ez4E2lD18VXVyZOWhpE/+AS6ZNuAMHT6TELAcfReYBdMF\niyqfS7b5cWv+YRfGtbPMTZvjQRBK1KgK1slOAF9LmT4U8JHrUXQ78zBQw43iNVZ+\nGzTD1qXAzqoaDzaCE8PRmEPQtLCdy5/HLTnI3kHxvxTUu0Vjyig3FiHK0zJLai05\nIUW+v6x0iAUjb1yi/pK4cc2PnDbTKStVCcqMqneirfx7/XfdpvcRJadFb+oVPkMy\nVqImHGoG7TaTeX55lfrVqrvPvj7aJ0HjdUBK4lsCIQDywxGTdM52yTVpkLRlN0oX\n8j+e01CJvZafYcbd6ZmMHwKCAQBcf/awb48UP+gohDNJPkdpxNmIrOW+JaDiSAln\nBxbGE9ewzuaTL4+qfETSyyRSPaU/vk9uw1lYktGqWMQyigbEahVmLn6qcDod7Pi7\nstBdvi65VsFCozhmHRBGHA0TVHIIUFfzSUMJ/6c8YR94syrbtXQMNhyfNb6QmX2y\nAU4u9apheC9Sq+uL1kMsTdCXvFQjsoXa+2DcNk6BYfSio1rKOhCxxNIDzHakcKM6\n/cvdkpWYWavYtW4XJSUteOrGbnG6muPx3SSHGZh0OTzU2DIYaABlR2Dh40wJ5NFV\nF5+ewNxEc/mWvc5u7Ryr7YtvEW962c9QXfD5mONKsnUUsP/nAoIBACvR2lUslz3D\nB/MUo0rHVIHVkhVJCxNjtgTOYgJ9ckArSXQbYzr/fcigcNGjUO2LbK5NFp9GK43C\nrLxMUnJ9nkyIVPaWvquJFZItjcDK3NiNGyD4XyM0eRj4dYeSxQM48hvFbmtbjlXn\n9SQTnGIlr1XnTI4RVHZSQOL6kFJIaLw6wYrQ4w08Ng+p45brp5ercAHnLiftNUWP\nqROhQkdSEpS9LEwfotUSY1jP2AhQfaIMxaeXsZuTU1IYvdhMFRL3DR0r5Ww2Upf8\ng0Ace0mtnsUQ2OG+7MTh2jYIEWRjvuoe3RCz603ujW6g7BfQ1H7f4YFwc5xOOJ3u\nr4dj49dCCjc=\n-----END PUBLIC KEY-----\n"},"E2e":{"Prime":"E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3DD2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861575E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FFB1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBCA23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD161C7738F32BF29A841698978825B4111B4BC3E1E198455095958333D776D8B2BEEED3A1A1A221A6E37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F278DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E6319BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC35873847AEF49F66E43873","Small_prime":"02","Generator":"02"},"CMIX":{"Prime":"9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B","Small_prime":"F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F","Generator":"5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7"}}` - retNDF, _, _ := ndf.DecodeNDF(ExampleJSON) - /* - var grp ndf.Group - grp.Prime = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" + - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" + - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" + - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" + - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" + - "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" + - "83655D23DCA3AD961C62F356208552BB9ED529077096966D" + - "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" + - "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" + - "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" + - "15728E5A8AACAA68FFFFFFFFFFFFFFFF" - grp.Generator = "2" - grp.SmallPrime = "2" - retNDF := ndf.NetworkDefinition{Timestamp: time.Now(), Registration: reg, Nodes: Nodes, CMIX: grp, E2E: grp}*/ - return *retNDF -} - // Setups general testing params and calls test wrapper func TestMain(m *testing.M) { os.Exit(testMainWrapper(m)) } -type MockConStatCallback struct{} - -func (*MockConStatCallback) Callback(status int, TimeoutSeconds int) { return } - // Make sure NewClient returns an error when called incorrectly. func TestNewClientNil(t *testing.T) { @@ -140,7 +107,6 @@ func TestRegister(t *testing.T) { d := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} client, err := NewClient(&d, "hello", "", ndfStr, pubKey) - client.DisableTLS() if err != nil { t.Errorf("Failed to marshal group JSON: %s", err) } @@ -178,8 +144,7 @@ func TestLoginLogout(t *testing.T) { if err != nil { t.Errorf("Error starting client: %+v", err) } - client.DisableTLS() - // Connect to gateway + // InitNetwork to gateway err = client.Connect() if err != nil { t.Errorf("Could not connect: %+v", err) @@ -221,8 +186,7 @@ func TestListen(t *testing.T) { d := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} client, err := NewClient(&d, "hello", "", ndfStr, pubKey) - client.DisableTLS() - // Connect to gateway + // InitNetwork to gateway err = client.Connect() if err != nil { @@ -261,8 +225,7 @@ func TestStopListening(t *testing.T) { d := DummyStorage{LocationA: "Blah", StoreA: []byte{'a', 'b', 'c'}} client, err := NewClient(&d, "hello", "", ndfStr, pubKey) - client.DisableTLS() - // Connect to gateway + // InitNetwork to gateway err = client.Connect() if err != nil { @@ -338,8 +301,8 @@ func TestParse(t *testing.T) { } -func getNDFJSONStr(netDef *ndf.NetworkDefinition, t *testing.T) (string, string) { - ndfBytes, err := json.Marshal(netDef) +func getNDFJSONStr(def *ndf.NetworkDefinition, t *testing.T) (string, string) { + ndfBytes, err := json.Marshal(def) if err != nil { t.Errorf("Could not JSON the NDF: %+v", err) @@ -371,8 +334,7 @@ func testMainWrapper(m *testing.M) int { // Initialize permissioning server pAddr := def.Registration.Address - pHandler := registration.Handler(&mockPermission{}) - permComms = registration.StartRegistrationServer(pAddr, pHandler, nil, nil) + RegComms = registration.StartRegistrationServer(pAddr, &RegHandler, nil, nil) // Start mock gateways used by registration and defer their shutdown (may not be needed) //the ports used are colliding between tests in GoLand when running full suite, this is a dumb fix diff --git a/bots/bots.go b/bots/bots.go index e94b1d3aa2a8d36fb87f7204d79bcac779514959..3ec2667505cbe673505df702b1fe1f0df33e082f 100644 --- a/bots/bots.go +++ b/bots/bots.go @@ -6,6 +6,7 @@ import ( "gitlab.com/elixxir/client/io" "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/connect" "gitlab.com/elixxir/primitives/circuit" "gitlab.com/elixxir/primitives/id" "gitlab.com/elixxir/primitives/switchboard" @@ -14,6 +15,7 @@ import ( var session user.Session var topology *circuit.Circuit var comms io.Communications +var transmissionHost *connect.Host // UdbID is the ID of the user discovery bot, which is always 3 var UdbID *id.User @@ -49,7 +51,7 @@ func (l *nickReqListener) Hear(msg switchboard.Item, isHeardElsewhere bool) { var nicknameRequestListener nickReqListener // InitBots is called internally by the Login API -func InitBots(s user.Session, m io.Communications, top *circuit.Circuit, udbID *id.User) { +func InitBots(s user.Session, m io.Communications, top *circuit.Circuit, udbID *id.User, host *connect.Host) { UdbID = udbID // FIXME: these all need to be used in non-blocking threads if we are @@ -65,6 +67,8 @@ func InitBots(s user.Session, m io.Communications, top *circuit.Circuit, udbID * session = s topology = top comms = m + transmissionHost = host + l := session.GetSwitchboard() l.Register(UdbID, int32(cmixproto.Type_UDB_PUSH_KEY_RESPONSE), @@ -86,7 +90,7 @@ func InitBots(s user.Session, m io.Communications, top *circuit.Circuit, udbID * // listener. func sendCommand(botID *id.User, command []byte) error { return comms.SendMessage(session, topology, botID, - parse.Unencrypted, command) + parse.Unencrypted, command, transmissionHost) } // Nickname Lookup function diff --git a/bots/bots_test.go b/bots/bots_test.go index 01880fa921f6db77f0f34eb9742c7a41d39821f6..015e8f46df0aa8f98fafc12e23ebdeefaa450301 100644 --- a/bots/bots_test.go +++ b/bots/bots_test.go @@ -16,6 +16,7 @@ import ( "gitlab.com/elixxir/client/globals" "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/connect" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/large" "gitlab.com/elixxir/primitives/circuit" @@ -38,7 +39,7 @@ func (d *dummyMessaging) SendMessage(sess user.Session, topology *circuit.Circuit, recipientID *id.User, cryptoType parse.CryptoType, - message []byte) error { + message []byte, transmissionHost *connect.Host) error { jww.INFO.Printf("Sending: %s", string(message)) return nil } @@ -48,14 +49,14 @@ func (d *dummyMessaging) SendMessageNoPartition(sess user.Session, topology *circuit.Circuit, recipientID *id.User, cryptoType parse.CryptoType, - message []byte) error { + message []byte, transmissionHost *connect.Host) error { jww.INFO.Printf("Sending: %s", string(message)) return nil } // MessageReceiver thread to get new messages func (d *dummyMessaging) MessageReceiver(session user.Session, - delay time.Duration, rekeyChan chan struct{}) { + delay time.Duration, rekeyChan chan struct{}, transmissionHost *connect.Host) { } var pubKeyBits string @@ -79,10 +80,10 @@ func TestMain(m *testing.M) { fakeComm := &dummyMessaging{ listener: ListenCh, } - + h := connect.Host{} topology := circuit.New([]*id.Node{id.NewNodeFromBytes(make([]byte, id.NodeIdLen))}) - InitBots(fakeSession, fakeComm, topology, id.NewUserFromBytes([]byte("testid"))) + InitBots(fakeSession, fakeComm, topology, id.NewUserFromBytes([]byte("testid")), &h) // Make the reception channels buffered for this test // which overwrites the channels registered in InitBots @@ -198,7 +199,7 @@ func (e *errorMessaging) SendMessage(sess user.Session, topology *circuit.Circuit, recipientID *id.User, cryptoType parse.CryptoType, - message []byte) error { + message []byte, transmissionHost *connect.Host) error { return errors.New("This is an error") } @@ -207,13 +208,13 @@ func (e *errorMessaging) SendMessageNoPartition(sess user.Session, topology *circuit.Circuit, recipientID *id.User, cryptoType parse.CryptoType, - message []byte) error { + message []byte, transmissionHost *connect.Host) error { return errors.New("This is an error") } // MessageReceiver thread to get new messages func (e *errorMessaging) MessageReceiver(session user.Session, - delay time.Duration, rekeyChan chan struct{}) { + delay time.Duration, rekeyChan chan struct{}, transmissionHost *connect.Host) { } // Test LookupNick returns error on sending problem diff --git a/cmd/root.go b/cmd/root.go index a7088c23327715d076955c3913fa3b897bcea3a0..62e167cc4980f3cbe243d5620b16d469aa6bdc49 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -174,12 +174,8 @@ func sessionInitialization() (*id.User, string, *api.Client) { return id.ZeroID, "", nil }*/ - if noTLS { - client.DisableTLS() - } - - // Connect to gateways and reg server - err = client.Connect() + // InitNetwork to gateways and reg server + err = client.InitNetwork() if err != nil { globals.Log.FATAL.Panicf("Could not call connect on client: %+v", err) } diff --git a/io/checkVersion.go b/globals/checkVersion.go similarity index 99% rename from io/checkVersion.go rename to globals/checkVersion.go index 84c6c6e4e474be914e2b569ce36c2c5e3d5f5adc..92f3666bc2ce5b60264f471c35770b9b700e9ecc 100644 --- a/io/checkVersion.go +++ b/globals/checkVersion.go @@ -4,7 +4,7 @@ // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// -package io +package globals import ( "github.com/pkg/errors" diff --git a/io/checkVersion_test.go b/globals/checkVersion_test.go similarity index 99% rename from io/checkVersion_test.go rename to globals/checkVersion_test.go index ac0af61b23e1f4a3fcc6e61163e5f61807bc781b..d59999671f96237b6c92393e081ff81ba4027fc0 100644 --- a/io/checkVersion_test.go +++ b/globals/checkVersion_test.go @@ -4,9 +4,11 @@ // All rights reserved. / //////////////////////////////////////////////////////////////////////////////// -package io +package globals -import "testing" +import ( + "testing" +) func TestParseClientVersion_Success(t *testing.T) { version, err := parseClientVersion("1.2.3456") diff --git a/globals/version.go b/globals/version.go index 59e2675a0179cf9ae882c384df0c853cc3b36757..e508befe6a1e52955ad72cd791c13389fe4d9b72 100644 --- a/globals/version.go +++ b/globals/version.go @@ -6,3 +6,9 @@ package globals const GITVERSION = `bd4f026 Merge branch 'hotfix/fixtimeout' into 'release'` const SEMVER = "0.1.0" const GLIDEDEPS = `` + +// Utility method, returns whether the local version and remote version are +// compatible +func CheckVersion(ver string) (bool, error) { // again, version stuff, move to globals + return checkVersion(SEMVER, ver) +} diff --git a/go.mod b/go.mod index 729f1da823a121ccefb0906efabcf3152baea9b1..9dfecc248699d2e331271a61e03094e3039b8e50 100644 --- a/go.mod +++ b/go.mod @@ -12,13 +12,13 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.5.0 - gitlab.com/elixxir/comms v0.0.0-20191113191412-951037b1a272 + gitlab.com/elixxir/comms v0.0.0-20191118213520-6016a851439b gitlab.com/elixxir/crypto v0.0.0-20191029164123-324be42ee600 gitlab.com/elixxir/primitives v0.0.0-20191029164023-7f6b4088b191 - golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 - golang.org/x/net v0.0.0-20191112182307-2180aed22343 // indirect - golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 // indirect - google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a // indirect + golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f + golang.org/x/net v0.0.0-20191118183410-d06c31c94cae // indirect + golang.org/x/sys v0.0.0-20191118133127-cf1e2d577169 // indirect + google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect google.golang.org/grpc v1.25.1 // indirect gopkg.in/yaml.v2 v2.2.5 // indirect ) diff --git a/go.sum b/go.sum index bfb7f71ad30392de1bfd8d8aee9a03d28cef998a..bc3a526221816da53727c4b0439ff58bc023975c 100644 --- a/go.sum +++ b/go.sum @@ -132,8 +132,8 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -gitlab.com/elixxir/comms v0.0.0-20191113191412-951037b1a272 h1:HLvJ4kaBVLoV+3cK7CBXT59nRpKSjpdGII/1Fc3vGas= -gitlab.com/elixxir/comms v0.0.0-20191113191412-951037b1a272/go.mod h1:X3hAF6MepjDANpPmIycDHy+dcXyyEtOZXHwlSXU7a6s= +gitlab.com/elixxir/comms v0.0.0-20191118213520-6016a851439b h1:7ST1IMS6kotS9pHErpAe5FkGLVsmczdDUtUltNj9sx4= +gitlab.com/elixxir/comms v0.0.0-20191118213520-6016a851439b/go.mod h1:X3hAF6MepjDANpPmIycDHy+dcXyyEtOZXHwlSXU7a6s= gitlab.com/elixxir/crypto v0.0.0-20191029164123-324be42ee600 h1:4oexoUT9k0H6W3i1j6T5nCPwCwEijVb/uI5yALJjAE8= gitlab.com/elixxir/crypto v0.0.0-20191029164123-324be42ee600/go.mod h1:+46Zj/NE6JEkXExYnzdvvDokPpDbA+fJsRszvrezK9k= gitlab.com/elixxir/primitives v0.0.0-20191028233752-882c08b8f095 h1:fnRh0PUwgy0qlWM7xMdk2w5MXh7gvQ0v/xyedn2gbcY= @@ -151,8 +151,8 @@ golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152 h1:ZC1Xn5A1nlpSmQCIva4bZ3 golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss= golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 h1:pXVtWnwHkrWD9ru3sDxY/qFK/bfc0egRovX91EjWjf4= -golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f h1:kz4KIr+xcPUsI3VMoqWfPMvtnJ6MGfiVwsWSVzphMO4= +golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -167,8 +167,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343 h1:00ohfJ4K98s3m6BGUoBd8nyfp4Yl0GoIKvw5abItTjI= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191118183410-d06c31c94cae h1:AzDIJnLFoW3GaQvpbMRKk+SptYRYtnhYdyuX+S/dTbc= +golang.org/x/net v0.0.0-20191118183410-d06c31c94cae/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -186,8 +186,8 @@ golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934 h1:u/E0NqCIWRDAo9WCFo6Ko49nj golang.org/x/sys v0.0.0-20191028164358-195ce5e7f934/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c h1:S/FtSvpNLtFBgjTqcKsRpsa6aVsI6iztaz1bQd9BJwE= golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk= -golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191118133127-cf1e2d577169 h1:LPLFLulk2vyM7yI3CwNW64O6e8AxBmr9opfv14yI7HI= +golang.org/x/sys v0.0.0-20191118133127-cf1e2d577169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -205,8 +205,8 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 h1:UXl+Zk3jqqcbEVV7ace5lrt4YdA4tXiz3f/KbmD29Vo= google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 h1:51D++eCgOHufw5VfDE9Uzqyyc+OyQIjb9hkYy9LN5Fk= +google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/io/commManager.go b/io/commManager.go index 84e0c799a4b3879a92f6f6355db9ac8903e33307..a752c3382387afe7e01252d544a182d82beadd4c 100644 --- a/io/commManager.go +++ b/io/commManager.go @@ -40,15 +40,6 @@ type CommManager struct { nextId func() []byte collator *Collator - //Defines network Topology - ndf *ndf.NetworkDefinition - //Flags if the network is using tls or note - tls bool - // Index in the NDF of the gateway used to receive messages - receptionGatewayIndex int - // Index in the NDF of the gateway used to send messages - transmissionGatewayIndex int - // blockTransmissions will use a mutex to prevent multiple threads from sending // messages at the same time. blockTransmissions bool @@ -61,100 +52,69 @@ type CommManager struct { sendLock sync.Mutex - registrationVersion string - lock sync.RWMutex } -func NewCommManager(ndf *ndf.NetworkDefinition) *CommManager { +func NewCommManager() *CommManager { cm := &CommManager{ - nextId: parse.IDCounter(), - collator: NewCollator(), - blockTransmissions: true, - transmitDelay: 1000 * time.Millisecond, - receivedMessages: make(map[string]struct{}), - Comms: &client.Comms{}, - tls: true, - ndf: ndf, - receptionGatewayIndex: len(ndf.Gateways) - 1, - transmissionGatewayIndex: 0, + nextId: parse.IDCounter(), + collator: NewCollator(), + blockTransmissions: true, + transmitDelay: 1000 * time.Millisecond, + receivedMessages: make(map[string]struct{}), + Comms: &client.Comms{}, } - //cm.Comms.ConnectionManager.SetMaxRetries(1) - return cm } // Connects to gateways using tls filepaths to create credential information // for connection establishment -func (cm *CommManager) ConnectToGateways() error { // tear out - var err error - if len(cm.ndf.Gateways) < 1 { +func (cm *CommManager) AddGatewayHosts(ndf *ndf.NetworkDefinition) error { // tear out + if len(ndf.Gateways) < 1 { return errors.New("could not connect due to invalid number of nodes") } // connect to all gateways - var wg sync.WaitGroup - errChan := make(chan error, len(cm.ndf.Gateways)) - for i, gateway := range cm.ndf.Gateways { + var errs error = nil + for i, gateway := range ndf.Gateways { var gwCreds []byte - cm.lock.RLock() // what is the purpose of this locked block - if gateway.TlsCertificate != "" && cm.tls { + if gateway.TlsCertificate != "" { gwCreds = []byte(gateway.TlsCertificate) } - gwID := id.NewNodeFromBytes(cm.ndf.Nodes[i].ID).NewGateway() + gwID := id.NewNodeFromBytes(ndf.Nodes[i].ID).NewGateway() gwAddr := gateway.Address - cm.lock.RUnlock() - - wg.Add(1) - go func() { // Does this still need a thread? - globals.Log.INFO.Printf("Connecting to gateway %s at %s...", - gwID.String(), gwAddr) - host, err := connect.NewHost(gwAddr, gwCreds, false) - if err != nil { - errChan <- errors.New(fmt.Sprintf( - "Failed to create host for gateway %s at %s: %+v", - gwID.String(), gwAddr, err)) - } - cm.Comms.AddHost(gwID.String(), host) - wg.Done() - }() - wg.Wait() - - var errs error - for len(errChan) > 0 { - err = <-errChan + + host, err := connect.NewHost(gwAddr, gwCreds, false) + if err != nil { + err = errors.Errorf("Failed to create host for gateway %s at %s: %+v", + gwID.String(), gwAddr, err) if errs != nil { errs = errors.Wrap(errs, err.Error()) } else { errs = err } } - - if errs != nil { - return errs - } + cm.Comms.AddHost(gwID.String(), host) } - - return nil + return errs } // Connects to the permissioning server, if we know about it, to get the latest // version from it -func (cm *CommManager) UpdateRemoteVersion() error { // need this but make getremoteversion, handle versioning in client +func (cm *CommManager) GetRemoteVersion() (string, error) { // need this but make getremoteversion, handle versioning in client permissioningHost, ok := cm.Comms.GetHost(PermissioningAddrID) if !ok { - return errors.Errorf("Failed to find permissioning host with id %s", PermissioningAddrID) + return "", errors.Errorf("Failed to find permissioning host with id %s", PermissioningAddrID) } registrationVersion, err := cm.Comms. SendGetCurrentClientVersionMessage(permissioningHost) if err != nil { - return errors.Wrap(err, "Couldn't get current version from permissioning") + return "", errors.Wrap(err, "Couldn't get current version from permissioning") } - cm.registrationVersion = registrationVersion.Version - return nil + return registrationVersion.Version, nil } //GetUpdatedNDF: Connects to the permissioning server to get the updated NDF from it @@ -184,7 +144,7 @@ func (cm *CommManager) GetUpdatedNDF(currentNDF *ndf.NetworkDefinition) (*ndf.Ne //If there was no error and the response is nil, client's ndf is up-to-date if response == nil { globals.Log.DEBUG.Printf("Client NDF up-to-date") - return cm.ndf, nil + return nil, nil } //FixMe: use verify instead? Probs need to add a signature to ndf, like in registration's getupdate? @@ -201,51 +161,30 @@ func (cm *CommManager) GetUpdatedNDF(currentNDF *ndf.NetworkDefinition) (*ndf.Ne return updatedNdf, nil } -// Update NDF modifies the network properties for the network which is -// communicated with -func (cm *CommManager) UpdateNDF(updatedNDF *ndf.NetworkDefinition) { // again, don't worry about ndf in this object - cm.lock.Lock() - cm.ndf = updatedNDF - cm.receptionGatewayIndex = len(cm.ndf.Gateways) - 1 - cm.transmissionGatewayIndex = 0 - cm.lock.Unlock() -} - -// Utility method, returns whether the local version and remote version are -// compatible -func (cm *CommManager) CheckVersion() (bool, error) { // again, version stuff, move to globals - return checkVersion(globals.SEMVER, cm.registrationVersion) -} - // There's currently no need to keep connected to permissioning constantly, // so we have functions to connect to and disconnect from it when a connection // to permissioning is needed -func (cm *CommManager) ConnectToPermissioning() (connected bool, err error) { // this disappears, make host in simple call - if cm.ndf.Registration.Address != "" { +func (cm *CommManager) AddPermissioningHost(reg *ndf.Registration) (bool, error) { // this disappears, make host in simple call + if reg.Address != "" { _, ok := cm.Comms.GetHost(PermissioningAddrID) if ok { return true, nil } var regCert []byte - if cm.ndf.Registration.TlsCertificate != "" && cm.tls { - regCert = []byte(cm.ndf.Registration.TlsCertificate) + if reg.TlsCertificate != "" { + regCert = []byte(reg.TlsCertificate) } - globals.Log.INFO.Printf("Connecting to permissioning/registration at %s...", - cm.ndf.Registration.Address) - host, err := connect.NewHost(cm.ndf.Registration.Address, regCert, false) + host, err := connect.NewHost(reg.Address, regCert, false) if err != nil { return false, errors.New(fmt.Sprintf( "Failed connecting to create host for permissioning: %+v", err)) } cm.Comms.AddHost(PermissioningAddrID, host) - globals.Log.INFO.Printf( - "Connected to permissioning at %v successfully!", - cm.ndf.Registration.Address) return true, nil } else { - globals.Log.DEBUG.Printf("failed to connect to %v silently", cm.ndf.Registration.Address) + globals.Log.DEBUG.Printf("failed to connect to %v silently", reg.Address) // Without an NDF, we can't connect to permissioning, but this isn't an // error per se, because we should be phasing out permissioning at some // point @@ -253,18 +192,6 @@ func (cm *CommManager) ConnectToPermissioning() (connected bool, err error) { // } } -func (cm *CommManager) Disconnect() { // gone - cm.Comms.DisconnectAll() -} - -func (cm *CommManager) DisableTLS() { // gone - cm.tls = false -} - -func (cm *CommManager) GetRegistrationVersion() string { // on client - return cm.registrationVersion -} - func (cm *CommManager) DisableBlockingTransmission() { // flag passed into receiver cm.blockTransmissions = false } diff --git a/io/interface.go b/io/interface.go index 2683ac675898a6bb09016cd35893d7917ba0b952..5fca361f795f0000a865efa5bad98c559e19bf68 100644 --- a/io/interface.go +++ b/io/interface.go @@ -9,6 +9,7 @@ package io import ( "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/connect" "gitlab.com/elixxir/primitives/circuit" "gitlab.com/elixxir/primitives/id" "time" @@ -20,11 +21,14 @@ type Communications interface { // this can go // TODO(nen) Can we get rid of the crypto type param here? SendMessage(session user.Session, topology *circuit.Circuit, - recipientID *id.User, cryptoType parse.CryptoType, message []byte) error + recipientID *id.User, cryptoType parse.CryptoType, message []byte, + transmissionHost *connect.Host) error // SendMessage without partitions to the server // This is used to send rekey messages SendMessageNoPartition(session user.Session, topology *circuit.Circuit, - recipientID *id.User, cryptoType parse.CryptoType, message []byte) error + recipientID *id.User, cryptoType parse.CryptoType, message []byte, + transmissionHost *connect.Host) error // MessageReceiver thread to get new messages - MessageReceiver(session user.Session, delay time.Duration, rekeyChan chan struct{}) + MessageReceiver(session user.Session, delay time.Duration, rekeyChan chan struct{}, + receptionHost *connect.Host) } diff --git a/io/receive.go b/io/receive.go index 14c18a01c541f3b6c3bc1af6c86ac96c29cfa490..714cb28ee5fb15cf8d6203b48393bda008c5885d 100644 --- a/io/receive.go +++ b/io/receive.go @@ -14,6 +14,7 @@ import ( "gitlab.com/elixxir/client/globals" "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/connect" pb "gitlab.com/elixxir/comms/mixmessages" "gitlab.com/elixxir/crypto/e2e" "gitlab.com/elixxir/primitives/format" @@ -28,7 +29,8 @@ const reportDuration = 30 * time.Second var errE2ENotFound = errors.New("E2EKey for matching fingerprint not found, can't process message") // MessageReceiver is a polling thread for receiving messages -func (cm *CommManager) MessageReceiver(session user.Session, delay time.Duration, rekeyChan chan struct{}) { +func (cm *CommManager) MessageReceiver(session user.Session, delay time.Duration, rekeyChan chan struct{}, + receptionHost *connect.Host) { // FIXME: It's not clear we should be doing decryption here. if session == nil { globals.Log.FATAL.Panicf("No user session available") @@ -36,9 +38,6 @@ func (cm *CommManager) MessageReceiver(session user.Session, delay time.Duration pollingMessage := pb.ClientRequest{ UserID: session.GetCurrentUser().User.Bytes(), } - cm.lock.RLock() - receiveGateway := id.NewNodeFromBytes(cm.ndf.Nodes[cm.receptionGatewayIndex].ID).NewGateway() - cm.lock.RUnlock() quit := session.GetQuitChan() NumChecks := 0 @@ -74,7 +73,7 @@ func (cm *CommManager) MessageReceiver(session user.Session, delay time.Duration var err error - encryptedMessages, err = cm.receiveMessagesFromGateway(session, &pollingMessage, receiveGateway) + encryptedMessages, err = cm.receiveMessagesFromGateway(session, &pollingMessage, receptionHost) if err != nil { @@ -165,17 +164,13 @@ func handleE2EReceiving(session user.Session, } func (cm *CommManager) receiveMessagesFromGateway(session user.Session, - pollingMessage *pb.ClientRequest, receiveGateway *id.Gateway) ([]*format.Message, error) { + pollingMessage *pb.ClientRequest, receiveGateway *connect.Host) ([]*format.Message, error) { // Get the last message ID received pollingMessage.LastMessageID = session.GetLastMessageID() // FIXME: dont do this over an over // Gets a list of mssages that are newer than the last one recieved - host, ok := cm.Comms.GetHost(receiveGateway.String()) - if !ok { - return nil, errors.Errorf("Could not find host with id %s", receiveGateway.String()) - } - messageIDs, err := cm.Comms.SendCheckMessages(host, pollingMessage) + messageIDs, err := cm.Comms.SendCheckMessages(receiveGateway, pollingMessage) if err != nil { return nil, err @@ -203,7 +198,7 @@ func (cm *CommManager) receiveMessagesFromGateway(session user.Session, messageID) // We haven't seen this message before. // So, we should retrieve it from the gateway. - newMessage, err := cm.Comms.SendGetMessage(host, + newMessage, err := cm.Comms.SendGetMessage(receiveGateway, &pb.ClientRequest{ UserID: session.GetCurrentUser().User. Bytes(), diff --git a/io/send.go b/io/send.go index 88fa51beda70cf0fd73e5a255dbdb6d0e569282d..623e7b90a1cbe2b5c6202e657f681c7833c2b93c 100644 --- a/io/send.go +++ b/io/send.go @@ -15,6 +15,7 @@ import ( "gitlab.com/elixxir/client/keyStore" "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/connect" pb "gitlab.com/elixxir/comms/mixmessages" "gitlab.com/elixxir/crypto/cmix" "gitlab.com/elixxir/crypto/csprng" @@ -31,9 +32,8 @@ import ( // TODO This method would be cleaner if it took a parse.Message (particularly // w.r.t. generating message IDs for multi-part messages.) func (cm *CommManager) SendMessage(session user.Session, topology *circuit.Circuit, - recipientID *id.User, - cryptoType parse.CryptoType, - message []byte) error { + recipientID *id.User, cryptoType parse.CryptoType, + message []byte, transmissionHost *connect.Host) error { // FIXME: We should really bring the plaintext parts of the NewMessage logic // into this module, then have an EncryptedMessage type that is sent to/from // the cMix network. This NewMessage does way too many things: break the @@ -62,13 +62,12 @@ func (cm *CommManager) SendMessage(session user.Session, topology *circuit.Circu // Add a byte for later encryption (15->16 bytes) extendedNowBytes := append(nowBytes, 0) cm.lock.RLock() - transmitGateway := id.NewNodeFromBytes(cm.ndf.Nodes[cm.transmissionGatewayIndex].ID).NewGateway() for i := range parts { message := format.NewMessage() message.SetRecipient(recipientID) message.SetTimestamp(extendedNowBytes) message.Contents.SetRightAligned(parts[i]) - err = cm.send(session, topology, cryptoType, message, false, transmitGateway) + err = cm.send(session, topology, cryptoType, message, false, transmissionHost) if err != nil { return errors.Wrap(err, "SendMessage send() error:") } @@ -82,7 +81,7 @@ func (cm *CommManager) SendMessage(session user.Session, topology *circuit.Circu // message, where a new public key will take up the whole message func (cm *CommManager) SendMessageNoPartition(session user.Session, topology *circuit.Circuit, recipientID *id.User, cryptoType parse.CryptoType, - message []byte) error { + message []byte, transmissionHost *connect.Host) error { size := len(message) if size > format.TotalLen { return fmt.Errorf("SendMessageNoPartition() error: message to be sent is too big") @@ -105,11 +104,7 @@ func (cm *CommManager) SendMessageNoPartition(session user.Session, msg.Contents.Set(message) globals.Log.DEBUG.Printf("Sending message to %v: %x", *recipientID, message) - cm.lock.RLock() - transmitGateway := id.NewNodeFromBytes(cm.ndf.Nodes[cm.transmissionGatewayIndex].ID).NewGateway() - cm.lock.RUnlock() - - err = cm.send(session, topology, cryptoType, msg, true, transmitGateway) + err = cm.send(session, topology, cryptoType, msg, true, transmissionHost) if err != nil { return fmt.Errorf("SendMessageNoPartition send() error: %v", err.Error()) } @@ -120,7 +115,7 @@ func (cm *CommManager) SendMessageNoPartition(session user.Session, func (cm *CommManager) send(session user.Session, topology *circuit.Circuit, cryptoType parse.CryptoType, message *format.Message, - rekey bool, transmitGateway *id.Gateway) error { + rekey bool, transmitGateway *connect.Host) error { // Enable transmission blocking if enabled if cm.blockTransmissions { cm.sendLock.Lock() @@ -154,12 +149,7 @@ func (cm *CommManager) send(session user.Session, topology *circuit.Circuit, KMACs: kmacs, } - host, ok := cm.Comms.GetHost(transmitGateway.String()) - if !ok { - return errors.Errorf("Could not find host with ID %s", transmitGateway.String()) - } - - return cm.Comms.SendPutMessage(host, msgPacket) + return cm.Comms.SendPutMessage(transmitGateway, msgPacket) } func handleE2ESending(session user.Session, diff --git a/rekey/rekey.go b/rekey/rekey.go index 24bab25feacdce6b3ca10e569924991bfb8d1997..030b104dc7b7be7728076b8046d4e077b61d7745 100644 --- a/rekey/rekey.go +++ b/rekey/rekey.go @@ -9,6 +9,7 @@ import ( "gitlab.com/elixxir/client/keyStore" "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/connect" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/diffieHellman" "gitlab.com/elixxir/crypto/e2e" @@ -22,6 +23,7 @@ import ( var session user.Session var topology *circuit.Circuit var comms io.Communications +var transmissionHost *connect.Host var rekeyTriggerList rekeyTriggerListener var rekeyList rekeyListener @@ -251,7 +253,7 @@ func rekeyProcess(rt rekeyType, partner *id.User, data []byte) error { // This ensures that the publicKey fits in a single message, which // is sent with E2E encryption using a send Rekey, and without padding return comms.SendMessageNoPartition(session, topology, partner, parse.E2E, - pubKeyCyclic.LeftpadBytes(uint64(format.ContentsLen))) + pubKeyCyclic.LeftpadBytes(uint64(format.ContentsLen)), transmissionHost) case Rekey: // Trigger the rekey channel select { @@ -266,7 +268,7 @@ func rekeyProcess(rt rekeyType, partner *id.User, data []byte) error { MessageType: int32(cmixproto.Type_REKEY_CONFIRM), Body: baseKeyHash, }) - return comms.SendMessage(session, topology, partner, parse.None, msg) + return comms.SendMessage(session, topology, partner, parse.None, msg, transmissionHost) } return nil } diff --git a/rekey/rekey_test.go b/rekey/rekey_test.go index 975b127dd33e8dbd2c4d07202bf6a89493486b58..c5dd2a8830cedbf35ba61a95af6e3cedfd4d1f63 100644 --- a/rekey/rekey_test.go +++ b/rekey/rekey_test.go @@ -8,6 +8,7 @@ import ( "gitlab.com/elixxir/client/keyStore" "gitlab.com/elixxir/client/parse" "gitlab.com/elixxir/client/user" + "gitlab.com/elixxir/comms/connect" "gitlab.com/elixxir/crypto/csprng" "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/diffieHellman" @@ -33,7 +34,7 @@ func (d *dummyMessaging) SendMessage(sess user.Session, topology *circuit.Circuit, recipientID *id.User, cryptoType parse.CryptoType, - message []byte) error { + message []byte, transmissionHost *connect.Host) error { d.listener <- message return nil } @@ -43,14 +44,14 @@ func (d *dummyMessaging) SendMessageNoPartition(sess user.Session, topology *circuit.Circuit, recipientID *id.User, cryptoType parse.CryptoType, - message []byte) error { + message []byte, transmissionHost *connect.Host) error { d.listener <- message return nil } // MessageReceiver thread to get new messages func (d *dummyMessaging) MessageReceiver(session user.Session, - delay time.Duration, rekeyChan chan struct{}) { + delay time.Duration, rekeyChan chan struct{}, transmissionHost *connect.Host) { } func TestMain(m *testing.M) {