remember user-supplied peer addresses as given

rather than post name resolution. This way we can forget them as given
even when name resolution has changed or fails.
This commit is contained in:
Matthias Radestock committed 2015-04-12 20:44:12 +01:00
1 parent 1275bb24e5
commit a93a09dd35
2 files changed
+25 -30

No files matched your search

+18 -9
View File
@@ -19,12 +19,13 @@ type ConnectionMaker struct {
peers *Peers
normalisePeerAddr func(string) string
targets map[string]*Target
cmdLineAddress map[string]struct{}
cmdLinePeers map[string]string
actionChan chan<- ConnectionMakerAction
}
// Information about an address where we may find a peer
type Target struct {
fromCmdLine bool // did this address originate from the command line?
attempting bool // are we currently attempting to connect there?
tryAfter time.Time // next time to try this address
tryInterval time.Duration // backoff time on next failure
@@ -37,7 +38,7 @@ func NewConnectionMaker(ourself *LocalPeer, peers *Peers, normalisePeerAddr func
ourself: ourself,
peers: peers,
normalisePeerAddr: normalisePeerAddr,
cmdLineAddress: make(map[string]struct{}),
cmdLinePeers: make(map[string]string),
targets: make(map[string]*Target)}
}
@@ -47,19 +48,27 @@ func (cm *ConnectionMaker) Start() {
go cm.queryLoop(actionChan)
}
func (cm *ConnectionMaker) InitiateConnection(address string) {
func (cm *ConnectionMaker) InitiateConnection(peer string) error {
addr, err := net.ResolveTCPAddr("tcp4", cm.normalisePeerAddr(peer))
if err != nil {
return err
}
address := addr.String()
cm.actionChan <- func() bool {
cm.cmdLineAddress[cm.normalisePeerAddr(address)] = void
cm.cmdLinePeers[peer] = address
// curtail any existing reconnect interval
if target, found := cm.targets[address]; found {
target.tryAfter, target.tryInterval = tryImmediately()
}
return true
}
return nil
}
func (cm *ConnectionMaker) ForgetConnection(address string) {
func (cm *ConnectionMaker) ForgetConnection(peer string) {
cm.actionChan <- func() bool {
delete(cm.cmdLineAddress, cm.normalisePeerAddr(address))
delete(cm.cmdLinePeers, peer)
return false
}
}
@@ -137,8 +146,9 @@ func (cm *ConnectionMaker) checkStateAndAttemptConnections() time.Duration {
}
// Add command-line targets that are not connected
for address := range cm.cmdLineAddress {
for _, address := range cm.cmdLinePeers {
addTarget(address)
cm.targets[address].fromCmdLine = true
}
// Add targets for peers that someone else is connected to, but we
@@ -188,8 +198,7 @@ func (cm *ConnectionMaker) connectToTargets(validTarget map[string]struct{}) tim
switch duration := target.tryAfter.Sub(now); {
case duration <= 0:
target.attempting = true
_, isCmdLineAddress := cm.cmdLineAddress[address]
go cm.attemptConnection(address, isCmdLineAddress)
go cm.attemptConnection(address, target.fromCmdLine)
case duration < after:
after = duration
}
+7 -21
View File
@@ -141,7 +141,11 @@ func main() {
log.Println("Our name is", router.Ourself.FullName())
router.Start()
initiateConnections(router, peers)
for _, peer := range peers {
if err := router.ConnectionMaker.InitiateConnection(peer); err != nil {
log.Fatal(err)
}
}
if httpAddr != "" {
go handleHTTP(router, httpAddr)
}
@@ -162,16 +166,6 @@ func logFrameFunc(debug bool) weave.LogFrameFunc {
}
}
func initiateConnections(router *weave.Router, peers []string) {
for _, peer := range peers {
if addr, err := net.ResolveTCPAddr("tcp4", router.NormalisePeerAddr(peer)); err == nil {
router.ConnectionMaker.InitiateConnection(addr.String())
} else {
log.Fatal(err)
}
}
}
func handleHTTP(router *weave.Router, httpAddr string) {
encryption := "off"
if router.UsingPassword() {
@@ -192,21 +186,13 @@ func handleHTTP(router *weave.Router, httpAddr string) {
})
muxRouter.Methods("POST").Path("/connect").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
peer := r.FormValue("peer")
if addr, err := net.ResolveTCPAddr("tcp4", router.NormalisePeerAddr(peer)); err == nil {
router.ConnectionMaker.InitiateConnection(addr.String())
} else {
if err := router.ConnectionMaker.InitiateConnection(r.FormValue("peer")); err != nil {
http.Error(w, fmt.Sprint("invalid peer address: ", err), http.StatusBadRequest)
}
})
muxRouter.Methods("POST").Path("/forget").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
peer := r.FormValue("peer")
if addr, err := net.ResolveTCPAddr("tcp4", router.NormalisePeerAddr(peer)); err == nil {
router.ConnectionMaker.ForgetConnection(addr.String())
} else {
http.Error(w, fmt.Sprint("invalid peer address: ", err), http.StatusBadRequest)
}
router.ConnectionMaker.ForgetConnection(r.FormValue("peer"))
})
http.Handle("/", muxRouter)