diff --git a/Makefile b/Makefile
index d6165e6fd8522bc385d1fce2ff82666a2ec884c7..6ffb05ab0cbe0c3795e6c44130f859657329a45e 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ build:
 update_release:
 	GOFLAGS="" go get -u gitlab.com/elixxir/primitives@release
 	GOFLAGS="" go get -u gitlab.com/elixxir/crypto@release
-	GOFLAGS="" go get -u gitlab.com/elixxir/comms@release
+	GOFLAGS="" go get -u gitlab.com/elixxir/comms@connectionRefactor
 
 update_master:
 	GOFLAGS="" go get -u gitlab.com/elixxir/primitives@master
diff --git a/api/client.go b/api/client.go
index 8e09b41f71a745ec4ffd7b69ffe82bcd21714a98..d7c8d8621f6226edc09667526d8d96c3a308bb69 100644
--- a/api/client.go
+++ b/api/client.go
@@ -56,50 +56,6 @@ var noNDFErr = errors.New("Failed to get ndf from permissioning: rpc error: code
 //used to report the state of registration
 type OperationProgressCallback func(int)
 
-// Creates a new Client using the storage mechanism provided.
-// If none is provided, a default storage using OS file access
-// is created
-// returns a new Client object, and an error if it fails
-func NewClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinition,
-	callback io.ConnectionStatusCallback) (*Client, error) {
-	var store globals.Storage
-	if s == nil {
-		globals.Log.INFO.Printf("No storage provided," +
-			" initializing Client with default storage")
-		store = &globals.DefaultStorage{}
-	} else {
-		store = s
-	}
-
-	err := store.SetLocation(locA, locB)
-
-	if err != nil {
-		err = errors.New("Invalid Local Storage Location: " + err.Error())
-		return nil, err
-	}
-
-	cl := new(Client)
-	cl.storage = store
-	cl.commManager = io.NewCommManager(ndfJSON, callback)
-	cl.ndf = ndfJSON
-
-	cl.topology = nil
-
-	//Create the cmix group and init the registry
-	cmixGrp := cyclic.NewGroup(
-		large.NewIntFromString(cl.ndf.CMIX.Prime, 16),
-		large.NewIntFromString(cl.ndf.CMIX.Generator, 16))
-	user.InitUserRegistry(cmixGrp)
-
-	cl.opStatus = func(int) {
-		return
-	}
-
-	cl.rekeyChan = make(chan struct{}, 1)
-
-	return cl, nil
-}
-
 // Populates a text message and returns its wire representation
 // TODO support multi-type messages or telling if a message is too long?
 func FormatTextMessage(message string) []byte {
@@ -175,6 +131,7 @@ func requestNdf(cl *Client) error {
 	// Continuously polls for a new ndf after sleeping until response if gotten
 	globals.Log.INFO.Printf("Polling for a new NDF")
 	newNDf, err := cl.commManager.GetUpdatedNDF(cl.ndf)
+
 	if err != nil {
 		//lets the client continue when permissioning does not provide NDFs
 		if err.Error() == noNDFErr.Error() {
@@ -193,6 +150,54 @@ func requestNdf(cl *Client) error {
 	return nil
 }
 
+// Creates a new Client using the storage mechanism provided.
+// If none is provided, a default storage using OS file access
+// is created
+// returns a new Client object, and an error if it fails
+func NewClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinition,
+	callback io.ConnectionStatusCallback) (*Client, error) {
+	var store globals.Storage
+	if s == nil {
+		globals.Log.INFO.Printf("No storage provided," +
+			" initializing Client with default storage")
+		store = &globals.DefaultStorage{}
+	} else {
+		store = s
+	}
+
+	err := store.SetLocation(locA, locB)
+
+	if err != nil {
+		err = errors.New("Invalid Local Storage Location: " + err.Error())
+		globals.Log.ERROR.Printf(err.Error())
+		return nil, err
+	}
+
+	cl := new(Client)
+	cl.storage = store
+	cl.commManager = io.NewCommManager(ndfJSON, callback)
+	cl.ndf = ndfJSON
+	//build the topology
+	nodeIDs := make([]*id.Node, len(cl.ndf.Nodes))
+	for i, node := range cl.ndf.Nodes {
+		nodeIDs[i] = id.NewNodeFromBytes(node.ID)
+	}
+
+	//Create the cmix group and init the registry
+	cmixGrp := cyclic.NewGroup(
+		large.NewIntFromString(cl.ndf.CMIX.Prime, 16),
+		large.NewIntFromString(cl.ndf.CMIX.Generator, 16))
+	user.InitUserRegistry(cmixGrp)
+
+	cl.opStatus = func(int) {
+		return
+	}
+
+	cl.rekeyChan = make(chan struct{}, 1)
+
+	return cl, nil
+}
+
 // DisableTLS makes the client run with TLS disabled
 // Must be called before Connect
 func (cl *Client) DisableTLS() {
@@ -211,7 +216,6 @@ func (cl *Client) Connect() error {
 	//Connect to permissioning
 	if cl.ndf.Registration.Address != "" {
 		isConnected, err := cl.commManager.ConnectToPermissioning()
-		defer cl.commManager.DisconnectFromPermissioning()
 
 		if err != nil {
 			return err
@@ -266,192 +270,6 @@ func (cl *Client) SetOperationProgressCallback(rpc OperationProgressCallback) {
 	cl.opStatus = func(i int) { go rpc(i) }
 }
 
-var sessionFileError = errors.New("Session file cannot be loaded and " +
-	"is possibly corrupt. Please contact support@xxmessenger.io")
-
-// LoadSession loads the session object for the UID
-func (cl *Client) Login(password string) (string, error) {
-
-	var session user.Session
-	var err error
-	done := make(chan struct{})
-
-	// run session loading in a separate goroutine so if it panics it can
-	// be caught and an error can be returned
-	go func() {
-		defer func() {
-			if r := recover(); r != nil {
-				err = sessionFileError
-				done <- struct{}{}
-			}
-		}()
-
-		session, err = user.LoadSession(cl.storage, password)
-		done <- struct{}{}
-	}()
-
-	//wait for session file loading to complete
-	<-done
-
-	if err != nil {
-		return "", errors.Wrap(err, "Login: Could not login")
-	}
-
-	if session == nil {
-		return "", errors.New("Unable to load session, no error reported")
-	}
-	if session.GetRegState() < user.PermissioningComplete {
-		return "", errors.New("Cannot log a user in which has not " +
-			"completed registration ")
-	}
-
-	cl.session = session
-	return cl.session.GetCurrentUser().Nick, nil
-}
-
-// Logout closes the connection to the server at this time and does
-// nothing with the user id. In the future this will release resources
-// and safely release any sensitive memory.
-// fixme: blocks forever is message reciever
-func (cl *Client) Logout() error {
-	if cl.session == nil {
-		err := errors.New("Logout: Cannot Logout when you are not logged in")
-		return err
-	}
-
-	// Stop reception runner goroutine
-	close(cl.session.GetQuitChan())
-
-	// Disconnect from the gateways
-	for _, gateway := range cl.ndf.Gateways {
-		cl.commManager.Comms.Disconnect(gateway.Address)
-	}
-
-	errStore := cl.session.StoreSession()
-
-	if errStore != nil {
-		err := errors.Errorf("Logout: Store Failed: %s" +
-			errStore.Error())
-		return err
-	}
-
-	errImmolate := cl.session.Immolate()
-	cl.session = nil
-
-	if errImmolate != nil {
-		err := errors.Errorf("Logout: Immolation Failed: %s" +
-			errImmolate.Error())
-		return err
-	}
-
-	return nil
-}
-
-// Logs in user and sets session on client object
-// returns the nickname or error if login fails
-func (cl *Client) StartMessageReceiver(errorCallback func(error)) error {
-	status := cl.commManager.GetConnectionStatus()
-	if status == io.Connecting || status == io.Offline {
-		return errors.New("ERROR: could not StartMessageReceiver - connection is either offline or connecting")
-	}
-
-	// Initialize UDB and nickname "bot" stuff here
-	bots.InitBots(cl.session, cl.commManager, cl.topology, id.NewUserFromBytes(cl.ndf.UDB.ID))
-	// 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 func() {
-		defer func() {
-			if r := recover(); r != nil {
-				time.Sleep(1 * time.Second)
-				go func() {
-					errorCallback(errors.Errorf(fmt.Sprintln("Message Receiver Panicked", r)))
-				}()
-			}
-		}()
-		cl.commManager.MessageReceiver(cl.session, pollWaitTimeMillis, cl.rekeyChan)
-	}()
-
-	return nil
-}
-
-// TryReconnect Attemps to to reconnect with te network.  It will only cause
-// an attempt if called durring a backoff timeout
-func (cl *Client) TryReconnect() {
-	cl.commManager.TryReconnect()
-}
-
-// 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 {
-	status := cl.commManager.GetConnectionStatus()
-	if status == io.Connecting || status == io.Offline {
-		return errors.New("Could not Send - connection is either offline or connecting")
-	}
-
-	// 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())
-}
-
-// DisableBlockingTransmission turns off blocking transmission, for
-// use with the channel bot and dummy bot
-func (cl *Client) DisableBlockingTransmission() {
-	cl.commManager.DisableBlockingTransmission()
-}
-
-// SetRateLimiting sets the minimum amount of time between message
-// transmissions just for testing, probably to be removed in production
-func (cl *Client) SetRateLimiting(limit uint32) {
-	cl.commManager.SetRateLimit(time.Duration(limit) * time.Millisecond)
-}
-
-func (cl *Client) Listen(user *id.User, messageType int32, newListener switchboard.Listener) string {
-	listenerId := cl.session.GetSwitchboard().
-		Register(user, messageType, newListener)
-	globals.Log.INFO.Printf("Listening now: user %v, message type %v, id %v",
-		user, messageType, listenerId)
-	return listenerId
-}
-
-func (cl *Client) StopListening(listenerHandle string) {
-	cl.session.GetSwitchboard().Unregister(listenerHandle)
-}
-
-func (cl *Client) GetSwitchboard() *switchboard.Switchboard {
-	return cl.session.GetSwitchboard()
-}
-
-func (cl *Client) GetCurrentUser() *id.User {
-	return cl.session.GetCurrentUser().User
-}
-
-func (cl *Client) GetKeyParams() *keyStore.KeyParams {
-	return cl.session.GetKeyStore().GetKeyParams()
-}
-
-func (cl *Client) GetNetworkStatus() uint32 {
-	return cl.commManager.GetConnectionStatus()
-}
-
-// Returns the local version of the client repo
-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)
-}
-
 const SaltSize = 256
 
 // RegisterWithPermissioning registers user with permissioning and returns the
@@ -777,6 +595,183 @@ func (cl *Client) registerWithNode(index int, salt, registrationValidationSignat
 	cl.session.PushNodeKey(nodeID, key)
 }
 
+var sessionFileError = errors.New("Session file cannot be loaded and " +
+	"is possibly corrupt. Please contact support@xxmessenger.io")
+
+// LoadSession loads the session object for the UID
+func (cl *Client) Login(password string) (string, error) {
+
+	var session user.Session
+	var err error
+	done := make(chan struct{})
+
+	// run session loading in a separate goroutine so if it panics it can
+	// be caught and an error can be returned
+	go func() {
+		defer func() {
+			if r := recover(); r != nil {
+				globals.Log.ERROR.Println("Session file loading crashed")
+				err = sessionFileError
+				done <- struct{}{}
+			}
+		}()
+
+		session, err = user.LoadSession(cl.storage, password)
+		done <- struct{}{}
+	}()
+
+	//wait for session file loading to complete
+	<-done
+
+	if err != nil {
+		return "", errors.Wrap(err, "Login: Could not login")
+	}
+
+	if session == nil {
+		return "", errors.New("Unable to load session, no error reported")
+	}
+	if session.GetRegState() < user.PermissioningComplete {
+		return "", errors.New("Cannot log a user in which has not " +
+			"completed registration ")
+	}
+
+	cl.session = session
+	return cl.session.GetCurrentUser().Nick, nil
+}
+
+// Logs in user and sets session on client object
+// returns the nickname or error if login fails
+func (cl *Client) StartMessageReceiver() error {
+	status := cl.commManager.GetConnectionStatus()
+	if status == io.Connecting || status == io.Offline {
+		return errors.New("ERROR: could not StartMessageReceiver - connection is either offline or connecting")
+	}
+
+	// Initialize UDB and nickname "bot" stuff here
+	bots.InitBots(cl.session, cl.commManager, cl.topology, id.NewUserFromBytes(cl.ndf.UDB.ID))
+	// 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)
+
+	return nil
+}
+
+// TryReconnect Attemps to to reconnect with te network.  It will only cause
+// an attempt if called durring a backoff timeout
+func (cl *Client) TryReconnect() {
+	cl.commManager.TryReconnect()
+}
+
+// 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 {
+	status := cl.commManager.GetConnectionStatus()
+	if status == io.Connecting || status == io.Offline {
+		return errors.New("Could not Send - connection is either offline or connecting")
+	}
+
+	// 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())
+}
+
+// DisableBlockingTransmission turns off blocking transmission, for
+// use with the channel bot and dummy bot
+func (cl *Client) DisableBlockingTransmission() {
+	cl.commManager.DisableBlockingTransmission()
+}
+
+// SetRateLimiting sets the minimum amount of time between message
+// transmissions just for testing, probably to be removed in production
+func (cl *Client) SetRateLimiting(limit uint32) {
+	cl.commManager.SetRateLimit(time.Duration(limit) * time.Millisecond)
+}
+
+func (cl *Client) Listen(user *id.User, messageType int32, newListener switchboard.Listener) string {
+	listenerId := cl.session.GetSwitchboard().
+		Register(user, messageType, newListener)
+	globals.Log.INFO.Printf("Listening now: user %v, message type %v, id %v",
+		user, messageType, listenerId)
+	return listenerId
+}
+
+func (cl *Client) StopListening(listenerHandle string) {
+	cl.session.GetSwitchboard().Unregister(listenerHandle)
+}
+
+func (cl *Client) GetSwitchboard() *switchboard.Switchboard {
+	return cl.session.GetSwitchboard()
+}
+
+func (cl *Client) GetCurrentUser() *id.User {
+	return cl.session.GetCurrentUser().User
+}
+
+func (cl *Client) GetKeyParams() *keyStore.KeyParams {
+	return cl.session.GetKeyStore().GetKeyParams()
+}
+
+func (cl *Client) GetNetworkStatus() uint32 {
+	return cl.commManager.GetConnectionStatus()
+}
+
+// Logout closes the connection to the server at this time and does
+// nothing with the user id. In the future this will release resources
+// and safely release any sensitive memory.
+// fixme: blocks forever is message reciever
+func (cl *Client) Logout() error {
+	if cl.session == nil {
+		err := errors.New("Logout: Cannot Logout when you are not logged in")
+		globals.Log.ERROR.Printf(err.Error())
+		return err
+	}
+
+	// Stop reception runner goroutine
+	close(cl.session.GetQuitChan())
+
+	cl.commManager.Disconnect()
+
+	errStore := cl.session.StoreSession()
+
+	if errStore != nil {
+		err := errors.New(fmt.Sprintf("Logout: Store Failed: %s" +
+			errStore.Error()))
+		globals.Log.ERROR.Printf(err.Error())
+		return err
+	}
+
+	errImmolate := cl.session.Immolate()
+	cl.session = nil
+
+	if errImmolate != nil {
+		err := errors.New(fmt.Sprintf("Logout: Immolation Failed: %s" +
+			errImmolate.Error()))
+		globals.Log.ERROR.Printf(err.Error())
+		return err
+	}
+
+	return nil
+}
+
+// Returns the local version of the client repo
+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)
+}
+
 // UDB Search API
 // Pass a callback function to extract results
 func (cl *Client) SearchForUser(emailAddress string,
@@ -836,63 +831,6 @@ func (cl *Client) SearchForUser(emailAddress string,
 	}()
 }
 
