From 8beac6f06d939818f09a5ab440df69657f9e83af Mon Sep 17 00:00:00 2001
From: Bernardo Cardoso <bernardo@elixxir.io>
Date: Thu, 16 May 2019 14:57:30 -0600
Subject: [PATCH] Modify client according to Comms refactor

---
 api/client.go      | 169 +++++++++++++++++++++++++++------------------
 api/mockserver.go  |  28 ++++----
 bindings/client.go |  36 ++++------
 cmd/root.go        |  21 ++----
 crypto/decrypt.go  |   2 +-
 io/disconnect.go   |  16 -----
 io/messaging.go    |  39 +++++++----
 user/session.go    |  24 +------
 8 files changed, 161 insertions(+), 174 deletions(-)
 delete mode 100644 io/disconnect.go

diff --git a/api/client.go b/api/client.go
index efbc52355..f39006538 100644
--- a/api/client.go
+++ b/api/client.go
@@ -21,28 +21,30 @@ import (
 	"gitlab.com/elixxir/client/parse"
 	"gitlab.com/elixxir/client/rekey"
 	"gitlab.com/elixxir/client/user"
-	"gitlab.com/elixxir/comms/client"
 	"gitlab.com/elixxir/comms/connect"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/csprng"
 	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/diffieHellman"
+	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/elixxir/crypto/large"
 	"gitlab.com/elixxir/crypto/registration"
 	"gitlab.com/elixxir/crypto/signature"
-	"gitlab.com/elixxir/crypto/diffieHellman"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/id"
 	"gitlab.com/elixxir/primitives/switchboard"
+	"google.golang.org/grpc/credentials"
 	goio "io"
 	"time"
 )
 
 type Client struct {
-	storage globals.Storage
-	sess user.Session
-	comm io.Communications
+	storage       globals.Storage
+	sess          user.Session
+	comm          io.Communications
+	gwAddresses   []io.ConnAddr
+	regAddress    io.ConnAddr
 }
 
 // Populates a text message and returns its wire representation
@@ -82,27 +84,59 @@ func NewClient(s globals.Storage, loc string) (*Client, error) {
 	cl := new(Client)
 	cl.storage = store
 	cl.comm = io.NewMessenger()
+	cl.gwAddresses = make([]io.ConnAddr, 0)
 	return cl, nil
 }
 
