@@ -157,7 +157,7 @@ func generateRequestId() string {
157157}
158158
159159// Given an origin's broker URL, return a connected socket to the origin
160- func ConnectToOrigin (ctx context.Context , brokerUrl , prefix , originName string ) (conn net.Conn , err error ) {
160+ func ConnectToService (ctx context.Context , brokerUrl , prefix , originName string ) (conn net.Conn , err error ) {
161161
162162 // Ensure we have a local CA for signing an origin host certificate.
163163 if err = config .GenerateCACert (); err != nil {
@@ -226,7 +226,7 @@ func ConnectToOrigin(ctx context.Context, brokerUrl, prefix, originName string)
226226 // Create a cloned transport which disables HTTP/2 (as that TCP string can't
227227 // be hijacked which we will need to do below). The clone ensures that we're
228228 // not going to be reusing TCP connections.
229- tr := config .GetTransport ().Clone ()
229+ tr := config .GetBasicTransport ().Clone ()
230230 tr .TLSNextProto = make (map [string ]func (string , * tls.Conn ) http.RoundTripper )
231231 client := & http.Client {Transport : tr }
232232
@@ -385,7 +385,7 @@ func ConnectToOrigin(ctx context.Context, brokerUrl, prefix, originName string)
385385//
386386// The TCP socket used for the callback will be converted to a one-shot listener
387387// and reused with the origin as the "server".
388- func doCallback (ctx context.Context , brokerResp reversalRequest ) (listener net.Listener , err error ) {
388+ func doCallback (ctx context.Context , sType server_structs. ServerType , brokerResp reversalRequest ) (listener net.Listener , err error ) {
389389 log .Debugln ("Origin starting callback to cache at" , brokerResp .CallbackUrl )
390390
391391 privateKey , err := privateKeyFromBytes (brokerResp .PrivateKey )
@@ -415,7 +415,18 @@ func doCallback(ctx context.Context, brokerResp reversalRequest) (listener net.L
415415 }
416416 cacheAud .Path = ""
417417
418- token , err := createToken (param .Origin_FederationPrefix .GetString (), param .Server_Hostname .GetString (), cacheAud .String (), token_scopes .Broker_Callback )
418+ servicePrefix := ""
419+ url , err := url .Parse (param .Server_ExternalWebUrl .GetString ())
420+ if err != nil {
421+ err = errors .Wrap (err , "failure when parsing the external web URL" )
422+ return
423+ }
424+ if sType .IsEnabled (server_structs .CacheType ) {
425+ servicePrefix = server_structs .GetCacheNs (url .Hostname ())
426+ } else {
427+ servicePrefix = server_structs .GetOriginNs (url .Host )
428+ }
429+ token , err := createToken (servicePrefix , url .Hostname (), cacheAud .String (), token_scopes .Broker_Callback )
419430 if err != nil {
420431 err = errors .Wrap (err , "failure when constructing the cache callback token" )
421432 return
@@ -550,32 +561,59 @@ func doCallback(ctx context.Context, brokerResp reversalRequest) (listener net.L
550561// TLS listener where you can invoke "Accept" once before it automatically
551562// closes itself. It is the result of a successful connection reversal to
552563// a cache.
553- func LaunchRequestMonitor (ctx context.Context , egrp * errgroup.Group , resultChan chan any ) (err error ) {
564+ //
565+ // The request monitor is used by the "private service" (the service behind the
566+ // firewall) to know when to setup connections requested by the "public service"
567+ // (e.g., a cache).
568+ func LaunchRequestMonitor (ctx context.Context , egrp * errgroup.Group , sType server_structs.ServerType , privateName string , resultChan chan any ) (err error ) {
554569 fedInfo , err := config .GetFederation (ctx )
555570 if err != nil {
556571 return err
557572 }
558573
574+ prefix := ""
575+ if sType .IsEnabled (server_structs .CacheType ) {
576+ prefix = server_structs .GetCacheNs (privateName )
577+ } else {
578+ prefix = server_structs .GetOriginNs (privateName )
579+ }
580+
559581 brokerUrl := fedInfo .BrokerEndpoint
560582 if brokerUrl == "" {
561583 return errors .New ("Broker service is not set or discovered; cannot enable broker functionality. Try setting Federation.BrokerUrl" )
562584 }
563585 brokerEndpoint := brokerUrl + "/api/v1.0/broker/retrieve"
564- originUrl , err := url .Parse (param .Server_ExternalWebUrl .GetString ())
565- if err != nil {
566- return
567- }
568586 oReq := originRequest {
569- Origin : originUrl . Hostname () ,
570- Prefix : param . Origin_FederationPrefix . GetString () ,
587+ Origin : privateName ,
588+ Prefix : prefix ,
571589 }
572590 req , err := json .Marshal (& oReq )
573591 if err != nil {
574592 return
575593 }
576594 reqReader := bytes .NewReader (req )
577595
596+ // Create a token that will be used to retrieve requests from the broker;
597+ // this is done before the goroutine starts to guarantee that we are looking up
598+ // the Viper config from a single-threaded context. Otherwise, during startup,
599+ // we may have concurrent read and write operations to the Viper config, which
600+ // can lead to a panic.
601+ brokerAud , err := url .Parse (fedInfo .BrokerEndpoint )
602+ if err != nil {
603+ log .Errorln ("Failure when parsing broker URL:" , err )
604+ return
605+ }
606+ brokerAud .Path = ""
607+ token , err := createToken (prefix , param .Server_Hostname .GetString (), brokerAud .String (), token_scopes .Broker_Retrieve )
608+ if err != nil {
609+ log .Errorln ("Failure when constructing the broker retrieve token:" , err )
610+ return
611+ }
612+
613+ client := & http.Client {Transport : config .GetBasicTransport ()}
614+
578615 egrp .Go (func () (err error ) {
616+ firstLoop := true
579617 for {
580618 sleepDuration := time .Second + time .Duration (mrand .Intn (500 ))* time .Microsecond
581619 select {
@@ -595,25 +633,21 @@ func LaunchRequestMonitor(ctx context.Context, egrp *errgroup.Group, resultChan
595633 req .Header .Set ("Content-Type" , "application/json" )
596634 req .Header .Set ("User-Agent" , "pelican-origin/" + config .GetVersion ())
597635
598- brokerAud , err := url .Parse (fedInfo .BrokerEndpoint )
599- if err != nil {
600- log .Errorln ("Failure when parsing broker URL:" , err )
601- break
602- }
603- brokerAud .Path = ""
604-
605- token , err := createToken (param .Origin_FederationPrefix .GetString (), param .Server_Hostname .GetString (), brokerAud .String (), token_scopes .Broker_Retrieve )
606- if err != nil {
607- log .Errorln ("Failure when constructing the broker retrieve token:" , err )
608- break
636+ if ! firstLoop {
637+ token , err = createToken (prefix , param .Server_Hostname .GetString (), brokerAud .String (), token_scopes .Broker_Retrieve )
638+ if err != nil {
639+ log .Errorln ("Failure when constructing the broker retrieve token:" , err )
640+ break
641+ }
609642 }
643+ firstLoop = false
610644 req .Header .Set ("Authorization" , "Bearer " + token )
611645
612- tr := config .GetTransport ()
613- client := & http.Client {Transport : tr }
614-
615646 resp , err := client .Do (req )
616647 if err != nil {
648+ if errors .Is (err , context .Canceled ) {
649+ break
650+ }
617651 log .Errorln ("Failure when invoking the broker URL for retrieving requests" , err )
618652 break
619653 }
@@ -642,7 +676,7 @@ func LaunchRequestMonitor(ctx context.Context, egrp *errgroup.Group, resultChan
642676 }
643677
644678 if brokerResp .Status == server_structs .RespOK {
645- listener , err := doCallback (ctx , brokerResp .Request )
679+ listener , err := doCallback (ctx , sType , brokerResp .Request )
646680 if err != nil {
647681 if errors .Is (err , context .Canceled ) {
648682 log .Debugln ("Shutdown encountered while processing callback" )
0 commit comments