gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/host/upnp.go (about)

     1  package host
     2  
     3  import (
     4  	"net"
     5  
     6  	"gitlab.com/SiaPrime/SiaPrime/build"
     7  	"gitlab.com/SiaPrime/SiaPrime/modules"
     8  )
     9  
    10  // managedLearnHostname discovers the external IP of the Host. If the host's
    11  // net address is blank and the host's auto address appears to have changed,
    12  // the host will make an announcement on the blockchain.
    13  func (h *Host) managedLearnHostname() {
    14  	if build.Release == "testing" {
    15  		return
    16  	}
    17  
    18  	// Fetch a group of host vars that will be used to dictate the logic of the
    19  	// function.
    20  	h.mu.RLock()
    21  	netAddr := h.settings.NetAddress
    22  	hostPort := h.port
    23  	hostAutoAddress := h.autoAddress
    24  	hostAnnounced := h.announced
    25  	hostAcceptingContracts := h.settings.AcceptingContracts
    26  	hostContractCount := h.financialMetrics.ContractCount
    27  	h.mu.RUnlock()
    28  
    29  	// If the settings indicate that an address has been manually set, there is
    30  	// no reason to learn the hostname.
    31  	if netAddr != "" {
    32  		return
    33  	}
    34  	h.log.Println("No manually set net address. Scanning to automatically determine address.")
    35  
    36  	// Use the gateway to get the external ip.
    37  	hostname, err := h.g.DiscoverAddress(h.tg.StopChan())
    38  	if err != nil {
    39  		h.log.Println("WARN: failed to discover external IP")
    40  		return
    41  	}
    42  
    43  	autoAddress := modules.NetAddress(net.JoinHostPort(hostname.String(), hostPort))
    44  	if err := autoAddress.IsValid(); err != nil {
    45  		h.log.Printf("WARN: discovered hostname %q is invalid: %v", autoAddress, err)
    46  		return
    47  	}
    48  	if autoAddress == hostAutoAddress && hostAnnounced {
    49  		// Nothing to do - the auto address has not changed and the previous
    50  		// annoucement was successful.
    51  		return
    52  	}
    53  
    54  	h.mu.Lock()
    55  	h.autoAddress = autoAddress
    56  	err = h.saveSync()
    57  	h.mu.Unlock()
    58  	if err != nil {
    59  		h.log.Println(err)
    60  	}
    61  
    62  	// Announce the host, but only if the host is either accepting contracts or
    63  	// has a storage obligation. If the host is not accepting contracts and has
    64  	// no open contracts, there is no reason to notify anyone that the host's
    65  	// address has changed.
    66  	if hostAcceptingContracts || hostContractCount > 0 {
    67  		h.log.Println("Host external IP address changed from", hostAutoAddress, "to", autoAddress, "- performing host announcement.")
    68  		err = h.managedAnnounce(autoAddress)
    69  		if err != nil {
    70  			// Set h.announced to false, as the address has changed yet the
    71  			// renewed annoucement has failed.
    72  			h.mu.Lock()
    73  			h.announced = false
    74  			h.mu.Unlock()
    75  			h.log.Println("unable to announce address after upnp-detected address change:", err)
    76  		}
    77  	}
    78  }