Beispiel #1
0
// registerConnection registers an ServerIdentity for a new connection, mapped with the
// real physical address of the connection and the connection itself
// it locks (and unlocks when done): entityListsLock and networkLock
func (h *Host) registerConnection(c network.SecureConn) {
	log.Lvl4(h.ServerIdentity.First(), "registers", c.ServerIdentity().First())
	h.networkLock.Lock()
	defer h.networkLock.Unlock()
	id := c.ServerIdentity()
	_, okc := h.connections[id.ID]
	if okc {
		// TODO - we should catch this in some way
		log.Lvl3("Connection already registered", okc)
	}
	h.connections[id.ID] = c
}
Beispiel #2
0
// Connect takes an entity where to connect to
func (h *Host) Connect(id *network.ServerIdentity) (network.SecureConn, error) {
	var err error
	var c network.SecureConn
	// try to open connection
	c, err = h.host.Open(id)
	if err != nil {
		return nil, err
	}
	log.Lvl3("Host", h.workingAddress, "connected to", c.Remote())
	h.registerConnection(c)
	go h.handleConn(c)
	return c, nil
}
Beispiel #3
0
// closeConnection closes a connection and removes it from the connections-map
// The h.networkLock must be taken.
func (h *Host) closeConnection(c network.SecureConn) error {
	h.networkLock.Lock()
	defer h.networkLock.Unlock()
	log.Lvl4(h.ServerIdentity.First(), "Closing connection", c, c.Remote(), c.Local())
	err := c.Close()
	if err != nil {
		return err
	}
	delete(h.connections, c.ServerIdentity().ID)
	return nil
}
Beispiel #4
0
// Handle a connection => giving messages to the MsgChans
func (h *Host) handleConn(c network.SecureConn) {
	address := c.Remote()
	for {
		ctx := context.TODO()
		am, err := c.Receive(ctx)
		// This is for testing purposes only: if the connection is missing
		// in the map, we just return silently
		h.networkLock.Lock()
		_, cont := h.connections[c.ServerIdentity().ID]
		h.networkLock.Unlock()
		if !cont {
			log.Lvl3(h.workingAddress, "Quitting handleConn ", c.Remote(), " because entry is not there")
			return
		}
		// So the receiver can know about the error
		am.SetError(err)
		am.From = address
		log.Lvl5("Got message", am)
		if err != nil {
			h.closingMut.Lock()
			log.Lvlf4("%+v got error (%+s) while receiving message (isClosing=%+v)",
				h.ServerIdentity.First(), err, h.isClosing)
			h.closingMut.Unlock()
			if err == network.ErrClosed || err == network.ErrEOF || err == network.ErrTemp {
				log.Lvl4(h.ServerIdentity.First(), c.Remote(), "quitting handleConn for-loop", err)
				h.closeConnection(c)
				return
			}
			log.Error(h.ServerIdentity.Addresses, "Error with connection", address, "=>", err)
		} else {
			h.closingMut.Lock()
			if !h.isClosing {
				h.networkChan <- am
			}
			h.closingMut.Unlock()
		}
	}
}