-func (cl *Client) GetSessionData() ([]byte, error) {
-	return cl.session.GetSessionData()
-}
-
-// Set the output of the
-func SetLogOutput(w goio.Writer) {
-	globals.Log.SetLogOutput(w)
-}
-
-// GetSession returns the session object for external access.  Access at your
-// own risk
-func (cl *Client) GetSession() user.Session {
-	return cl.session
-}
-
-// CommManager returns the comm manager object for external access.  Access
-// at your own risk
-func (cl *Client) GetCommManager() *io.CommManager {
-	return cl.commManager
-}
-
-// LoadSessionText: load the encrypted session as a string
-func (cl *Client) LoadEncryptedSession() (string, error) {
-	encryptedSession, err := cl.GetSession().LoadEncryptedSession(cl.storage)
-	if err != nil {
-		return "", err
-	}
-	//Encode session to bas64 for useability
-	encodedSession := base64.StdEncoding.EncodeToString(encryptedSession)
-
-	return encodedSession, nil
-}
-
-//WriteToSession: Writes an arbitrary string to the session file
-// Takes in a string that is base64 encoded (meant to be output of LoadEncryptedSession)
-func (cl *Client) WriteToSessionFile(replacement string, store globals.Storage) error {
-	//This call must not occur prior to a newClient call, thus check that client has been initialized
-	if cl.ndf == nil || cl.topology == nil {
-		errMsg := errors.Errorf("Cannot write to session if client hasn't been created yet")
-		return errMsg
-	}
-	//Decode the base64 encoded replacement string (assumed to be encoded form LoadEncryptedSession)
-	decodedSession, err := base64.StdEncoding.DecodeString(replacement)
-	if err != nil {
-		errMsg := errors.Errorf("Failed to decode replacment string: %+v", err)
-		return errMsg
-	}
-	//Write the new session data to both locations
-	err = user.WriteToSession(decodedSession, store)
-	if err != nil {
-		errMsg := errors.Errorf("Failed to store session: %+v", err)
-		return errMsg
-	}
-
-	return nil
-}
-
 type NickLookupCallback interface {
 	Callback(nick string, err error)
 }
