func setupUPnP() { if len(cfg.Options.ListenAddress) == 1 { _, portStr, err := net.SplitHostPort(cfg.Options.ListenAddress[0]) if err != nil { l.Warnln("Bad listen address:", err) } else { // Set up incoming port forwarding, if necessary and possible port, _ := strconv.Atoi(portStr) igd, err := upnp.Discover() if err == nil { externalPort = setupExternalPort(igd, port) if externalPort == 0 { l.Warnln("Failed to create UPnP port mapping") } else { l.Infoln("Created UPnP port mapping - external port", externalPort) } } else { l.Infof("No UPnP gateway detected") if debugNet { l.Debugf("UPnP: %v", err) } } if cfg.Options.UPnPRenewal > 0 { go renewUPnP(port) } } } else { l.Warnln("Multiple listening addresses; not attempting UPnP port mapping") } }
func renewUPnP(port int) { for { time.Sleep(time.Duration(cfg.Options.UPnPRenewal) * time.Minute) igd, err := upnp.Discover() if err != nil { continue } // Just renew the same port that we already have err = igd.AddPortMapping(upnp.TCP, externalPort, port, "syncthing", cfg.Options.UPnPLease*60) if err == nil { l.Infoln("Renewed UPnP port mapping - external port", externalPort) continue } // Something strange has happened. Perhaps the gateway has changed? // Retry the same port sequence from the beginning. r := setupExternalPort(igd, port) if r != 0 { externalPort = r l.Infoln("Updated UPnP port mapping - external port", externalPort) discoverer.StopGlobal() discoverer.StartGlobal(cfg.Options.GlobalAnnServer, uint16(r)) continue } l.Warnln("Failed to update UPnP port mapping - external port", externalPort) } }
func setupUPnP(r rand.Source) int { var externalPort = 0 if len(cfg.Options.ListenAddress) == 1 { _, portStr, err := net.SplitHostPort(cfg.Options.ListenAddress[0]) if err != nil { l.Warnln("Bad listen address:", err) } else { // Set up incoming port forwarding, if necessary and possible port, _ := strconv.Atoi(portStr) igd, err := upnp.Discover() if err == nil { for i := 0; i < 10; i++ { r := 1024 + int(r.Int63()%(65535-1024)) err := igd.AddPortMapping(upnp.TCP, r, port, "syncthing", 0) if err == nil { externalPort = r l.Infoln("Created UPnP port mapping - external port", externalPort) break } } if externalPort == 0 { l.Warnln("Failed to create UPnP port mapping") } } else { l.Infof("No UPnP gateway detected") if debugNet { l.Debugf("UPnP: %v", err) } } } } else { l.Warnln("Multiple listening addresses; not attempting UPnP port mapping") } return externalPort }