-// Registers user and returns the User ID.
-// Returns an error if registration fails.
-func (cl *Client) Register(preCan bool, registrationCode, nick,
-	registrationAddr string, gwAddresses []string,
-	mint bool, grp *cyclic.Group) (*id.User, error) {
+// Connects to gateways and registration server (if needed)
+// using TLS filepaths to create credential information
+// for connection establishment
+func (cl *Client) Connect(gwAddresses []string, gwCertPath,
+    regAddr, regCertPath string) {
+	if len(gwAddresses) < 1 {
+		globals.Log.ERROR.Printf("Connect: Invalid number of nodes")
+		return
+	}
 
-	var err error
+	var gwCreds credentials.TransportCredentials = nil
+	if gwCertPath != "" {
+		gwCreds = connect.NewCredentialsFromFile(gwCertPath, "")
+	}
 
-	if len(gwAddresses) < 1 {
-		globals.Log.ERROR.Printf("Register: Invalid number of nodes")
-		err = errors.New("could not register due to invalid number of nodes")
-		return id.ZeroID, err
+	for _, gw := range gwAddresses {
+		info := &connect.ConnectionInfo{
+			Address: gw,
+			Creds:   gwCreds,
+		}
+		addr := io.ConnAddr(gw)
+		(cl.comm).(*io.Messaging).Comms.ConnectToGateway(addr, info)
+		cl.gwAddresses = append(cl.gwAddresses, addr)
 	}
 
+	if regAddr != "" {
+		var regCreds credentials.TransportCredentials = nil
+		if regCertPath != "" {
+			regCreds = connect.NewCredentialsFromFile(regCertPath, "")
+		}
+		info := &connect.ConnectionInfo{
+			Address: regAddr,
+			Creds:   regCreds,
+		}
+		addr := io.ConnAddr(regAddr)
+		(cl.comm).(*io.Messaging).Comms.ConnectToRegistration(addr, info)
+		cl.regAddress = addr
+	}
+}
+
+// Registers user and returns the User ID.
+// Returns an error if registration fails.
+func (cl *Client) Register(preCan bool, registrationCode, nick string,
+	mint bool, grp *cyclic.Group) (*id.User, error) {
+	var err error
 	var u *user.User
 	var UID *id.User
 	// Make CMIX keys array
-	nk := make([]user.NodeKeys, len(gwAddresses))
+	nk := make([]user.NodeKeys, len(cl.gwAddresses))
 
 	// Generate DSA keypair even for precanned users as it will probably
 	// be needed for the new UDB flow
@@ -143,7 +177,7 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 			return id.ZeroID, err
 		}
 
-		for i := 0; i < len(gwAddresses); i++ {
+		for i := 0; i < len(cl.gwAddresses); i++ {
 			nk[i] = *nodekeys
 		}
 	} else {
@@ -164,15 +198,18 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 
 		// If Registration Server is specified, contact it
 		// Only if registrationCode is set
-		if registrationAddr != "" && registrationCode != "" {
+		if cl.regAddress != "" && registrationCode != "" {
 			// Send registration code and public key to RegistrationServer
-			response, err := client.SendRegistrationMessage(registrationAddr,
-				&pb.RegisterUserMessage{
+			response, err := (cl.comm).(*io.Messaging).Comms.
+				SendRegistrationMessage(cl.regAddress,
+				&pb.UserRegistration{
 					RegistrationCode: registrationCode,
-					Y:                publicKey.GetKey().Bytes(),
-					P:                params.GetP().Bytes(),
-					Q:                params.GetQ().Bytes(),
-					G:                params.GetG().Bytes(),
+					Client: &pb.DSAPublicKey{
+						Y: publicKey.GetKey().Bytes(),
+						P: params.GetP().Bytes(),
+						Q: params.GetQ().Bytes(),
+						G: params.GetG().Bytes(),
+					},
 				})
 			if err != nil {
 				globals.Log.ERROR.Printf(
@@ -183,23 +220,33 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 				globals.Log.ERROR.Printf("Register: %s", response.Error)
 				return id.ZeroID, errors.New(response.Error)
 			}
-			regHash, regR, regS = response.Hash, response.R, response.S
+			regHash = response.ClientSignedByServer.Hash
+			regR = response.ClientSignedByServer.R
+			regS = response.ClientSignedByServer.S
+			// Disconnect from regServer here since it will not be needed
+			(cl.comm).(*io.Messaging).Comms.Disconnect(cl.regAddress.String())
+			cl.regAddress = ""
 		}
 
 		// Loop over all Servers
-		for _, gwAddr := range gwAddresses {
+		for _, gwAddr := range cl.gwAddresses {
 
 			// Send signed public key and salt for UserID to Server
-			nonceResponse, err := client.SendRequestNonceMessage(gwAddr,
-				&pb.RequestNonceMessage{
+			nonceResponse, err := (cl.comm).(*io.Messaging).Comms.
+				SendRequestNonceMessage(gwAddr,
+				&pb.NonceRequest{
 					Salt: salt,
-					Y:    publicKey.GetKey().Bytes(),
-					P:    params.GetP().Bytes(),
-					Q:    params.GetQ().Bytes(),
-					G:    params.GetG().Bytes(),
-					Hash: regHash,
-					R:    regR,
-					S:    regS,
+					Client: &pb.DSAPublicKey{
+						Y: publicKey.GetKey().Bytes(),
+						P: params.GetP().Bytes(),
+						Q: params.GetQ().Bytes(),
+						G: params.GetG().Bytes(),
+					},
+					ClientSignedByServer: &pb.DSASignature{
+						Hash: regHash,
+						R:    regR,
+						S:    regS,
+					},
 				})
 			if err != nil {
 				globals.Log.ERROR.Printf(
@@ -223,8 +270,9 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 
 			// Send signed nonce to Server
 			// TODO: This returns a receipt that can be used to speed up registration
-			confirmResponse, err := client.SendConfirmNonceMessage(gwAddr,
-				&pb.ConfirmNonceMessage{
+			confirmResponse, err := (cl.comm).(*io.Messaging).Comms.
+				SendConfirmNonceMessage(gwAddr,
+				&pb.DSASignature{
 					Hash: nonce,
 					R:    sig.R.Bytes(),
 					S:    sig.S.Bytes(),
@@ -244,10 +292,10 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 			serverPublicKeys = append(serverPublicKeys,
 				signature.ReconstructPublicKey(signature.
 					CustomDSAParams(
-						large.NewIntFromBytes(confirmResponse.GetP()),
-						large.NewIntFromBytes(confirmResponse.GetQ()),
-						large.NewIntFromBytes(confirmResponse.GetG())),
-					large.NewIntFromBytes(confirmResponse.GetY())))
+						large.NewIntFromBytes(confirmResponse.Server.GetP()),
+						large.NewIntFromBytes(confirmResponse.Server.GetQ()),
+						large.NewIntFromBytes(confirmResponse.Server.GetG())),
+					large.NewIntFromBytes(confirmResponse.Server.GetY())))
 
 		}
 
@@ -284,8 +332,7 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 	}
 
 	// Create the user session
-	nus := user.NewSession(cl.storage, u, gwAddresses[0], nk,
-		publicKey, privateKey, grp)
+	nus := user.NewSession(cl.storage, u, nk, publicKey, privateKey, grp)
 
 	// Store the user session
 	errStore := nus.StoreSession()
@@ -308,27 +355,16 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 
 // Logs in user and sets session on client object
 // returns the nickname or error if login fails
-func (cl *Client) Login(UID *id.User, email, addr string, tlsCert string) (string, error) {
-
-	connect.GatewayCertString = tlsCert
-
+func (cl *Client) Login(UID *id.User, email string) (string, error) {
 	session, err := user.LoadSession(cl.storage, UID)
 
 	if session == nil {
-		return "", errors.New("Unable to load session: " + err.Error() +
-			fmt.Sprintf("Passed parameters: %q, %s, %q", *UID, addr, tlsCert))
+		return "", errors.New("Unable to load session: " + err.Error())
 	}
 
-	if addr != "" {
-		session.SetGWAddress(addr)
-	}
-
-	addrToUse := session.GetGWAddress()
-
-	// TODO: These can be separate, but we set them to the same thing
-	//       until registration is completed.
-	(cl.comm).(*io.Messaging).SendAddress = addrToUse
-	(cl.comm).(*io.Messaging).ReceiveAddress = addrToUse
+	(cl.comm).(*io.Messaging).SendAddress = cl.gwAddresses[0]
+	(cl.comm).(*io.Messaging).ReceiveAddress =
+		cl.gwAddresses[len(cl.gwAddresses)-1]
 
 	if err != nil {
 		err = errors.New(fmt.Sprintf("Login: Could not login: %s",
@@ -420,13 +456,9 @@ func (cl *Client) Logout() error {
 	// Stop reception runner goroutine
 	cl.sess.GetQuitChan() <- true
 
-	// Disconnect from the gateway
-	io.Disconnect(
-		(cl.comm).(*io.Messaging).SendAddress)
-	if (cl.comm).(*io.Messaging).SendAddress !=
-		(cl.comm).(*io.Messaging).ReceiveAddress {
-		io.Disconnect(
-			(cl.comm).(*io.Messaging).ReceiveAddress)
+	// Disconnect from the gateways
+	for _, gw := range cl.gwAddresses {
+		(cl.comm).(*io.Messaging).Comms.Disconnect(gw.String())
 	}
 
 	errStore := cl.sess.StoreSession()
@@ -475,8 +507,7 @@ type SearchCallback interface {
 // UDB Search API
 // Pass a callback function to extract results
 func (cl *Client) SearchForUser(emailAddress string,
-	cb SearchCallback,
-	) {
+	cb SearchCallback) {
 	valueType := "EMAIL"
 	go func() {
 		uid, pubKey, err := bots.Search(valueType, emailAddress)
diff --git a/api/mockserver.go b/api/mockserver.go
index 0e45c84c8..3504c0faf 100644
--- a/api/mockserver.go
+++ b/api/mockserver.go
@@ -54,14 +54,14 @@ func (m APIMessage) Pack() []byte {
 
 // Blank struct implementing ServerHandler interface for testing purposes (Passing to StartServer)
 type TestInterface struct {
-	LastReceivedMessage pb.CmixMessage
+	LastReceivedMessage pb.Slot
 }
 
 // Returns message contents for MessageID, or a null/randomized message
 // if that ID does not exist of the same size as a regular message
 func (m *TestInterface) GetMessage(userId *id.User,
-	msgId string) (*pb.CmixMessage, bool) {
-	return &pb.CmixMessage{}, true
+	msgId string) (*pb.Slot, bool) {
+	return &pb.Slot{}, true
 }
 
 // Return any MessageIDs in the globals for this User
@@ -71,25 +71,25 @@ func (m *TestInterface) CheckMessages(userId *id.User,
 }
 
 // Receives batch from server and stores it in the local MessageBuffer
-func (m *TestInterface) ReceiveBatch(msg *pb.OutputMessages) {
+func (m *TestInterface) ReceiveBatch(msg *pb.Batch) {
 }
 
 // PutMessage adds a message to the outgoing queue and
 // calls SendBatch when it's size is the batch size
-func (m *TestInterface) PutMessage(msg *pb.CmixMessage) bool {
+func (m *TestInterface) PutMessage(msg *pb.Slot) bool {
 	m.LastReceivedMessage = *msg
 	return true
 }
 
-func (m *TestInterface) ConfirmNonce(message *pb.ConfirmNonceMessage) (*pb.RegistrationConfirmation, error) {
-	regConfifmration := &pb.RegistrationConfirmation{}
+func (m *TestInterface) ConfirmNonce(message *pb.DSASignature) (*pb.RegistrationConfirmation, error) {
+	regConfirmation := &pb.RegistrationConfirmation{}
 
-	regConfifmration.P = large.NewInt(1).Bytes()
-	regConfifmration.Q = large.NewInt(1).Bytes()
-	regConfifmration.G = large.NewInt(1).Bytes()
-	regConfifmration.Y = large.NewInt(1).Bytes()
+	regConfirmation.Server.P = large.NewInt(1).Bytes()
+	regConfirmation.Server.Q = large.NewInt(1).Bytes()
+	regConfirmation.Server.G = large.NewInt(1).Bytes()
+	regConfirmation.Server.Y = large.NewInt(1).Bytes()
 
-	return regConfifmration, nil
+	return regConfirmation, nil
 }
 
 // Blank struct implementing Registration Handler interface for testing purposes (Passing to StartServer)
@@ -105,8 +105,8 @@ func (s *MockRegistration) RegisterUser(registrationCode string,
 
 
 // Pass-through for Registration Nonce Communication
-func (m *TestInterface) RequestNonce(message *pb.RequestNonceMessage) (*pb.NonceMessage, error) {
-	return &pb.NonceMessage{}, nil
+func (m *TestInterface) RequestNonce(message *pb.NonceRequest) (*pb.Nonce, error) {
+	return &pb.Nonce{}, nil
 }
 
 // Mock dummy storage interface for testing.
diff --git a/bindings/client.go b/bindings/client.go
index 72ade2fbf..d5e6e1eec 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -11,7 +11,6 @@ import (
 	"gitlab.com/elixxir/client/api"
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/parse"
-	"gitlab.com/elixxir/crypto/certs"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/id"
@@ -110,6 +109,17 @@ func NewClient(storage Storage, loc string) (*Client, error) {
 	return &Client{client: cl}, err
 }
 
+
+// Connects to gateways and registration server (if needed)
+// using TLS filepaths to create credential information
+// for connection establishment
+func (cl *Client) Connect(gwAddressesList, gwCertPath,
+	regAddr, regCertPath string) {
+
+	gwList := strings.Split(gwAddressesList, ",")
+	cl.client.Connect(gwList, gwCertPath, regAddr, regCertPath)
+}
+
 // Registers user and returns the User ID bytes.
 // Returns null if registration fails and error
 // If preCan set to true, registration is attempted assuming a pre canned user
@@ -117,14 +127,9 @@ func NewClient(storage Storage, loc string) (*Client, error) {
 // registrationAddr is the address of the registration server
 // gwAddressesList is CSV of gateway addresses
 // grp is the CMIX group needed for keys generation in JSON string format
-func (cl *Client) Register(preCan bool, registrationCode, nick,
-	registrationAddr string, gwAddressesList string,
+func (cl *Client) Register(preCan bool, registrationCode, nick string,
 	mint bool, grpJSON string) ([]byte, error) {
 
-	if gwAddressesList == "" {
-		return id.ZeroID[:], errors.New("invalid number of nodes")
-	}
-
 	// Unmarshal group JSON
 	var grp cyclic.Group
 	err := grp.UnmarshalJSON([]byte(grpJSON))
@@ -132,10 +137,7 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 		return id.ZeroID[:], err
 	}
 
-	gwList := strings.Split(gwAddressesList, ",")
-
-	UID, err := cl.client.Register(preCan, registrationCode, nick,
-		registrationAddr, gwList, mint, &grp)
+	UID, err := cl.client.Register(preCan, registrationCode, nick, mint, &grp)
 
 	if err != nil {
 		return id.ZeroID[:], err
@@ -153,17 +155,9 @@ func (cl *Client) Register(preCan bool, registrationCode, nick,
 // certificate string to "default", the bindings will use that certificate.
 // If you leave it empty, the Client will try to connect to the GW without TLS
 // This should only ever be used for testing purposes
-func (cl *Client) Login(UID []byte, email, addr string,
-	tlsCert string) (string, error) {
+func (cl *Client) Login(UID []byte, email string) (string, error) {
 	userID := id.NewUserFromBytes(UID)
-	var err error
-	var nick string
-	if tlsCert == "default" {
-		nick, err = cl.client.Login(userID, email, addr, certs.GatewayTLS)
-	} else {
-		nick, err = cl.client.Login(userID, email, addr, tlsCert)
-	}
-	return nick, err
+	return cl.client.Login(userID, email)
 }
 
 // Sends a message structured via the message interface
diff --git a/cmd/root.go b/cmd/root.go
index e96ea2587..d310b7f5c 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -20,8 +20,6 @@ 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/certs"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/large"
 	"gitlab.com/elixxir/primitives/format"
@@ -124,6 +122,10 @@ func sessionInitialization() *id.User {
 		}
 	}
 
+	// Connect to gateways and reg server
+	client.Connect(gateways, gwCertPath,
+		registrationAddr, registrationCertPath)
+
 	// Holds the User ID
 	var uid *id.User
 
@@ -146,8 +148,7 @@ func sessionInitialization() *id.User {
 
 		globals.Log.INFO.Printf("Attempting to register with code %s...", regCode)
 
-		uid, err = client.Register(userId != 0, regCode, "",
-			registrationAddr, gwAddresses, mint, &grp)
+		uid, err = client.Register(userId != 0, regCode, "", mint, &grp)
 		if err != nil {
 			fmt.Printf("Could Not Register User: %s\n", err.Error())
 			return id.ZeroID
@@ -165,8 +166,7 @@ func sessionInitialization() *id.User {
 
 	// Log the user in, for now using the first gateway specified
 	// This will also register the user email with UDB
-	_, err = client.Login(uid, userEmail,
-		gwAddresses[0], certs.GatewayTLS)
+	_, err = client.Login(uid, userEmail)
 	if err != nil {
 		fmt.Printf("Could Not Log In: %s\n", err)
 		return id.ZeroID
@@ -310,9 +310,6 @@ var rootCmd = &cobra.Command{
 		var dummyPeriod time.Duration
 		var timer *time.Timer
 
-		// Set the cert paths explicitly to avoid data races
-		SetCertPaths(gwCertPath, registrationCertPath)
-
 		userID := sessionInitialization()
 		// Set Key parameters if defined
 		if len(keyParams) == 5 {
@@ -504,12 +501,6 @@ func init() {
 			" in the following order: MinKeys,MaxKeys,NumRekeys,TTLScalar,MinNumKeys")
 }
 
-// Sets the cert paths in comms
-func SetCertPaths(gwCertPath, registrationCertPath string) {
-	connect.GatewayCertPath = gwCertPath
-	connect.RegistrationCertPath = registrationCertPath
-}
-
 // initConfig reads in config file and ENV variables if set.
 func initConfig() {
 	// Temporarily need to get group as JSON data into viper
diff --git a/crypto/decrypt.go b/crypto/decrypt.go
index a1d7485eb..ade5e1a11 100644
--- a/crypto/decrypt.go
+++ b/crypto/decrypt.go
@@ -21,7 +21,7 @@ import (
 // of a message from a team of nodes
 // It returns a new message
 func CMIXDecrypt(session user.Session,
-	msg *pb.CmixMessage) *format.Message {
+	msg *pb.Slot) *format.Message {
 	salt := msg.Salt
 	nodeKeys := session.GetKeys()
 	baseKeys := make([]*cyclic.Int, len(nodeKeys))
diff --git a/io/disconnect.go b/io/disconnect.go
deleted file mode 100644
index 8d501b80d..000000000
--- a/io/disconnect.go
+++ /dev/null
@@ -1,16 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2018 Privategrity Corporation                                   /
-//                                                                             /
-// All rights reserved.                                                        /
-////////////////////////////////////////////////////////////////////////////////
-
-package io
-
-import (
-	"gitlab.com/elixxir/comms/connect"
-)
-
-// Disconnect from the server
-func Disconnect(address string) {
-	connect.Disconnect(address)
-}
diff --git a/io/messaging.go b/io/messaging.go
index cdd27f195..f8e732629 100644
--- a/io/messaging.go
+++ b/io/messaging.go
@@ -29,14 +29,20 @@ import (
 	"time"
 )
 
+type ConnAddr string
+
+func (a ConnAddr) String() string {
+	return string(a)
+}
+
 // Messaging implements the Communications interface
 type Messaging struct {
 	nextId   func() []byte
 	collator *Collator
 	// SendAddress is the address of the server to send messages
-	SendAddress string
+	SendAddress ConnAddr
 	// ReceiveAddress is the address of the server to receive messages from
-	ReceiveAddress string
+	ReceiveAddress ConnAddr
 	// BlockTransmissions will use a mutex to prevent multiple threads from sending
 	// messages at the same time.
 	BlockTransmissions bool
@@ -45,6 +51,8 @@ type Messaging struct {
 	// Map that holds a record of the messages that this client successfully
 	// received during this session
 	ReceivedMessages map[string]struct{}
+	// Comms pointer to send/recv messages
+	Comms            *client.ClientComms
 	sendLock         sync.Mutex
 }
 
@@ -55,6 +63,7 @@ func NewMessenger() *Messaging {
 		BlockTransmissions: true,
 		TransmitDelay:      1000 * time.Millisecond,
 		ReceivedMessages:   make(map[string]struct{}),
+		Comms:              &client.ClientComms{},
 	}
 }
 
@@ -179,7 +188,7 @@ func (m *Messaging) send(session user.Session,
 	salt := cmix.NewSalt(csprng.Source(&csprng.SystemRNG{}), 16)
 	encMsg := crypto.CMIXEncrypt(session, salt, message)
 
-	msgPacket := &pb.CmixMessage{
+	msgPacket := &pb.Slot{
 		SenderID:       session.GetCurrentUser().User.Bytes(),
 		MessagePayload: encMsg.SerializePayload(),
 		AssociatedData: encMsg.SerializeAssociatedData(),
@@ -188,7 +197,7 @@ func (m *Messaging) send(session user.Session,
 	}
 
 	globals.Log.INFO.Println("Sending put message to gateway")
-	return client.SendPutMessage(m.SendAddress, msgPacket)
+	return m.Comms.SendPutMessage(m.SendAddress, msgPacket)
 }
 
 func handleE2ESending(session user.Session,
@@ -263,7 +272,7 @@ func (m *Messaging) MessageReceiver(session user.Session, delay time.Duration) {
 	if session == nil {
 		globals.Log.FATAL.Panicf("No user session available")
 	}
-	pollingMessage := pb.ClientPollMessage{
+	pollingMessage := pb.ClientRequest{
 		UserID: session.GetCurrentUser().User.Bytes(),
 	}
 
@@ -342,10 +351,10 @@ func handleE2EReceiving(session user.Session,
 }
 
 func (m *Messaging) receiveMessagesFromGateway(session user.Session,
-	pollingMessage *pb.ClientPollMessage) []*format.Message {
+	pollingMessage *pb.ClientRequest) []*format.Message {
 	if session != nil {
-		pollingMessage.MessageID = session.GetLastMessageID()
-		messages, err := client.SendCheckMessages(session.GetGWAddress(),
+		pollingMessage.LastMessageID = session.GetLastMessageID()
+		messages, err := m.Comms.SendCheckMessages(m.ReceiveAddress,
 			pollingMessage)
 
 		if err != nil {
@@ -353,10 +362,10 @@ func (m *Messaging) receiveMessagesFromGateway(session user.Session,
 			return nil
 		}
 
-		globals.Log.INFO.Printf("Checking novelty of %v messages", len(messages.MessageIDs))
+		globals.Log.INFO.Printf("Checking novelty of %v messages", len(messages.IDs))
 
-		results := make([]*format.Message, 0, len(messages.MessageIDs))
-		for _, messageID := range messages.MessageIDs {
+		results := make([]*format.Message, 0, len(messages.IDs))
+		for _, messageID := range messages.IDs {
 			// Get the first unseen message from the list of IDs
 			_, received := m.ReceivedMessages[messageID]
 			if !received {
@@ -364,12 +373,12 @@ func (m *Messaging) receiveMessagesFromGateway(session user.Session,
 					messageID)
 				// We haven't seen this message before.
 				// So, we should retrieve it from the gateway.
-				newMessage, err := client.SendGetMessage(
-					session.GetGWAddress(),
-					&pb.ClientPollMessage{
+				newMessage, err := m.Comms.SendGetMessage(
+					m.ReceiveAddress,
+					&pb.ClientRequest{
 						UserID: session.GetCurrentUser().User.
 							Bytes(),
-						MessageID: messageID,
+						LastMessageID: messageID,
 					})
 				if err != nil {
 					globals.Log.WARN.Printf(
diff --git a/user/session.go b/user/session.go
index 198bd8d42..7195f184d 100644
--- a/user/session.go
+++ b/user/session.go
@@ -29,8 +29,6 @@ var ErrQuery = errors.New("element not in map")
 // Interface for User Session operations
 type Session interface {
 	GetCurrentUser() (currentUser *User)
-	GetGWAddress() string
-	SetGWAddress(addr string)
 	GetKeys() []NodeKeys
 	GetPrivateKey() *signature.DSAPrivateKey
 	GetPublicKey() *signature.DSAPublicKey
@@ -58,7 +56,7 @@ type NodeKeys struct {
 
 // Creates a new Session interface for registration
 func NewSession(store globals.Storage,
-	u *User, GatewayAddr string, nk []NodeKeys,
+	u *User, nk []NodeKeys,
 	publicKey *signature.DSAPublicKey,
 	privateKey *signature.DSAPrivateKey,
 	grp *cyclic.Group) Session {
@@ -66,7 +64,6 @@ func NewSession(store globals.Storage,
 	// With an underlying Session data structure
 	return Session(&SessionObj{
 		CurrentUser:         u,
-		GWAddress:           GatewayAddr, // FIXME: don't store this here
 		Keys:                nk,
 		PrivateKey:          privateKey,
 		PublicKey:           publicKey,
@@ -147,9 +144,6 @@ type SessionObj struct {
 	// Currently authenticated user
 	CurrentUser *User
 
-	// Gateway address to the cMix network
-	GWAddress string
-
 	Keys       []NodeKeys
 	PrivateKey *signature.DSAPrivateKey
 	PublicKey  *signature.DSAPublicKey
@@ -231,18 +225,6 @@ func (s *SessionObj) GetCurrentUser() (currentUser *User) {
 	return currentUser
 }
 
-func (s *SessionObj) GetGWAddress() string {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.GWAddress
-}
-
-func (s *SessionObj) SetGWAddress(addr string) {
-	s.LockStorage()
-	s.GWAddress = addr
-	s.UnlockStorage()
-}
-
 func (s *SessionObj) storeSession() error {
 
 	if s.store == nil {
@@ -289,10 +271,6 @@ func (s *SessionObj) Immolate() error {
 	s.CurrentUser.Nick = burntString(len(s.CurrentUser.Nick))
 	s.CurrentUser.Nick = ""
 
-	s.GWAddress = burntString(len(s.GWAddress))
-	s.GWAddress = burntString(len(s.GWAddress))
-	s.GWAddress = ""
-
 	s.UnlockStorage()
 
 	return nil
-- 
GitLab