Example #1
0
File: scan.go Project: mm3/Sia
// threadedProbeHost tries to fetch the settings of a host. If successful, the
// host is put in the set of active hosts. If unsuccessful, the host id deleted
// from the set of active hosts.
func (hdb *HostDB) threadedProbeHosts() {
	for hostEntry := range hdb.scanPool {
		// Request settings from the queued host entry.
		var settings modules.HostSettings
		err := func() error {
			conn, err := net.DialTimeout("tcp", string(hostEntry.IPAddress), hostRequestTimeout)
			if err != nil {
				return err
			}
			defer conn.Close()
			err = encoding.WriteObject(conn, [8]byte{'S', 'e', 't', 't', 'i', 'n', 'g', 's'})
			if err != nil {
				return err
			}
			return encoding.ReadObject(conn, &settings, maxSettingsLen)
		}()

		// Now that network communication is done, lock the hostdb to modify the
		// host entry.
		id := hdb.mu.Lock()
		{
			if err != nil {
				hdb.decrementReliability(hostEntry.IPAddress, UnreachablePenalty)
				hdb.mu.Unlock(id)
				continue
			}

			// Update the host settings, reliability, and weight. The old IPAddress
			// must be preserved.
			settings.IPAddress = hostEntry.HostSettings.IPAddress
			hostEntry.HostSettings = settings
			hostEntry.reliability = MaxReliability
			hostEntry.weight = hdb.hostWeight(*hostEntry)

			// If the host is not already in the database and 'MaxActiveHosts' has not
			// been reached, add the host to the database.
			_, exists1 := hdb.activeHosts[hostEntry.IPAddress]
			_, exists2 := hdb.allHosts[hostEntry.IPAddress]
			if !exists1 && exists2 && len(hdb.activeHosts) < MaxActiveHosts {
				hdb.insertNode(hostEntry)
				hdb.notifySubscribers()
			}
		}
		hdb.mu.Unlock(id)
	}
}
Example #2
0
File: scan.go Project: zzmjohn/Sia
// threadedProbeHost tries to fetch the settings of a host. If successful, the
// host is put in the set of active hosts. If unsuccessful, the host id deleted
// from the set of active hosts.
func (hdb *HostDB) threadedProbeHosts() {
	for hostEntry := range hdb.scanPool {
		// Request settings from the queued host entry.
		var settings modules.HostSettings
		err := func() error {
			conn, err := hdb.dialer.DialTimeout(hostEntry.NetAddress, hostRequestTimeout)
			if err != nil {
				return err
			}
			defer conn.Close()
			err = encoding.WriteObject(conn, modules.RPCSettings)
			if err != nil {
				return err
			}
			// COMPATv0.4.8 - If first decoding attempt fails, try decoding
			// into the old HostSettings type. Because we decode twice, we
			// must read the data into memory first.
			settingsBytes, err := encoding.ReadPrefix(conn, maxSettingsLen)
			if err != nil {
				return err
			}
			err = encoding.Unmarshal(settingsBytes, &settings)
			if err != nil {
				var oldSettings oldHostSettings
				err = encoding.Unmarshal(settingsBytes, &oldSettings)
				if err != nil {
					return err
				}
				// Convert the old type.
				settings = modules.HostSettings{
					NetAddress:   oldSettings.NetAddress,
					TotalStorage: oldSettings.TotalStorage,
					MinDuration:  oldSettings.MinDuration,
					MaxDuration:  oldSettings.MaxDuration,
					WindowSize:   oldSettings.WindowSize,
					Price:        oldSettings.Price,
					Collateral:   oldSettings.Collateral,
					UnlockHash:   oldSettings.UnlockHash,
				}
			}
			return nil
		}()

		// Now that network communication is done, lock the hostdb to modify the
		// host entry.
		func() {
			hdb.mu.Lock()
			defer hdb.mu.Unlock()

			// Regardless of whether the host responded, add it to allHosts.
			if _, exists := hdb.allHosts[hostEntry.NetAddress]; !exists {
				hdb.allHosts[hostEntry.NetAddress] = hostEntry
			}

			// If the scan was unsuccessful, decrement the host's reliability.
			if err != nil {
				hdb.decrementReliability(hostEntry.NetAddress, UnreachablePenalty)
				return
			}

			// Update the host settings, reliability, and weight. The old NetAddress
			// must be preserved.
			settings.NetAddress = hostEntry.HostSettings.NetAddress
			hostEntry.HostSettings = settings
			hostEntry.reliability = MaxReliability
			hostEntry.weight = calculateHostWeight(*hostEntry)
			hostEntry.online = true

			// If 'MaxActiveHosts' has not been reached, add the host to the
			// activeHosts tree.
			if _, exists := hdb.activeHosts[hostEntry.NetAddress]; !exists && len(hdb.activeHosts) < MaxActiveHosts {
				hdb.insertNode(hostEntry)
			}
		}()
	}
}