@@ -2,7 +2,6 @@ package main
22
33import  (
44	"fmt" 
5- 	"net" 
65	"strconv" 
76	"strings" 
87	"time" 
@@ -16,12 +15,15 @@ import (
1615	"github.com/lightningnetwork/lnd/keychain" 
1716	"github.com/lightningnetwork/lnd/lncfg" 
1817	"github.com/lightningnetwork/lnd/lnwire" 
18+ 	"github.com/lightningnetwork/lnd/peer" 
1919	"github.com/lightningnetwork/lnd/tor" 
2020	"github.com/spf13/cobra" 
2121)
2222
2323var  (
2424	dialTimeout  =  time .Minute 
25+ 
26+ 	defaultTorDNSHostPort  =  "soa.nodes.lightning.directory:53" 
2527)
2628
2729type  triggerForceCloseCommand  struct  {
@@ -30,6 +32,8 @@ type triggerForceCloseCommand struct {
3032
3133	APIURL  string 
3234
35+ 	TorProxy  string 
36+ 
3337	rootKey  * rootKey 
3438	cmd      * cobra.Command 
3539}
@@ -63,6 +67,10 @@ does not properly respond to a Data Loss Protection re-establish message).'`,
6367		& cc .APIURL , "apiurl" , defaultAPIURL , "API URL to use (must " + 
6468			"be esplora compatible)" ,
6569	)
70+ 	cc .cmd .Flags ().StringVar (
71+ 		& cc .TorProxy , "torproxy" , "" , "SOCKS5 proxy to use for Tor " + 
72+ 			"connections (to .onion addresses)" ,
73+ 	)
6674	cc .rootKey  =  newRootKey (cc .cmd , "deriving the identity key" )
6775
6876	return  cc .cmd 
@@ -94,7 +102,9 @@ func (c *triggerForceCloseCommand) Execute(_ *cobra.Command, _ []string) error {
94102		return  fmt .Errorf ("error parsing channel point: %w" , err )
95103	}
96104
97- 	err  =  requestForceClose (c .Peer , pubKey , outPoint , identityECDH )
105+ 	err  =  requestForceClose (
106+ 		c .Peer , c .TorProxy , pubKey , outPoint , identityECDH ,
107+ 	)
98108	if  err  !=  nil  {
99109		return  fmt .Errorf ("error requesting force close: %w" , err )
100110	}
@@ -134,34 +144,44 @@ func noiseDial(idKey keychain.SingleKeyECDH, lnAddr *lnwire.NetAddress,
134144	return  brontide .Dial (idKey , lnAddr , timeout , netCfg .Dial )
135145}
136146
137- func  requestForceClose (peerHost  string , peerPubKey  * btcec.PublicKey ,
138- 	channelPoint  * wire.OutPoint , identity  keychain.SingleKeyECDH ) error  {
147+ func  connectPeer (peerHost , torProxy  string , peerPubKey  * btcec.PublicKey ,
148+ 	identity  keychain.SingleKeyECDH ,
149+ 	dialTimeout  time.Duration ) (* peer.Brontide , error ) {
150+ 
151+ 	var  dialNet  tor.Net  =  & tor.ClearNet {}
152+ 	if  torProxy  !=  ""  {
153+ 		dialNet  =  & tor.ProxyNet {
154+ 			SOCKS :                       torProxy ,
155+ 			DNS :                         defaultTorDNSHostPort ,
156+ 			StreamIsolation :             false ,
157+ 			SkipProxyForClearNetTargets : true ,
158+ 		}
159+ 	}
139160
161+ 	log .Debugf ("Attempting to resolve peer address %v" , peerHost )
140162	peerAddr , err  :=  lncfg .ParseLNAddressString (
141- 		peerHost , "9735" , net .ResolveTCPAddr ,
163+ 		peerHost , "9735" , dialNet .ResolveTCPAddr ,
142164	)
143165	if  err  !=  nil  {
144- 		return  fmt .Errorf ("error parsing peer address: %w" , err )
166+ 		return  nil ,  fmt .Errorf ("error parsing peer address: %w" , err )
145167	}
146168
147- 	channelID  :=  lnwire .NewChanIDFromOutPoint (channelPoint )
148- 
149- 	conn , err  :=  noiseDial (
150- 		identity , peerAddr , & tor.ClearNet {}, dialTimeout ,
151- 	)
169+ 	log .Debugf ("Attempting to dial resolved peer address %v" ,
170+ 		peerAddr .String ())
171+ 	conn , err  :=  noiseDial (identity , peerAddr , dialNet , dialTimeout )
152172	if  err  !=  nil  {
153- 		return  fmt .Errorf ("error dialing peer: %w" , err )
173+ 		return  nil ,  fmt .Errorf ("error dialing peer: %w" , err )
154174	}
155175
156- 	log .Infof ("Attempting to connect  to peer %x, dial timeout is %v"  , 
157- 		peerPubKey .SerializeCompressed (), dialTimeout )
176+ 	log .Infof ("Attempting to establish p2p connection  to peer %x, dial"  + 
177+ 		"timeout is %v" ,  peerPubKey .SerializeCompressed (), dialTimeout )
158178	req  :=  & connmgr.ConnReq {
159179		Addr :      peerAddr ,
160180		Permanent : false ,
161181	}
162182	p , err  :=  lnd .ConnectPeer (conn , req , chainParams , identity )
163183	if  err  !=  nil  {
164- 		return  fmt .Errorf ("error connecting to peer: %w" , err )
184+ 		return  nil ,  fmt .Errorf ("error connecting to peer: %w" , err )
165185	}
166186
167187	log .Infof ("Connection established to peer %x" ,
@@ -171,10 +191,25 @@ func requestForceClose(peerHost string, peerPubKey *btcec.PublicKey,
171191	select  {
172192	case  <- p .ActiveSignal ():
173193	case  <- p .QuitSignal ():
174- 		return  fmt .Errorf ("peer %x disconnected" ,
194+ 		return  nil ,  fmt .Errorf ("peer %x disconnected" ,
175195			peerPubKey .SerializeCompressed ())
176196	}
177197
198+ 	return  p , nil 
199+ }
200+ 
201+ func  requestForceClose (peerHost , torProxy  string , peerPubKey  * btcec.PublicKey ,
202+ 	channelPoint  * wire.OutPoint , identity  keychain.SingleKeyECDH ) error  {
203+ 
204+ 	p , err  :=  connectPeer (
205+ 		peerHost , torProxy , peerPubKey , identity , dialTimeout ,
206+ 	)
207+ 	if  err  !=  nil  {
208+ 		return  fmt .Errorf ("error connecting to peer: %w" , err )
209+ 	}
210+ 
211+ 	channelID  :=  lnwire .NewChanIDFromOutPoint (channelPoint )
212+ 
178213	// Channel ID (32 byte) + u16 for the data length (which will be 0). 
179214	data  :=  make ([]byte , 34 )
180215	copy (data [:32 ], channelID [:])
0 commit comments