@@ -991,3 +929,24 @@ func ParseMessage(message []byte) (ParsedMessage, error) {
 
 	return pm, nil
 }
+
+func (cl *Client) GetSessionData() ([]byte, error) {
+	return cl.session.GetSessionData()
+}
+
+// Set the output of the
+func SetLogOutput(w goio.Writer) {
+	globals.Log.SetLogOutput(w)
+}
+
+// GetSession returns the session object for external access.  Access at your
+// own risk
+func (cl *Client) GetSession() user.Session {
+	return cl.session
+}
+
+// CommManager returns the comm manager object for external access.  Access
+// at your own risk
+func (cl *Client) GetCommManager() *io.CommManager {
+	return cl.commManager
+}
diff --git a/api/mockserver_test.go b/api/mockserver_test.go
index 7db11a55a5bdaff2596527acb452933a684cb82e..38e83dc14163c40255064304d52005ce4cf3279f 100644
--- a/api/mockserver_test.go
+++ b/api/mockserver_test.go
@@ -27,8 +27,7 @@ const GWsStartPort = 7900
 const PermErrorServerPort = 4000
 
 var RegHandler = MockRegistration{}
-var RegComms *registration.RegistrationComms
-var NDFErrorReg = MockPerm_NDF_ErrorCase{}
+var RegComms *registration.Comms
 
 const ValidRegCode = "UAV6IWD6"
 const InvalidRegCode = "INVALID_REG_CODE_"
@@ -38,7 +37,7 @@ var RegGWHandlers [3]*TestInterface = [NumGWs]*TestInterface{
 	{LastReceivedMessage: pb.Slot{}},
 	{LastReceivedMessage: pb.Slot{}},
 }
-var GWComms [NumGWs]*gateway.GatewayComms
+var GWComms [NumGWs]*gateway.Comms
 
 var def *ndf.NetworkDefinition
 var errorDef *ndf.NetworkDefinition
diff --git a/api/private.go b/api/private.go
index da0d5fba4378bd689e9642c5e792ee03e8baa19a..eea749ccbb0c08f75d44d2492da33378c63dd234 100644
--- a/api/private.go
+++ b/api/private.go
@@ -11,7 +11,6 @@ import (
 	"fmt"
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/globals"
-	"gitlab.com/elixxir/client/io"
 	"gitlab.com/elixxir/client/keyStore"
 	"gitlab.com/elixxir/client/user"
 	pb "gitlab.com/elixxir/comms/mixmessages"
@@ -72,7 +71,6 @@ func (cl *Client) precannedRegister(registrationCode, nick string,
 func (cl *Client) sendRegistrationMessage(registrationCode string,
 	publicKeyRSA *rsa.PublicKey) ([]byte, error) {
 	connected, err := cl.commManager.ConnectToPermissioning()
-	defer cl.commManager.DisconnectFromPermissioning()
 	if err != nil {
 		return nil, errors.Wrap(err, "Couldn't connect to permissioning to send registration message")
 	}
@@ -81,8 +79,12 @@ func (cl *Client) sendRegistrationMessage(registrationCode string,
 	}
 	regValidationSignature := make([]byte, 0)
 	// Send registration code and public key to RegistrationServer
+	host, ok := cl.commManager.Comms.GetHost(PermissioningAddrID)
+	if !ok {
+		return nil, errors.New("Failed to find permissioning host")
+	}
 	response, err := cl.commManager.Comms.
-		SendRegistrationMessage(io.ConnAddr(PermissioningAddrID),
+		SendRegistrationMessage(host,
 			&pb.UserRegistration{
 				RegistrationCode: registrationCode,
 				ClientRSAPubKey:  string(rsa.CreatePublicKeyPem(publicKeyRSA)),
@@ -121,8 +123,12 @@ func (cl *Client) requestNonce(salt, regHash []byte,
 	}
 
 	// Send signed public key and salt for UserID to Server
+	host, ok := cl.commManager.Comms.GetHost(gwID.String())
+	if !ok {
+		return nil, nil, errors.Errorf("Failed to find host with ID %s", gwID.String())
+	}
 	nonceResponse, err := cl.commManager.Comms.
-		SendRequestNonceMessage(gwID,
+		SendRequestNonceMessage(host,
 			&pb.NonceRequest{
 				Salt:            salt,
 				ClientRSAPubKey: string(rsa.CreatePublicKeyPem(publicKeyRSA)),
@@ -177,8 +183,12 @@ func (cl *Client) confirmNonce(UID, nonce []byte,
 			Signature: sig,
 		},
 	}
+	host, ok := cl.commManager.Comms.GetHost(gwID.String())
+	if !ok {
+		return errors.Errorf("Failed to find host with ID %s", gwID.String())
+	}
 	confirmResponse, err := cl.commManager.Comms.
-		SendConfirmNonceMessage(gwID, msg)
+		SendConfirmNonceMessage(host, msg)
 	if err != nil {
 		err := errors.New(fmt.Sprintf(
 			"confirmNonce: Unable to send signed nonce! %s", err))
diff --git a/bindings/client_test.go b/bindings/client_test.go
index 96c177dce3af0448f528ecd60191e61542942c38..fc4c16d1f037fea34ec2bc3ae06cdb7effca0f47 100644
--- a/bindings/client_test.go
+++ b/bindings/client_test.go
@@ -37,15 +37,15 @@ const RegPort = 5000
 const ValidRegCode = "UAV6IWD6"
 
 var RegHandler = api.MockRegistration{}
-var RegComms *registration.RegistrationComms
+var RegComms *registration.Comms
 
-var GWComms [NumGWs]*gateway.GatewayComms
+var GWComms [NumGWs]*gateway.Comms
 
 var def *ndf.NetworkDefinition
 
 //Variables ported to get mock permissioning server running
 var nodeId *id.Node
-var permComms *registration.RegistrationComms
+var permComms *registration.Comms
 
 type mockPermission struct {
 }
@@ -133,7 +133,7 @@ func TestNewClient(t *testing.T) {
 		t.Errorf("NewClient returned nil Client object")
 	}
 	for _, gw := range GWComms {
-		gw.Disconnect(api.PermissioningAddrID)
+		gw.DisconnectAll()
 	}
 }
 
@@ -163,7 +163,7 @@ func TestRegister(t *testing.T) {
 		t.Errorf("Invalid registration number received: %v", regRes)
 	}
 	for _, gw := range GWComms {
-		gw.Disconnect(api.PermissioningAddrID)
+		gw.DisconnectAll()
 	}
 }
 
@@ -209,7 +209,7 @@ func TestLoginLogout(t *testing.T) {
 		t.Errorf("Logoutfailed: %s", err3.Error())
 	}
 	for _, gw := range GWComms {
-		gw.Disconnect(api.PermissioningAddrID)
+		gw.DisconnectAll()
 	}
 }
 
@@ -257,7 +257,7 @@ func TestListen(t *testing.T) {
 		t.Error("Message not received")
 	}
 	for _, gw := range GWComms {
-		gw.Disconnect(api.PermissioningAddrID)
+		gw.DisconnectAll()
 	}
 }
 
diff --git a/go.mod b/go.mod
index a1c87ed7b9b050bec7237aa8a250942e865ae17f..729f1da823a121ccefb0906efabcf3152baea9b1 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-20191121235257-58343c70ada1
-	gitlab.com/elixxir/crypto v0.0.0-20191121235352-86d305a9b253
-	gitlab.com/elixxir/primitives v0.0.0-20191119224420-3776ddb853b2
-	golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
-	golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 // indirect
-	golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e // indirect
-	google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect
+	gitlab.com/elixxir/comms v0.0.0-20191113191412-951037b1a272
+	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
 	google.golang.org/grpc v1.25.1 // indirect
-	gopkg.in/yaml.v2 v2.2.7 // indirect
+	gopkg.in/yaml.v2 v2.2.5 // indirect
 )
diff --git a/go.sum b/go.sum
index cb5753582a725f05ada3230498857b7b8c69174c..bfb7f71ad30392de1bfd8d8aee9a03d28cef998a 100644
--- a/go.sum
+++ b/go.sum
@@ -132,18 +132,14 @@ 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-20191121235257-58343c70ada1 h1:7x/igwp+d1W20WIIxw6lcgkEtdkLalVcCZ9DMTS6Q+E=
-gitlab.com/elixxir/comms v0.0.0-20191121235257-58343c70ada1/go.mod h1:X3hAF6MepjDANpPmIycDHy+dcXyyEtOZXHwlSXU7a6s=
+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/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/crypto v0.0.0-20191121235352-86d305a9b253 h1:BqgqJ0mLANRjhAFLvGAcB5AWdgAnFZhsGx0qTk5G+3Y=
-gitlab.com/elixxir/crypto v0.0.0-20191121235352-86d305a9b253/go.mod h1:+46Zj/NE6JEkXExYnzdvvDokPpDbA+fJsRszvrezK9k=
 gitlab.com/elixxir/primitives v0.0.0-20191028233752-882c08b8f095 h1:fnRh0PUwgy0qlWM7xMdk2w5MXh7gvQ0v/xyedn2gbcY=
 gitlab.com/elixxir/primitives v0.0.0-20191028233752-882c08b8f095/go.mod h1:+UiRRWzNpl/WoWUuQtJSoimfXImJAJ5lrrmg0pQKY3g=
 gitlab.com/elixxir/primitives v0.0.0-20191029164023-7f6b4088b191 h1:pKf6JBoZb97UFb3w1h71FsvDoewL2VFfOSmIinOSTdQ=
 gitlab.com/elixxir/primitives v0.0.0-20191029164023-7f6b4088b191/go.mod h1:uOh4MxLDB8xGoDA2f0a/HJxgb2VFS4Pd2PC8f4m6/tU=
-gitlab.com/elixxir/primitives v0.0.0-20191119224420-3776ddb853b2 h1:Rwb9XrA9WQTPqB/hUAXgbgfbLtec8QKMXI5FyIXrVvQ=
-gitlab.com/elixxir/primitives v0.0.0-20191119224420-3776ddb853b2/go.mod h1:uOh4MxLDB8xGoDA2f0a/HJxgb2VFS4Pd2PC8f4m6/tU=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -155,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-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
-golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/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/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=
@@ -171,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-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4=
-golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/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/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=
@@ -190,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-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/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/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=
@@ -209,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-20191115221424-83cc0476cb11 h1:51D++eCgOHufw5VfDE9Uzqyyc+OyQIjb9hkYy9LN5Fk=
-google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11/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/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=
@@ -230,7 +226,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
-gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/io/commManager.go b/io/commManager.go
index a5016c650e59505ac293d6a37d5838c36406cba8..b7b6ca6b83f61477b4d8123f58d9473f60af3f9a 100644
--- a/io/commManager.go
+++ b/io/commManager.go
@@ -16,6 +16,7 @@ import (
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/parse"
 	"gitlab.com/elixxir/comms/client"
+	"gitlab.com/elixxir/comms/connect"
 	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/primitives/id"
 	"gitlab.com/elixxir/primitives/ndf"
@@ -37,7 +38,7 @@ func (a ConnAddr) String() string {
 // CommManager implements the Communications interface
 type CommManager struct {
 	// Comms pointer to send/recv messages
-	Comms *client.ClientComms
+	Comms *client.Comms
 
 	nextId   func() []byte
 	collator *Collator
@@ -85,7 +86,7 @@ func NewCommManager(ndf *ndf.NetworkDefinition,
 		blockTransmissions:       true,
 		transmitDelay:            1000 * time.Millisecond,
 		receivedMessages:         make(map[string]struct{}),
-		Comms:                    &client.ClientComms{},
+		Comms:                    &client.Comms{},
 		tryReconnect:             make(chan struct{}),
 		tls:                      true,
 		ndf:                      ndf,
@@ -95,7 +96,7 @@ func NewCommManager(ndf *ndf.NetworkDefinition,
 		connectionStatus:         &status,
 	}
 
-	cm.Comms.ConnectionManager.SetMaxRetries(1)
+	//cm.Comms.ConnectionManager.SetMaxRetries(1)
 
 	return cm
 }
@@ -130,14 +131,13 @@ func (cm *CommManager) ConnectToGateways() error {
 
 			globals.Log.INFO.Printf("Connecting to gateway %s at %s...",
 				gwID.String(), gwAddr)
-			err = cm.Comms.ConnectToRemote(gwID, gwAddr,
-				gwCreds, false)
-
+			host, err := connect.NewHost(gwAddr, gwCreds, false)
 			if err != nil {
 				errChan <- errors.New(fmt.Sprintf(
-					"Failed to connect to gateway %s at %s: %+v",
+					"Failed to create host for gateway %s at %s: %+v",
 					gwID.String(), gwAddr, err))
 			}
+			cm.Comms.AddHost(gwID.String(), host)
 			wg.Done()
 		}()
 		wg.Wait()
@@ -165,8 +165,12 @@ func (cm *CommManager) ConnectToGateways() error {
 // Connects to the permissioning server, if we know about it, to get the latest
 // version from it
 func (cm *CommManager) UpdateRemoteVersion() error {
+	permissioningHost, ok := cm.Comms.GetHost(PermissioningAddrID)
+	if !ok {
+		return errors.Errorf("Failed to find permissioning host with id %s", PermissioningAddrID)
+	}
 	registrationVersion, err := cm.Comms.
-		SendGetCurrentClientVersionMessage(ConnAddr(PermissioningAddrID))
+		SendGetCurrentClientVersionMessage(permissioningHost)
 	if err != nil {
 		return errors.Wrap(err, "Couldn't get current version from permissioning")
 	}
@@ -190,8 +194,13 @@ func (cm *CommManager) GetUpdatedNDF(currentNDF *ndf.NetworkDefinition) (*ndf.Ne
 	//Put the hash in a message
 	msg := &mixmessages.NDFHash{Hash: ndfHash}
 
+	host, ok := cm.Comms.GetHost(PermissioningAddrID)
+	if !ok {
+		return nil, errors.New("Failed to find permissioning host")
+	}
+
 	//Send the hash to registration
-	response, err := cm.Comms.SendGetUpdatedNDF(ConnAddr(PermissioningAddrID), msg)
+	response, err := cm.Comms.SendGetUpdatedNDF(host, msg)
 	if err != nil {
 		errMsg := fmt.Sprintf("Failed to get ndf from permissioning: %v", err)
 		return nil, errors.New(errMsg)
@@ -238,18 +247,24 @@ func (cm *CommManager) CheckVersion() (bool, error) {
 // to permissioning is needed
 func (cm *CommManager) ConnectToPermissioning() (connected bool, err error) {
 	if cm.ndf.Registration.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)
 		}
-		addr := ConnAddr(PermissioningAddrID)
+
 		globals.Log.INFO.Printf("Connecting to permissioning/registration at %s...",
 			cm.ndf.Registration.Address)
-		err = cm.Comms.ConnectToRemote(addr, cm.ndf.Registration.Address, regCert, false)
+		host, err := connect.NewHost(cm.ndf.Registration.Address, regCert, false)
 		if err != nil {
 			return false, errors.New(fmt.Sprintf(
-				"Failed connecting to permissioning: %+v", err))
+				"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)
@@ -263,11 +278,6 @@ func (cm *CommManager) ConnectToPermissioning() (connected bool, err error) {
 	}
 }
 
-func (cm *CommManager) DisconnectFromPermissioning() {
-	globals.Log.DEBUG.Printf("Disconnecting from permissioning")
-	cm.Comms.Disconnect(PermissioningAddrID)
-}
-
 func (cm *CommManager) Disconnect() {
 	cm.Comms.DisconnectAll()
 }
diff --git a/io/receive.go b/io/receive.go
index 2448ec62db04372a4b7fda2a73b1150b6e57b9f2..a08573832b4e7d98b17f27a468e7ea78c3715184 100644
--- a/io/receive.go
+++ b/io/receive.go
@@ -84,42 +84,6 @@ func (cm *CommManager) MessageReceiver(session user.Session, delay time.Duration
 				if strings.Contains(err.Error(), "Client has exceeded communications rate limit") {
 					globals.Log.WARN.Printf("Rate limit excceded on gateway, pausing polling for 5 seconds")
 					time.Sleep(5 * time.Second)
-				} else if !skipErrChecker(err) {
-					backoffCount := 0
-
-					// Handles disconnections
-					for notConnected := true; notConnected; {
-
-						cm.Disconnect()
-
-						block, backoffTime := cm.computeBackoff(backoffCount)
-
-						cm.setConnectionStatus(Offline, toSeconds(backoffTime))
-
-						globals.Log.WARN.Printf("Disconnected, reconnecting in %s", backoffTime)
-
-						timer := time.NewTimer(backoffTime)
-
-						if block {
-							timer.Stop()
-						}
-
-						select {
-						case <-session.GetQuitChan():
-							close(session.GetQuitChan())
-							return
-						case <-timer.C:
-						case <-cm.tryReconnect:
-							backoffCount = 0
-						}
-						err := cm.ConnectToGateways()
-
-						if err == nil {
-							notConnected = false
-						}
-
-						backoffCount++
-					}
 				}
 			}
 			NumMessages += len(encryptedMessages)
@@ -236,8 +200,11 @@ func (cm *CommManager) receiveMessagesFromGateway(session user.Session,
 	// FIXME: dont do this over an over
 
 	// Gets a list of mssages that are newer than the last one recieved
-	messageIDs, err := cm.Comms.SendCheckMessages(receiveGateway,
-		pollingMessage)
+	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)
 
 	if err != nil {
 		return nil, err
@@ -265,8 +232,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(
-				receiveGateway,
+			newMessage, err := cm.Comms.SendGetMessage(host,
 				&pb.ClientRequest{
 					UserID: session.GetCurrentUser().User.
 						Bytes(),
diff --git a/io/send.go b/io/send.go
index 54f1d083aad4e04c8ba46209ba4e4c72ab6c16c1..88fa51beda70cf0fd73e5a255dbdb6d0e569282d 100644
--- a/io/send.go
+++ b/io/send.go
@@ -154,7 +154,12 @@ func (cm *CommManager) send(session user.Session, topology *circuit.Circuit,
 		KMACs:    kmacs,
 	}
 
-	return cm.Comms.SendPutMessage(transmitGateway, msgPacket)
+	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)
 }
 
 func handleE2ESending(session user.Session,