Beispiel #1
0
/*
sendOutstandingRequest sends all request messages for update messages that have
not yet been applied. This ensures that no files are missed and the bootstrap
successfully completes.
*/
func (c *chaninterface) sendOutstandingRequest(address string) {
	// if no address given nothing to do so return immediately
	if address == "" {
		return
	}
	// lock and unlock map access for this function
	c.mutex.Lock()
	defer func() { c.mutex.Unlock() }()
	// determine messages available
	amount := len(c.messages)
	// if all have been applied this method can stop
	if amount == 0 {
		log.Println("WARNING: nothing to request!")
		return
	}
	// send requests
	log.Println("Requesting", amount, "files.")
	for _, um := range c.messages {
		// make sure we don't request directories
		if um.Object.Directory {
			log.Println("WARNING: trying to request directory, ignoring!")
			continue
		}
		// prepare request file
		rm := shared.CreateRequestMessage(shared.OtObject, um.Object.Identification)
		// send request file
		c.boot.channel.Send(address, rm.JSON())
	}
}
Beispiel #2
0
/*
handlePushMessage handles the logic upon receiving a PushMessage.
*/
func (c *chaninterface) handlePushMessage(address string, pm *shared.PushMessage) {
	// note that file transfer is allowed for when file is received
	key := c.buildKey(address, pm.Identification)
	// if we reach this, allow and store push message too
	c.mutex.Lock()
	c.allowedTransfers[key] = *pm
	c.mutex.Unlock()
	log.Println("Receiving", pm.Identification)
	// notify that we have received the push message
	rm := shared.CreateRequestMessage(pm.ObjType, pm.Identification)
	c.enc.channel.Send(address, rm.JSON())
}
Beispiel #3
0
/*
Run is the background thread that keeps checking if it can bootstrap.
*/
func (b *Bootstrap) run() {
	defer func() { log.Println("Bootstrap:", "Background process stopped.") }()
	waitTicker := time.Tick(tickSpanNone)
	for {
		select {
		case <-b.stop:
			b.wg.Done()
			return
		case <-waitTicker:
			addresses, err := b.channel.OnlineAddresses()
			if err != nil {
				log.Println("Check:", err)
				break
			}
			if len(addresses) == 0 {
				log.Println("None available yet.")
				break
			}
			if len(addresses) > 1 {
				// since we'll always only try connecting to one, warn specifically!
				log.Println("WARNING: Multiple online! Will try connecting to ", addresses[0][:8], " only.")
			}
			// if not trusted, we are done once the connection has been accepted.
			if !b.IsTrusted() {
				// execute callback
				b.done()
				// stop bg thread
				b.stop <- false
				// go quit
				continue
			}
			log.Println("Initiating transfer of directory state.")
			// yo, we want to bootstrap!
			rm := shared.CreateRequestMessage(shared.OtModel, shared.IDMODEL)
			b.channel.Send(addresses[0], rm.JSON())
		} // select
	} // for
}
Beispiel #4
0
func (c *chaninterface) OnMessage(address, message string) {
	// check if lock message, or request, or send message
	v := &shared.Message{}
	err := json.Unmarshal([]byte(message), v)
	if err == nil {
		// special case for lock messages (can be received if not locked)
		if v.Type == shared.MsgLock {
			msg := &shared.LockMessage{}
			err := json.Unmarshal([]byte(message), msg)
			if err != nil {
				log.Println("OnMessage: failed to parse JSON!", err)
				return
			}
			c.handleLockMessage(address, msg)
			return
		}
		// for all others ensure that we are locked correctly
		if !c.enc.checkLock(address) {
			// if not warn and ignore message
			log.Println("OnMessage: not locked to given address!", address[:8])
			// TODO send notify that they are unlocked back?
			return
		}
		// if correctly locked handle message according to type
		switch msgType := v.Type; msgType {
		case shared.MsgRequest:
			msg := &shared.RequestMessage{}
			err := json.Unmarshal([]byte(message), msg)
			if err != nil {
				log.Println("OnMessage: failed to parse JSON!", err)
				return
			}
			c.handleRequestMessage(address, msg)
		case shared.MsgPush:
			msg := &shared.PushMessage{}
			err := json.Unmarshal([]byte(message), msg)
			if err != nil {
				log.Println("OnMessage: failed to parse JSON!", err)
				return
			}
			c.handlePushMessage(address, msg)
		case shared.MsgNotify:
			msg := &shared.NotifyMessage{}
			err := json.Unmarshal([]byte(message), msg)
			if err != nil {
				log.Println("OnMessage: failed to parse JSON!", err)
				return
			}
			c.handleNotifyMessage(address, msg)
		default:
			log.Println("OnMessage: WARNING: Unknown object received:", msgType.String())
		}
		// in any case return as we are done handling them
		return
	}
	// if unmarshal didn't work check for plain commands:
	// TODO these are temporary until it works, remove them later
	switch message {
	case "push":
		log.Println("Sending example push message.")
		pm := shared.CreatePushMessage("ID_HERE", shared.OtObject)
		c.enc.channel.Send(address, pm.JSON())
	case "lock":
		log.Println("Sending example lock message.")
		lm := shared.CreateLockMessage(shared.LoRequest)
		c.enc.channel.Send(address, lm.JSON())
	case "unlock":
		log.Println("Sending example unlock message.")
		lm := shared.CreateLockMessage(shared.LoRelease)
		c.enc.channel.Send(address, lm.JSON())
	case "request":
		log.Println("Sending example request message.")
		rm := shared.CreateRequestMessage(shared.OtObject, "ID_HERE")
		c.enc.channel.Send(address, rm.JSON())
	default:
		log.Println("Received:", message)
		c.enc.channel.Send(address, "Received non JSON message.")
	}
}