@@ -59,7 +59,8 @@ func (e *proxyErr) Unwrap() error {
5959// component.
6060func newRpcProxy (cfg * Config , validator macaroons.MacaroonValidator ,
6161 superMacValidator session.SuperMacaroonValidator ,
62- permsMgr * PermissionsManager ) * rpcProxy {
62+ permsMgr * PermissionsManager , statusServer * statusServer ,
63+ subServerMgr * subServerMgr ) * rpcProxy {
6364
6465 // The gRPC web calls are protected by HTTP basic auth which is defined
6566 // by base64(username:password). Because we only have a password, we
@@ -79,6 +80,8 @@ func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator,
7980 permsMgr : permsMgr ,
8081 macValidator : validator ,
8182 superMacValidator : superMacValidator ,
83+ statusServer : statusServer ,
84+ subServerMgr : subServerMgr ,
8285 }
8386 p .grpcServer = grpc .NewServer (
8487 // From the grpxProxy doc: This codec is *crucial* to the
@@ -153,10 +156,10 @@ type rpcProxy struct {
153156
154157 superMacaroon string
155158
156- lndConn * grpc.ClientConn
157- faradayConn * grpc. ClientConn
158- loopConn * grpc. ClientConn
159- poolConn * grpc. ClientConn
159+ lndConn * grpc.ClientConn
160+
161+ statusServer * statusServer
162+ subServerMgr * subServerMgr
160163
161164 grpcServer * grpc.Server
162165 grpcWebProxy * grpcweb.WrappedGrpcServer
@@ -167,44 +170,8 @@ type rpcProxy struct {
167170
168171// Start creates initial connection to lnd.
169172func (p * rpcProxy ) Start (lndConn * grpc.ClientConn ) error {
170- var err error
171173 p .lndConn = lndConn
172174
173- // Make sure we can connect to all the daemons that are configured to be
174- // running in remote mode.
175- if p .cfg .faradayRemote {
176- p .faradayConn , err = dialBackend (
177- "faraday" , p .cfg .Remote .Faraday .RPCServer ,
178- lncfg .CleanAndExpandPath (
179- p .cfg .Remote .Faraday .TLSCertPath ,
180- ),
181- )
182- if err != nil {
183- return fmt .Errorf ("could not dial remote faraday: %v" ,
184- err )
185- }
186- }
187-
188- if p .cfg .loopRemote {
189- p .loopConn , err = dialBackend (
190- "loop" , p .cfg .Remote .Loop .RPCServer ,
191- lncfg .CleanAndExpandPath (p .cfg .Remote .Loop .TLSCertPath ),
192- )
193- if err != nil {
194- return fmt .Errorf ("could not dial remote loop: %v" , err )
195- }
196- }
197-
198- if p .cfg .poolRemote {
199- p .poolConn , err = dialBackend (
200- "pool" , p .cfg .Remote .Pool .RPCServer ,
201- lncfg .CleanAndExpandPath (p .cfg .Remote .Pool .TLSCertPath ),
202- )
203- if err != nil {
204- return fmt .Errorf ("could not dial remote pool: %v" , err )
205- }
206- }
207-
208175 // Set started to true to indicate that the rpcProxy is now ready to
209176 // handle requests.
210177 p .mu .Lock ()
@@ -218,27 +185,6 @@ func (p *rpcProxy) Start(lndConn *grpc.ClientConn) error {
218185func (p * rpcProxy ) Stop () error {
219186 p .grpcServer .Stop ()
220187
221- if p .faradayConn != nil {
222- if err := p .faradayConn .Close (); err != nil {
223- log .Errorf ("Error closing faraday connection: %v" , err )
224- return err
225- }
226- }
227-
228- if p .loopConn != nil {
229- if err := p .loopConn .Close (); err != nil {
230- log .Errorf ("Error closing loop connection: %v" , err )
231- return err
232- }
233- }
234-
235- if p .poolConn != nil {
236- if err := p .poolConn .Close (); err != nil {
237- log .Errorf ("Error closing pool connection: %v" , err )
238- return err
239- }
240- }
241-
242188 return nil
243189}
244190
@@ -303,6 +249,12 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
303249
304250 outCtx := metadata .NewOutgoingContext (ctx , mdCopy )
305251
252+ // Check that the target subsystem is running.
253+ err := p .checkSubSystemStarted (requestURI )
254+ if err != nil {
255+ return nil , nil , err
256+ }
257+
306258 // Is there a basic auth or super macaroon set?
307259 authHeaders := md .Get ("authorization" )
308260 macHeader := md .Get (HeaderMacaroon )
@@ -344,26 +296,20 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
344296 // since it must either be an lnd call or something that'll be
345297 // handled by the integrated daemons that are hooking into lnd's
346298 // gRPC server.
347- switch {
348- case p .permsMgr .IsFaradayURI (requestURI ) && p .cfg .faradayRemote :
349- return outCtx , p .faradayConn , nil
350-
351- case p .permsMgr .IsLoopURI (requestURI ) && p .cfg .loopRemote :
352- return outCtx , p .loopConn , nil
353-
354- case p .permsMgr .IsPoolURI (requestURI ) && p .cfg .poolRemote :
355- return outCtx , p .poolConn , nil
299+ handled , conn := p .subServerMgr .GetRemoteConn (requestURI )
300+ if handled {
301+ return outCtx , conn , nil
302+ }
356303
357304 // Calls to LiT session RPC aren't allowed in some cases.
358- case p .permsMgr .IsLitURI (requestURI ) && ! allowLitRPC :
305+ if p .permsMgr .IsLitURI (requestURI ) && ! allowLitRPC {
359306 return outCtx , nil , status .Errorf (
360307 codes .Unimplemented , "unknown service %s" ,
361308 requestURI ,
362309 )
363-
364- default :
365- return outCtx , p .lndConn , nil
366310 }
311+
312+ return outCtx , p .lndConn , nil
367313 }
368314}
369315
@@ -379,6 +325,12 @@ func (p *rpcProxy) UnaryServerInterceptor(ctx context.Context, req interface{},
379325 "required for method" , info .FullMethod )
380326 }
381327
328+ // Check that the target subsystem is running.
329+ err := p .checkSubSystemStarted (info .FullMethod )
330+ if err != nil {
331+ return nil , err
332+ }
333+
382334 // For now, basic authentication is just a quick fix until we
383335 // have proper macaroon support implemented in the UI. We allow
384336 // gRPC web requests to have it and "convert" the auth into a
@@ -420,6 +372,12 @@ func (p *rpcProxy) StreamServerInterceptor(srv interface{},
420372 "for method" , info .FullMethod )
421373 }
422374
375+ // Check that the target subsystem is running.
376+ err := p .checkSubSystemStarted (info .FullMethod )
377+ if err != nil {
378+ return err
379+ }
380+
423381 // For now, basic authentication is just a quick fix until we
424382 // have proper macaroon support implemented in the UI. We allow
425383 // gRPC web requests to have it and "convert" the auth into a
@@ -451,6 +409,35 @@ func (p *rpcProxy) StreamServerInterceptor(srv interface{},
451409 return handler (srv , ss )
452410}
453411
412+ // checkSubSystemStarted checks if the subsystem responsible for handling the
413+ // given URI has started.
414+ func (p * rpcProxy ) checkSubSystemStarted (requestURI string ) error {
415+ var system string
416+
417+ handled , subServerName := p .subServerMgr .HandledBy (requestURI )
418+
419+ switch {
420+ case handled :
421+ system = subServerName
422+
423+ case p .permsMgr .IsLndURI (requestURI ):
424+ return nil
425+
426+ case p .permsMgr .IsLitURI (requestURI ):
427+ return nil
428+
429+ default :
430+ return fmt .Errorf ("unknown gRPC web request: %v" , requestURI )
431+ }
432+
433+ started , startErr := p .statusServer .getSubServerState (system )
434+ if ! started {
435+ return fmt .Errorf ("%s has not running: %s" , system , startErr )
436+ }
437+
438+ return nil
439+ }
440+
454441// convertBasicAuth tries to convert the HTTP authorization header into a
455442// macaroon based authentication header.
456443func (p * rpcProxy ) convertBasicAuth (ctx context.Context ,
@@ -502,30 +489,15 @@ func (p *rpcProxy) basicAuthToMacaroon(basicAuth, requestURI string,
502489 macPath string
503490 macData []byte
504491 )
492+
493+ handled , path := p .subServerMgr .MacaroonPath (requestURI )
494+
505495 switch {
506496 case p .permsMgr .IsLndURI (requestURI ):
507497 _ , _ , _ , macPath , macData = p .cfg .lndConnectParams ()
508498
509- case p .permsMgr .IsFaradayURI (requestURI ):
510- if p .cfg .faradayRemote {
511- macPath = p .cfg .Remote .Faraday .MacaroonPath
512- } else {
513- macPath = p .cfg .Faraday .MacaroonPath
514- }
515-
516- case p .permsMgr .IsLoopURI (requestURI ):
517- if p .cfg .loopRemote {
518- macPath = p .cfg .Remote .Loop .MacaroonPath
519- } else {
520- macPath = p .cfg .Loop .MacaroonPath
521- }
522-
523- case p .permsMgr .IsPoolURI (requestURI ):
524- if p .cfg .poolRemote {
525- macPath = p .cfg .Remote .Pool .MacaroonPath
526- } else {
527- macPath = p .cfg .Pool .MacaroonPath
528- }
499+ case handled :
500+ macPath = path
529501
530502 case p .permsMgr .IsLitURI (requestURI ):
531503 macPath = p .cfg .MacaroonPath
@@ -604,21 +576,9 @@ func (p *rpcProxy) convertSuperMacaroon(ctx context.Context, macHex string,
604576
605577 // Is this actually a request that goes to a daemon that is running
606578 // remotely?
607- switch {
608- case p .permsMgr .IsFaradayURI (fullMethod ) && p .cfg .faradayRemote :
609- return readMacaroon (lncfg .CleanAndExpandPath (
610- p .cfg .Remote .Faraday .MacaroonPath ,
611- ))
612-
613- case p .permsMgr .IsLoopURI (fullMethod ) && p .cfg .loopRemote :
614- return readMacaroon (lncfg .CleanAndExpandPath (
615- p .cfg .Remote .Loop .MacaroonPath ,
616- ))
617-
618- case p .permsMgr .IsPoolURI (fullMethod ) && p .cfg .poolRemote :
619- return readMacaroon (lncfg .CleanAndExpandPath (
620- p .cfg .Remote .Pool .MacaroonPath ,
621- ))
579+ handled , macBytes , err := p .subServerMgr .ReadRemoteMacaroon (fullMethod )
580+ if handled {
581+ return macBytes , err
622582 }
623583
624584 return nil , nil
0 commit comments