|
||||
File indexing completed on 2025-01-30 10:27:57
0001 #ifndef __XRDXROOTDBRIDGE_HH_ 0002 #define __XRDXROOTDBRIDGE_HH_ 0003 /******************************************************************************/ 0004 /* */ 0005 /* X r d X r o o t d B r i d g e . h h */ 0006 /* */ 0007 /* (c) 2012 by the Board of Trustees of the Leland Stanford, Jr., University */ 0008 /* All Rights Reserved */ 0009 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 0010 /* DE-AC02-76-SFO0515 with the Department of Energy */ 0011 /* */ 0012 /* This file is part of the XRootD software suite. */ 0013 /* */ 0014 /* XRootD is free software: you can redistribute it and/or modify it under */ 0015 /* the terms of the GNU Lesser General Public License as published by the */ 0016 /* Free Software Foundation, either version 3 of the License, or (at your */ 0017 /* option) any later version. */ 0018 /* */ 0019 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ 0020 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ 0021 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ 0022 /* License for more details. */ 0023 /* */ 0024 /* You should have received a copy of the GNU Lesser General Public License */ 0025 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ 0026 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */ 0027 /* */ 0028 /* The copyright holder's institutional names and contributor's names may not */ 0029 /* be used to endorse or promote products derived from this software without */ 0030 /* specific prior written permission of the institution or contributor. */ 0031 /******************************************************************************/ 0032 0033 #include <cstring> 0034 0035 #include "XProtocol/XPtypes.hh" 0036 0037 //----------------------------------------------------------------------------- 0038 //! Bridge 0039 //! 0040 //! The Bridge object allows other protocols to gain access to the xrootd 0041 //! protocol stack. Almost any kind of request/response protocol can use this 0042 //! class to convert its request to an xroot protocol request and rewrite the 0043 //! xroot protocol response to adhere to its protocol specification. Callers 0044 //! of these methods must be thread-safe and must not rely on thread-local 0045 //! storage as bridge requests and responses may or may not be executed using 0046 //! the initiating thread. Also, see the Result object class below. 0047 //----------------------------------------------------------------------------- 0048 0049 struct iovec; 0050 class XrdLink; 0051 class XrdSecEntity; 0052 class XrdXrootdProtocol; 0053 0054 namespace XrdXrootd 0055 { 0056 0057 /******************************************************************************/ 0058 /* X r d X r o o t d : : B r i d g e */ 0059 /******************************************************************************/ 0060 0061 class Bridge 0062 { 0063 public: 0064 class Result; 0065 0066 //----------------------------------------------------------------------------- 0067 //! Create a Bridge object. 0068 //! 0069 //! The first step is to create a Bridge object via a Login() call. The object 0070 //! should correspond to a session (i.e. tied to a particular client) real or 0071 //! not. The returned object must be used to inject xrootd requests into the 0072 //! protocol stack. Response rewrites are handled by the Result object passed as 0073 //! an argument. A successful Login() takes control of the connection. You can 0074 //! still write using the Link object but reads may only occur when your 0075 //! protocol's Process() method is called. Use Disc() to disband the bridge and 0076 //! free its storage. The bridge is automatically disbanded when your protocol's 0077 //! Recycle() method is called. This happens when you explicitly close the link 0078 //! or implicitly when the Process() method returns a negative error code or 0079 //! a callback method returns false. 0080 //! 0081 //! @param rsltP a pointer to the result object. This object is used to 0082 //! to rewrite xrootd responses to protocol specific responses. 0083 //! It must be allocated by the caller. One such object can be 0084 //! created for each session or, if the protocol allows, be 0085 //! shared by all sessions. It cannot be deleted until all 0086 //! references to the object disappear (see the Result class). 0087 //! @param linkP a pointer to the link object that the protocol driver 0088 //! created to the client connection. 0089 //! @param seceP a pointer to the XrdSecEntity object that describes the 0090 //! client's identity. 0091 //! @param nameP An arbitrary 1-to-8 character client name. The Bridge will 0092 //! uniquefy this name so that log file messages will track the 0093 //! the associated client. The link's identity is set to 0094 //! correspond to this name with additional information. 0095 //! @param protP a 1-to-7 character name of the protocol using this bridge 0096 //! (e.g. "http"). 0097 //! 0098 //! @return bridgeP a pointer to a new instance of this class if a bridge 0099 //! could be created, null otherwise. If null is returned, the 0100 //! retc variable holds the errno indicating why it failed. 0101 //----------------------------------------------------------------------------- 0102 0103 static 0104 Bridge *Login(Result *rsltP, //!< The result callback object 0105 XrdLink *linkP, //!< Client's network connection 0106 XrdSecEntity *seceP, //!< Client's identity 0107 const char *nameP, //!< Client's name for tracking 0108 const char *protP //!< Protocol name for tracking 0109 ); 0110 0111 //----------------------------------------------------------------------------- 0112 //! Inject an xrootd request into the protocol stack. 0113 //! 0114 //! The Run() method allows you to inject an xrootd-style request into the 0115 //! stack. It must use the same format as a real xrootd client would use across 0116 //! the network. The xroot protocol reference describes these requests. The 0117 //! Run() method handles the request as if it came through the network with 0118 //! some notable exceptions (see the xdataP and xdataL arguments). 0119 //! 0120 //! @param xreqP pointer to the xrootd request. This is the standard 24-byte 0121 //! request header common to all xrootd requests in network 0122 //! format. The contents of the buffer may be modified by the 0123 //! this method. The buffer must not be modified by the caller 0124 //! before a response is solicited via the Result object. 0125 //! 0126 //! @param xdataP the associated data for this request. Full or partial data 0127 //! may be supplied as indicated by the xdataL argument. See 0128 //! explanation of xdataL. For write requests, this buffer may 0129 //! not be altered or deleted until the Result Free() callback 0130 //! is invoked. For other requests, it doesn't matter. 0131 //! 0132 //! If the pointer is zero but the "dlen" field is not zero, 0133 //! dlen's worth of data is read from the network using the 0134 //! associated XdLink object to complete the request. 0135 //! 0136 //! @param xdataL specifies the length of data in the buffer pointed to by 0137 //! xdataP. Depending on the value and the value in the "dlen" 0138 //! field, additional data may be read from the network. 0139 //! 0140 //! xdataL < "dlen": dlen-xdataL additional bytes will be read 0141 //! from the network to complete the request. 0142 //! xdataL >= "dlen": no additional bytes will be read from the 0143 //! network. The request data is complete. 0144 //! 0145 //! @return true the request has been accepted. Processing will start when 0146 //! the caller returns from the Process() method. 0147 //! A response will come via a Result object callback. 0148 //! false the request has been rejected because the bridge is still 0149 //! processing a previous request. 0150 //----------------------------------------------------------------------------- 0151 0152 virtual bool Run(const char *xreqP, //!< xrootd request header 0153 char *xdataP=0, //!< xrootd request data (optional) 0154 int xdataL=0 //!< xrootd request data length 0155 ) = 0; 0156 0157 //----------------------------------------------------------------------------- 0158 //! Disconnect the session from the bridge. 0159 //! 0160 //! The Disc() method allows you to disconnect the session from the bridge and 0161 //! free the storage associated with this object. It may be called when you want 0162 //! to regain control of the connection and delete the Bridge object (note that 0163 //! you cannot use delete on Bridge). The Disc() method must not be called in 0164 //! your protocol Recycle() method as protocol object recycling already implies 0165 //! a Disc() call (i.e. the connection is disbanding the associated protocol). 0166 //! 0167 //! @return true the bridge has been dismantled. 0168 //! false the bridge cannot be dismantled because it is still 0169 //! processing a previous request. 0170 //----------------------------------------------------------------------------- 0171 0172 virtual bool Disc() = 0; 0173 0174 //----------------------------------------------------------------------------- 0175 //! Set file's sendfile capability. 0176 //! 0177 //! The setSF() method allows you to turn on or off the ability of an open 0178 //! file to be used with the sendfile() system call. This is useful when you 0179 //! must see the data prior to sending to the client (e.g. for encryption). 0180 //! 0181 //! @param fhandle the filehandle as returned by kXR_open. 0182 //! @param seton When true, enables sendfile() otherwise it is disabled. 0183 //! 0184 //! @return =0 Sucessful. 0185 //! @return <0 Call failed. The return code is -errno and usually will 0186 //! indicate that the filehandle is not valid. 0187 //----------------------------------------------------------------------------- 0188 0189 virtual int setSF(kXR_char *fhandle, bool seton=false) = 0; 0190 0191 //----------------------------------------------------------------------------- 0192 //! Set the maximum delay. 0193 //! 0194 //! The setWait() method allows you to specify the maximum amount of time a 0195 //! request may be delayed (i.e. via kXR_wait result) before it generates a 0196 //! kXR_Cancelled error with the associated Error() result callback. The default 0197 //! maximum time is 1 hour. If you specify a time less than or equal to zero, 0198 //! wait requests are reflected back via the Wait() result callback method and 0199 //! you are responsible for handling them. You can request wait notification 0200 //! while still having the wait internally handled using the second parameter. 0201 //! Maximum delays are bridge specific. There is no global value. If you desire 0202 //! something other than the default you must call SetWait for each Login(). 0203 //! 0204 //! @param wtime the maximum wait time in seconds. 0205 //! @param notify When true, issues a Wait callback whenever a wait occurs. 0206 //! This is the default when wtime is <= 0. 0207 //! 0208 //----------------------------------------------------------------------------- 0209 0210 virtual void SetWait(int wtime, bool notify=false) = 0; 0211 0212 /******************************************************************************/ 0213 /* X r d X r o o t d : : B r i d g e : : C o n t e x t */ 0214 /******************************************************************************/ 0215 0216 //----------------------------------------------------------------------------- 0217 //! Provide callback context. 0218 //! 0219 //! The Context object is passed in all Result object callbacks and contains 0220 //! information describing the result context. No public members should be 0221 //! changed by any result callback method. The context object also includes a 0222 //! method that must be used to complete a pending sendfile() result. 0223 //----------------------------------------------------------------------------- 0224 0225 class Context 0226 { 0227 public: 0228 0229 XrdLink *linkP; //!< -> associated session link object (i.e. connection) 0230 kXR_unt16 rCode; //!< associated "kXR" request code in host byte order 0231 union{kXR_unt16 num; //!< associated stream ID as a short 0232 kXR_char chr[2];//!< associated stream ID as the original char[2] 0233 } sID; //!< associated request stream ID 0234 0235 //----------------------------------------------------------------------------- 0236 //! Complete a File() callback. 0237 //! 0238 //! The Send() method must be called after the File() callback is invoked to 0239 //! complete data transmission using sendfile(). If Send() is not called the 0240 //! pending sendfile() call is not made and no data is sent to the client. 0241 //! 0242 //! @param headP a pointer to the iovec structure containing the data that 0243 //! must be sent before the sendfile() data. If there is none, 0244 //! the pointer can be null. 0245 //! @param headN the number of elements in the headP iovec structure array. 0246 //! @param tailP a pointer to the iovec structure containing the data that 0247 //! must be sent after the sendfile() data. If there is none, 0248 //! the pointer can be null. 0249 //! @param tailN the number of elements in the tailP iovec structure array. 0250 //! 0251 //! @return < 0 transmission error has occurred. This can be due to either 0252 //! connection failure or data source error (i.e. I/O error). 0253 //! = 0 data has been successfully sent. 0254 //! > 0 the supplied context was not generated by a valid File() 0255 //! callback. No data has been sent. 0256 //----------------------------------------------------------------------------- 0257 0258 virtual int Send(const 0259 struct iovec *headP, //!< pointer to leading data array 0260 int headN, //!< array count 0261 const 0262 struct iovec *tailP, //!< pointer to trailing data array 0263 int tailN //!< array count 0264 ) 0265 { 0266 (void)headP; (void)headN; (void)tailP; (void)tailN; 0267 return 1; 0268 } 0269 0270 //----------------------------------------------------------------------------- 0271 //! Constructor and Destructor 0272 //----------------------------------------------------------------------------- 0273 0274 Context(XrdLink *lP, kXR_char *sid, kXR_unt16 req) 0275 : linkP(lP), rCode(req) 0276 {memcpy(sID.chr, sid, sizeof(sID.chr));} 0277 virtual ~Context() {} 0278 }; 0279 0280 /******************************************************************************/ 0281 /* X r d X r o o t d : : B r i d g e : : R e s u l t */ 0282 /******************************************************************************/ 0283 0284 //----------------------------------------------------------------------------- 0285 //! Handle xroot protocol execution results. 0286 //! 0287 //! The Result object is an abstract class that defines the interface used 0288 //! by the xroot protocol stack to effect a client response using whatever 0289 //! alternate protocol is needed. You must define an implementation and pass it 0290 //! as an argument to the Login() Bridge method. 0291 //----------------------------------------------------------------------------- 0292 0293 class Result 0294 { 0295 public: 0296 0297 //----------------------------------------------------------------------------- 0298 //! Effect a client data response. 0299 //! 0300 //! The Data() method is called when Run() resulted in a successful data 0301 //! response. The method should rewrite the data and send it to the client using 0302 //! the associated XrdLink object. As an example, 0303 //! 1) Result::Data(info, iovP, iovN, iovL) is called. 0304 //! 2) Inspect iovP, rewrite the data. 0305 //! 3) Send the response: info->linkP->Send(new_iovP, new_iovN, new_iovL); 0306 //! 4) Handle send errors and cleanup(e.g. deallocate storage). 0307 //! 5) Return, the exchange is now complete. 0308 //! 0309 //! @param info the context associated with the result. 0310 //! @param iovP a pointer to the iovec structure containing the xrootd data 0311 //! response about to be sent to the client. The request header 0312 //! is not included in the iovec structure. The elements of this 0313 //! structure must not be modified by the method. 0314 //! @param iovN the number of elements in the iovec structure array. 0315 //! @param iovL total number of data bytes that would be sent to the client. 0316 //! This is simply the sum of all the lengths in the iovec. 0317 //! @param final True is this is the final result. Otherwise, this is a 0318 //! partial result (i.e. kXR_oksofar) and more data will result 0319 //! causing additional callbacks. For write requests, any 0320 //! supplied data buffer may now be reused or freed. 0321 //! 0322 //! @return true continue normal processing. 0323 //! false terminate the bridge and close the link. 0324 //----------------------------------------------------------------------------- 0325 0326 virtual bool Data(Bridge::Context &info, //!< the result context 0327 const 0328 struct iovec *iovP, //!< pointer to data array 0329 int iovN, //!< array count 0330 int iovL, //!< byte count 0331 bool final //!< true -> final result 0332 ) = 0; 0333 0334 //----------------------------------------------------------------------------- 0335 //! Effect a client acknowledgement. 0336 //! 0337 //! The Done() method is called when Run() resulted in success and there is no 0338 //! associated data for the client (equivalent to a simple kXR_ok response). 0339 //! 0340 //! @param info the context associated with the result. 0341 //! 0342 //! @return true continue normal processing. 0343 //! false terminate the bridge and close the link. 0344 //----------------------------------------------------------------------------- 0345 0346 virtual bool Done(Bridge::Context &info)=0;//!< the result context 0347 0348 //----------------------------------------------------------------------------- 0349 //! Effect a client error response. 0350 //! 0351 //! The Error() method is called when an error was encountered while processing 0352 //! the Run() request. The error should be reflected to the client. 0353 //! 0354 //! @param info the context associated with the result. 0355 //! @param ecode the "kXR" error code describing the nature of the error. 0356 //! The code is in host byte format. 0357 //! @param etext a null terminated string describing the error in human terms 0358 //! 0359 //! @return true continue normal processing. 0360 //! false terminate the bridge and close the link. 0361 //----------------------------------------------------------------------------- 0362 0363 virtual bool Error(Bridge::Context &info, //!< the result context 0364 int ecode, //!< the "kXR" error code 0365 const char *etext //!< associated error message 0366 ) = 0; 0367 0368 //----------------------------------------------------------------------------- 0369 //! Notify callback that a sendfile() request is pending. 0370 //! 0371 //! The File() method is called when Run() resulted in a sendfile response (i.e. 0372 //! sendfile() would have been used to send data to the client). This allows 0373 //! the callback to reframe the sendfile() data using the Send() method in the 0374 //! passed context object (see class Context above). 0375 //! 0376 //! @param info the context associated with the result. 0377 //! @param dlen total number of data bytes that would be sent to the client. 0378 //! 0379 //! @return true continue normal processing. 0380 //! false terminate the bridge and close the link. 0381 //----------------------------------------------------------------------------- 0382 0383 virtual int File(Bridge::Context &info, //!< the result context 0384 int dlen //!< byte count 0385 ) = 0; 0386 0387 //----------------------------------------------------------------------------- 0388 //! Notify callback that a write buffer is now available for reuse. 0389 //! 0390 //! The Free() method is called when Run() was called to write data and a buffer 0391 //! was supplied. Normally, he buffer is pinned and cannot be reused until the 0392 //! write completes. This callback provides the notification that the buffer is 0393 //! no longer in use. The callback is invoked prior to any other callbacks and 0394 //! is only invoked if a buffer was supplied. 0395 //! 0396 //! @param info the context associated with this call. 0397 //! @param buffP pointer to the buffer. 0398 //! @param buffL the length originally supplied in the Run() call. 0399 //----------------------------------------------------------------------------- 0400 0401 virtual void Free(Bridge::Context &info, //!< the result context 0402 char *buffP, //!< pointer to the buffer 0403 int buffL //!< original length to Run() 0404 ) 0405 { 0406 (void)info; (void)buffP; (void)buffL; 0407 } 0408 0409 //----------------------------------------------------------------------------- 0410 //! Redirect the client to another host:port. 0411 //! 0412 //! The Redir() method is called when the client must be redirected to another 0413 //! host. 0414 //! 0415 //! @param info the context associated with the result. 0416 //! @param port the port number in host byte format. 0417 //! @param hname the DNS name of the host or IP address is IPV4 or IPV6 0418 //! format (i.e. "n.n.n.n" or "[ipv6_addr]"). 0419 //! 0420 //! @return true continue normal processing. 0421 //! false terminate the bridge and close the link. 0422 //----------------------------------------------------------------------------- 0423 0424 virtual bool Redir(Bridge::Context &info, //!< the result context 0425 int port, //!< the port number 0426 const char *hname //!< the destination host 0427 ) = 0; 0428 0429 //----------------------------------------------------------------------------- 0430 //! Effect a client wait. 0431 //! 0432 //! The Wait() method is called when Run() needs to delay a request. Normally, 0433 //! delays are internally handled. However, you can request that delays be 0434 //! reflected via a callback using the Bridge SetWait() method. 0435 //! 0436 //! @param info the context associated with the result. 0437 //! @param wtime the number of seconds to delay the request. 0438 //! @param wtext a null terminated string describing the wait in human terms 0439 //! 0440 //! @return true continue normal processing. 0441 //! false terminate the bridge and close the link. 0442 //----------------------------------------------------------------------------- 0443 0444 virtual bool Wait(Bridge::Context &info, //!< the result context 0445 int wtime, //!< the wait time 0446 const char *wtext //!< associated message 0447 ) 0448 { 0449 (void)info; (void)wtime; (void)wtext; 0450 return false; 0451 } 0452 0453 //----------------------------------------------------------------------------- 0454 //! Effect a client wait response (waitresp) NOT CURRENTLY IMPLEMENTED! 0455 //! 0456 //! The WaitResp() method is called when an operation ended with a wait for 0457 //! response (waitresp) condition. The wait for response condition indicates 0458 //! that the actual response will be delivered at a later time. You can use 0459 //! context object to determine the operation being delayed. This callback 0460 //! provides you the opportunity to say how the waitresp is to be handled. 0461 //! 0462 //! @param info the context associated with the result. 0463 //! @param wtime the number of seconds in which a response is expected. 0464 //! @param wtext a null terminated string describing the delay in human terms 0465 //! 0466 //! @return !0 pointer to the callback object whose appropriate method 0467 //! should be called when the actual response is generated. 0468 //! @return 0 the waitresp will be handled by the bridge application. The 0469 //! application is responsible for re-issuing the request when 0470 //! the final response is a wait. 0471 //----------------------------------------------------------------------------- 0472 virtual 0473 Bridge::Result *WaitResp(Bridge::Context &info, //!< the result context 0474 int wtime, //!< the wait time 0475 const char *wtext //!< associated message 0476 ) 0477 { 0478 (void)info; (void)wtime; (void)wtext; 0479 return 0; 0480 } 0481 0482 //----------------------------------------------------------------------------- 0483 //! Constructor & Destructor 0484 //----------------------------------------------------------------------------- 0485 0486 Result() {} 0487 virtual ~Result() {} 0488 }; 0489 0490 //----------------------------------------------------------------------------- 0491 //! Constructor & Destructor 0492 //----------------------------------------------------------------------------- 0493 0494 Bridge() {} 0495 protected: 0496 virtual ~Bridge() {} 0497 }; 0498 } 0499 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |