Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/xrootd/XProtocol/XProtocol.hh was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 #ifndef __XPROTOCOL_H
0002 #define __XPROTOCOL_H
0003 /******************************************************************************/
0004 /*                                                                            */
0005 /*                          X P r o t o c o l . 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 /* The XRoot protocol definition, documented in this file, is distributed     */
0020 /* under a modified BSD license and may be freely used to reimplement it.     */
0021 /* Any references to "source" in this license refers to this file or any      */
0022 /* other file that specifically contains the following license.               */
0023 /*                                                                            */
0024 /* Redistribution and use in source and binary forms, with or without         */
0025 /* modification, are permitted provided that the following conditions         */
0026 /* are met:                                                                   */
0027 /*                                                                            */
0028 /* 1. Redistributions of source code must retain the above copyright notice,  */
0029 /*    this list of conditions and the following disclaimer.                   */
0030 /*                                                                            */
0031 /* 2. Redistributions in binary form must reproduce the above copyright       */
0032 /*    notice, this list of conditions and the following disclaimer in the     */
0033 /*    documentation and/or other materials provided with the distribution.    */
0034 /*                                                                            */
0035 /* 3. Neither the name of the copyright holder nor the names of its           */
0036 /*    contributors may be used to endorse or promote products derived from    */
0037 /*    this software without specific prior written permission.                */
0038 /*                                                                            */
0039 /* 4. Derived software may not use the name XRootD or cmsd (regardless of     */
0040 /*    capitilization) in association with the derived work if the protocol    */
0041 /*    documented in this file is changed in any way.                          */
0042 /*                                                                            */
0043 /*    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     */
0044 /*    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT       */
0045 /*    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   */
0046 /*    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT    */
0047 /*    HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  */
0048 /*    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        */
0049 /*    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,   */
0050 /*    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY   */
0051 /*    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT     */
0052 /*    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
0053 /******************************************************************************/
0054 
0055 #ifdef __CINT__
0056 #define __attribute__(x)
0057 #endif
0058 
0059 #include "XProtocol/XPtypes.hh"
0060 
0061 /******************************************************************************/
0062 /*          P r o t o c o l   V e r s i o n   D e f i n i t i o n s           */
0063 /******************************************************************************/
0064   
0065 // The following is the binary representation of the protocol version here.
0066 // Protocol version is repesented as three base10 digits x.y.z with x having no
0067 // upper limit (i.e. n.9.9 + 1 -> n+1.0.0). The kXR_PROTSIGNVERSION defines the
0068 // protocol version where request signing became available.
0069 //
0070 #define kXR_PROTOCOLVERSION  0x00000511
0071 #define kXR_PROTXATTVERSION  0x00000500
0072 #define kXR_PROTTLSVERSION   0x00000500
0073 #define kXR_PROTPGRWVERSION  0x00000511
0074 #define kXR_PROTSIGNVERSION  0x00000310
0075 #define kXR_PROTOCOLVSTRING "5.1.0"
0076 
0077 /******************************************************************************/
0078 /*               C l i e n t - S e r v e r   H a n d s h a k e                */
0079 /******************************************************************************/
0080 
0081 // The fields to be sent as initial handshake
0082 //
0083 struct ClientInitHandShake {
0084    kXR_int32 first;
0085    kXR_int32 second;
0086    kXR_int32 third;
0087    kXR_int32 fourth;
0088    kXR_int32 fifth;
0089 };
0090 
0091 // The body received after the first handshake's header
0092 //
0093 struct ServerInitHandShake {
0094    kXR_int32 msglen;
0095    kXR_int32 protover;
0096    kXR_int32 msgval;
0097 };
0098   
0099 /******************************************************************************/
0100 /*                       C l i e n t   R e q u e s t s                        */
0101 /******************************************************************************/
0102 
0103 // G.Ganis: All the following structures never need padding bytes:
0104 //          no need of packing options like __attribute__((packed))
0105 //
0106 // All binary data is sent in network byte order.
0107 
0108 // Client request codes
0109 // 
0110 enum XRequestTypes {
0111    kXR_1stRequest= 3000,
0112    kXR_auth    =   3000,
0113    kXR_query,   // 3001
0114    kXR_chmod,   // 3002
0115    kXR_close,   // 3003
0116    kXR_dirlist, // 3004
0117    kXR_gpfile,  // 3005 was kXR_getfile
0118    kXR_protocol,// 3006
0119    kXR_login,   // 3007
0120    kXR_mkdir,   // 3008
0121    kXR_mv,      // 3009
0122    kXR_open,    // 3010
0123    kXR_ping,    // 3011
0124    kXR_chkpoint,// 3012 was kXR_putfile
0125    kXR_read,    // 3013
0126    kXR_rm,      // 3014
0127    kXR_rmdir,   // 3015
0128    kXR_sync,    // 3016
0129    kXR_stat,    // 3017
0130    kXR_set,     // 3018
0131    kXR_write,   // 3019
0132    kXR_fattr,   // 3020 was kXR_admin
0133    kXR_prepare, // 3021
0134    kXR_statx,   // 3022
0135    kXR_endsess, // 3023
0136    kXR_bind,    // 3024
0137    kXR_readv,   // 3025
0138    kXR_pgwrite, // 3026 was kXR_verifyw
0139    kXR_locate,  // 3027
0140    kXR_truncate,// 3028
0141    kXR_sigver,  // 3029
0142    kXR_pgread,  // 3030 was kXR_decrypt
0143    kXR_writev,  // 3031
0144    kXR_REQFENCE // Always last valid request code +1
0145 };
0146 
0147 // Virtual client request codes
0148 //
0149 enum XVirtRequestTypes {
0150    kXR_virtReadv = 2000
0151 };
0152 
0153 // All client requests use a header with the following format
0154 //
0155 struct ClientRequestHdr {
0156    kXR_char  streamid[2];
0157    kXR_unt16 requestid;
0158    kXR_char  body[16];
0159    kXR_int32 dlen;
0160 };
0161 
0162 /******************************************************************************/
0163 /*                      k X R _ a u t h   R e q u e s t                       */
0164 /******************************************************************************/
0165   
0166 struct ClientAuthRequest {
0167    kXR_char  streamid[2];
0168    kXR_unt16 requestid;
0169    kXR_char  reserved[12];
0170    kXR_char  credtype[4];
0171    kXR_int32 dlen;
0172 };
0173 
0174 /******************************************************************************/
0175 /*                      k X R _ b i n d   R e q u e s t                       */
0176 /******************************************************************************/
0177   
0178 struct ClientBindRequest {
0179    kXR_char  streamid[2];
0180    kXR_unt16 requestid;
0181    kXR_char  sessid[16];
0182    kXR_int32 dlen;
0183 };
0184 
0185 /******************************************************************************/
0186 /*                     k X R _ c h m o d   R e q u e s t                      */
0187 /******************************************************************************/
0188   
0189 struct ClientChmodRequest {
0190    kXR_char  streamid[2];
0191    kXR_unt16 requestid;
0192    kXR_char  reserved[14];
0193    kXR_unt16 mode;        // See XOpenRequestMode
0194    kXR_int32 dlen;
0195 };
0196 
0197 /******************************************************************************/
0198 /*                  k X R _ c h k p o i n t   R e q u e s t                   */
0199 /******************************************************************************/
0200   
0201 struct ClientChkPointRequest {
0202    kXR_char  streamid[2];
0203    kXR_unt16 requestid;
0204    kXR_char  fhandle[4];    // For Create, Delete, Query, or Restore
0205    kXR_char  reserved[11];
0206    kXR_char  opcode;        // One of kXR_ckpxxxx actions
0207    kXR_int32 dlen;
0208 };
0209 
0210 // Actions
0211 //
0212 static const int kXR_ckpBegin   = 0;  // Begin    checkpoint
0213 static const int kXR_ckpCommit  = 1;  // Commit   changes
0214 static const int kXR_ckpQuery   = 2;  // Query    checkpoint limits
0215 static const int kXR_ckpRollback= 3;  // Rollback changes
0216 static const int kXR_ckpXeq     = 4;  // Execute trunc, write, or writev
0217 
0218 // The minimum size of a checkpoint data limit
0219 //
0220 static const int kXR_ckpMinMax  = 104857604;  // 10 MB
0221   
0222 /******************************************************************************/
0223 /*                     k X R _ c l o s e   R e q u e s t                      */
0224 /******************************************************************************/
0225   
0226 struct ClientCloseRequest {
0227    kXR_char  streamid[2];
0228    kXR_unt16 requestid;
0229    kXR_char  fhandle[4];
0230    kXR_char  reserved[12];
0231    kXR_int32 dlen;
0232 };
0233 
0234 /******************************************************************************/
0235 /*                   k X R _ d i r l i s t   R e q u e s t                    */
0236 /******************************************************************************/
0237 
0238 enum XDirlistRequestOption {
0239    kXR_online = 1,
0240    kXR_dstat  = 2,
0241    kXR_dcksm  = 4    // dcksm implies dstat irrespective of dstat setting
0242 };
0243   
0244 struct ClientDirlistRequest {
0245    kXR_char  streamid[2];
0246    kXR_unt16 requestid;
0247    kXR_char  reserved[15];
0248    kXR_char  options[1];     // See XDirlistRequestOption enum
0249    kXR_int32 dlen;
0250 };
0251 
0252 /******************************************************************************/
0253 /*                   k X R _ e n d s e s s   R e q u e s t                    */
0254 /******************************************************************************/
0255   
0256 struct ClientEndsessRequest {
0257    kXR_char  streamid[2];
0258    kXR_unt16 requestid;
0259    kXR_char  sessid[16];
0260    kXR_int32 dlen;
0261 };
0262 
0263 /******************************************************************************/
0264 /*                     k X R _ f a t t r   R e q u e s t                      */
0265 /******************************************************************************/
0266 
0267 // kXR_fattr subcodes
0268 //
0269 enum xfaSubCode {
0270    kXR_fattrDel    = 0,
0271    kXR_fattrGet    = 1,
0272    kXR_fattrList   = 2,
0273    kXR_fattrSet    = 3,
0274    kXR_fatrrMaxSC  = 3     // Highest valid subcode
0275 };
0276 
0277 // kXR_fattr limits
0278 //
0279 enum xfaLimits {
0280    kXR_faMaxVars = 16,     // Maximum variables per request
0281    kXR_faMaxNlen = 248,    // Maximum length of variable name
0282    kXR_faMaxVlen = 65536   // Maximum length of variable value
0283 };
0284   
0285 struct ClientFattrRequest {
0286    kXR_char  streamid[2];
0287    kXR_unt16 requestid;
0288    kXR_char  fhandle[4];
0289    kXR_char  subcode;      // See xfaSubCode enum
0290    kXR_char  numattr;
0291    kXR_char  options;      // See valid options below
0292    kXR_char  reserved[9];
0293    kXR_int32 dlen;
0294 
0295 // Valid options:
0296 //
0297    static const int isNew = 0x01; // For set,  the variable must not exist
0298    static const int aData = 0x10; // For list, return attribute value
0299 
0300 // Add an attribute name to nvec (the buffer has to be sufficiently big)
0301 //
0302    static char* NVecInsert( const char *name,  char *buffer );
0303 
0304 // Add an attribute name to vvec (the buffer has to be sufficiently big)
0305 //
0306    static char* VVecInsert( const char *value, char *buffer );
0307 
0308 // Read error code from nvec
0309 //
0310    static char* NVecRead( char* buffer, kXR_unt16 &rc );
0311 
0312 // Read attribute name from nvec, should be deallocated with free()
0313 //
0314    static char* NVecRead( char* buffer, char *&name );
0315 
0316 // Read value length from vvec
0317 //
0318    static char* VVecRead( char* buffer, kXR_int32 &len );
0319 
0320 // Read attribute value from vvec, should be deallocated with free()
0321 //
0322    static char* VVecRead( char* buffer, kXR_int32 len, char *&value );
0323 
0324 };
0325   
0326 /******************************************************************************/
0327 /*                    k X R _ g p f i l e   R e q u e s t                     */
0328 /******************************************************************************/
0329   
0330 struct ClientGPfileRequest { // ??? This is all wrong; correct when implemented
0331    kXR_char  streamid[2];
0332    kXR_unt16 requestid;      // kXR_gpfile
0333    kXR_int32 options;
0334    kXR_char reserved[8];
0335    kXR_int32 buffsz;
0336    kXR_int32  dlen;
0337 };
0338 
0339 /******************************************************************************/
0340 /*                    k X R _ l o c a t e   R e q u e s t                     */
0341 /******************************************************************************/
0342   
0343 struct ClientLocateRequest {
0344    kXR_char  streamid[2];
0345    kXR_unt16 requestid;
0346    kXR_unt16 options;     // See XOpenRequestOption enum tagged for locate
0347    kXR_char  reserved[14];
0348    kXR_int32 dlen;
0349 };
0350 
0351 /******************************************************************************/
0352 /*                     k X R _ l o g i n   R e q u e s t                      */
0353 /******************************************************************************/
0354 
0355 // this is a bitmask
0356 enum XLoginAbility {
0357    kXR_nothing    =   0,
0358    kXR_fullurl    =   1,
0359    kXR_multipr    =   3,
0360    kXR_readrdok   =   4,
0361    kXR_hasipv64   =   8,
0362    kXR_onlyprv4   =  16,
0363    kXR_onlyprv6   =  32,
0364    kXR_lclfile    =  64,
0365    kXR_redirflags = 128
0366 };
0367 
0368 // this iss a bitmask
0369 enum XLoginAbility2 {
0370    kXR_empty   = 0,
0371    kXR_ecredir = 1
0372 };
0373 
0374 // this is a bitmask (note that XLoginVersion resides in lower bits)
0375 enum XLoginCapVer {
0376    kXR_lcvnone = 0,
0377    kXR_vermask = 63,
0378    kXR_asyncap = 128
0379 };
0380 
0381 // this is a single number that is or'd into capver as the version
0382 //
0383 enum XLoginVersion {
0384    kXR_ver000 = 0,  // Old clients predating history
0385    kXR_ver001 = 1,  // Generally implemented 2005 protocol
0386    kXR_ver002 = 2,  // Same as 1 but adds asyncresp recognition
0387    kXR_ver003 = 3,  // The 2011-2012 rewritten client
0388    kXR_ver004 = 4,  // The 2016 sign-capable   client
0389    kXR_ver005 = 5   // The 2019 TLS-capable    client
0390 };
0391   
0392 struct ClientLoginRequest {
0393    kXR_char  streamid[2];
0394    kXR_unt16 requestid;
0395    kXR_int32 pid;
0396    kXR_char username[8];
0397    kXR_char ability2;      // See XLoginAbility2 enum flags
0398    kXR_char ability;       // See XLoginAbility  enum flags
0399    kXR_char capver[1];     // See XLoginCapVer   enum flags
0400    kXR_char reserved2;
0401    kXR_int32  dlen;
0402 };
0403 
0404 /******************************************************************************/
0405 /*                     k X R _ m k d i r   R e q u e s t                      */
0406 /******************************************************************************/
0407 
0408 enum XMkdirOptions {
0409    kXR_mknone  = 0,
0410    kXR_mkdirpath  = 1
0411 };
0412   
0413 struct ClientMkdirRequest {
0414    kXR_char  streamid[2];
0415    kXR_unt16 requestid;
0416    kXR_char  options[1];
0417    kXR_char  reserved[13];
0418    kXR_unt16 mode;          // See XOpenRequestMode
0419    kXR_int32 dlen;
0420 };
0421 
0422 /******************************************************************************/
0423 /*                        k X R _ m v   R e q u e s t                         */
0424 /******************************************************************************/
0425   
0426 struct ClientMvRequest {
0427    kXR_char  streamid[2];
0428    kXR_unt16 requestid;
0429    kXR_char  reserved[14];
0430    kXR_int16 arg1len;
0431    kXR_int32 dlen;
0432 };
0433 
0434 /******************************************************************************/
0435 /*                      k X R _ o p e n   R e q u e s t                       */
0436 /******************************************************************************/
0437 
0438 // OPEN MODE FOR A REMOTE FILE
0439 enum XOpenRequestMode {
0440    kXR_ur = 0x100,
0441    kXR_uw = 0x080,
0442    kXR_ux = 0x040,
0443    kXR_gr = 0x020,
0444    kXR_gw = 0x010,
0445    kXR_gx = 0x008,
0446    kXR_or = 0x004,
0447    kXR_ow = 0x002,
0448    kXR_ox = 0x001
0449 };
0450 
0451 enum XOpenRequestOption {
0452    kXR_compress = 0x0001, //     1   // also locate (return unique hosts)
0453    kXR_delete   = 0x0002, //     2
0454    kXR_force    = 0x0004, //     4
0455    kXR_new      = 0x0008, //     8
0456    kXR_open_read= 0x0010, //    16
0457    kXR_open_updt= 0x0020, //    32
0458    kXR_async    = 0x0040, //    64
0459    kXR_refresh  = 0x0080, //   128   // also locate
0460    kXR_mkpath   = 0x0100, //   256
0461    kXR_prefname = 0x0100, //   256   // only locate
0462    kXR_open_apnd= 0x0200, //   512
0463    kXR_retstat  = 0x0400, //  1024
0464    kXR_4dirlist = 0x0400, //  1024   // for locate intending a dirlist
0465    kXR_replica  = 0x0800, //  2048
0466    kXR_posc     = 0x1000, //  4096
0467    kXR_nowait   = 0x2000, //  8192   // also locate
0468    kXR_seqio    = 0x4000, // 16384
0469    kXR_open_wrto= 0x8000  // 32768
0470 };
0471 
0472 enum XOpenRequestOption2 {
0473    kXR_dup      = 0x0001, //     1
0474    kXR_samefs   = 0x0002  //     2
0475 };
0476   
0477 struct ClientOpenRequest {
0478    kXR_char  streamid[2];
0479    kXR_unt16 requestid;
0480    kXR_unt16 mode;
0481    kXR_unt16 options;
0482    kXR_char  reserved[12];
0483    kXR_int32  dlen;
0484 };
0485 
0486 /******************************************************************************/
0487 /*                    k X R _ p g r e a d   R e q u e s t                     */
0488 /******************************************************************************/
0489   
0490 // The page size for pgread and pgwrite and the maximum transmission size
0491 //
0492 namespace XrdProto  // Always use this namespace for new additions
0493 {
0494 static const int kXR_pgPageSZ = 4096;     // Length of a page
0495 static const int kXR_pgPageBL = 12;       // log2(page length)
0496 static const int kXR_pgUnitSZ = kXR_pgPageSZ + sizeof(kXR_unt32);
0497 static const int kXR_pgMaxEpr = 128;      // Max checksum errs per request
0498 static const int kXR_pgMaxEos = 256;      // Max checksum errs outstanding
0499 
0500 // kXR_pgread/write options
0501 //
0502 static const kXR_char kXR_AnyPath = 0xff; // In pathid
0503 static const int      kXR_pgRetry = 0x01; // In reqflags
0504 }
0505   
0506 struct ClientPgReadRequest {
0507    kXR_char  streamid[2];
0508    kXR_unt16 requestid;
0509    kXR_char  fhandle[4];
0510    kXR_int64 offset;
0511    kXR_int32 rlen;
0512    kXR_int32 dlen;     // Request data length must be 0 unless args present
0513 };
0514 
0515 struct ClientPgReadReqArgs {
0516    kXR_char  pathid;   // Request data length must be 1
0517    kXR_char  reqflags; // Request data length must be 2
0518 };
0519 
0520 namespace
0521 {
0522 }
0523 
0524 /******************************************************************************/
0525 /*                   k X R _ p r w r i t e   R e q u e s t                    */
0526 /******************************************************************************/
0527   
0528 struct ClientPgWriteRequest {
0529    kXR_char  streamid[2];
0530    kXR_unt16 requestid;
0531    kXR_char  fhandle[4];
0532    kXR_int64 offset;
0533    kXR_char  pathid;
0534    kXR_char  reqflags;
0535    kXR_char  reserved[2];
0536    kXR_int32 dlen;
0537 // kXR_char  data[dlen];
0538 };
0539 
0540 /******************************************************************************/
0541 /*                      k X R _ p i n g   R e q u e s t                       */
0542 /******************************************************************************/
0543   
0544 struct ClientPingRequest {
0545    kXR_char  streamid[2];
0546    kXR_unt16 requestid;
0547    kXR_char  reserved[16];
0548    kXR_int32 dlen;
0549 };
0550 
0551 /******************************************************************************/
0552 /*                  k X R _ p r o t o c o l   R e q u e s t                   */
0553 /******************************************************************************/
0554   
0555 struct ClientProtocolRequest {
0556    kXR_char  streamid[2];
0557    kXR_unt16 requestid;
0558    kXR_int32 clientpv;      // 2.9.7 or higher
0559    kXR_char  flags;         // 3.1.0 or higher
0560    kXR_char  expect;        // 4.0.0 or higher
0561    kXR_char  reserved[10];
0562    kXR_int32 dlen;
0563 
0564 enum RequestFlags {
0565    kXR_secreqs  = 0x01,  // Options: Return security requirements
0566    kXR_ableTLS  = 0x02,  // Options: Client is TLS capable
0567    kXR_wantTLS  = 0x04,  // Options: Change connection to use TLS
0568    kXR_bifreqs  = 0x08   // Options: Return bind interface requirements
0569 };
0570 
0571 enum ExpectFlags {
0572    kXR_ExpMask   = 0x0f, // Isolate the relevant expect enumeration value
0573    kXR_ExpNone   = 0x00,
0574    kXR_ExpBind   = 0x01,
0575    kXR_ExpGPF    = 0x02,
0576    kXR_ExpLogin  = 0x03,
0577    kXR_ExpTPC    = 0x04,
0578    kXR_ExpGPFA   = 0x08
0579 };
0580 };
0581 
0582 /******************************************************************************/
0583 /*                   k X R _ p r e p a r e   R e q u e s t                    */
0584 /******************************************************************************/
0585 
0586 enum XPrepRequestOption {
0587    kXR_cancel = 1,
0588    kXR_notify = 2,
0589    kXR_noerrs = 4,
0590    kXR_stage  = 8,
0591    kXR_wmode  = 16,
0592    kXR_coloc  = 32,
0593    kXR_fresh  = 64,
0594    kXR_usetcp = 128,
0595 
0596    kXR_evict  = 0x0001 // optionsX: file no longer useful
0597 };
0598   
0599 struct ClientPrepareRequest {
0600    kXR_char  streamid[2];
0601    kXR_unt16 requestid;
0602    kXR_char  options;
0603    kXR_char  prty;
0604    kXR_unt16 port;          // 2.9.9 or higher
0605    kXR_unt16 optionX;       // Extended options
0606    kXR_char  reserved[10];
0607    kXR_int32 dlen;
0608 };
0609 
0610 /******************************************************************************/
0611 /*                     k X R _ q u e r y   R e q u e s t                      */
0612 /******************************************************************************/
0613 
0614 enum XQueryType {
0615    kXR_QStats = 1,
0616    kXR_QPrep  = 2,
0617    kXR_Qcksum = 3,
0618    kXR_Qxattr = 4,
0619    kXR_Qspace = 5,
0620    kXR_Qckscan= 6,
0621    kXR_Qconfig= 7,
0622    kXR_Qvisa  = 8,
0623    kXR_Qopaque=16,
0624    kXR_Qopaquf=32,
0625    kXR_Qopaqug=64
0626 };
0627   
0628 struct ClientQueryRequest {
0629    kXR_char  streamid[2];
0630    kXR_unt16 requestid;
0631    kXR_unt16 infotype;    // See XQueryType enum
0632    kXR_char  reserved1[2];
0633    kXR_char  fhandle[4];
0634    kXR_char  reserved2[8];
0635    kXR_int32 dlen;
0636 };
0637 
0638 /******************************************************************************/
0639 /*                      k X R _ r e a d   R e q u e s t                       */
0640 /******************************************************************************/
0641   
0642 struct ClientReadRequest {
0643    kXR_char  streamid[2];
0644    kXR_unt16 requestid;
0645    kXR_char  fhandle[4];
0646    kXR_int64 offset;
0647    kXR_int32 rlen;
0648    kXR_int32 dlen;
0649 // Optionally followed by read_args
0650 };
0651 
0652 struct read_args {
0653    kXR_char  pathid;
0654    kXR_char  reserved[7];
0655 // This struct may be followed by an array of readahead_list
0656 };
0657 
0658 struct readahead_list {
0659    kXR_char  fhandle[4];
0660    kXR_int32 rlen;
0661    kXR_int64 offset;
0662 };
0663 
0664 /******************************************************************************/
0665 /*                     k X R _ r e a d v   R e q u e s t                      */
0666 /******************************************************************************/
0667   
0668 struct ClientReadVRequest {
0669    kXR_char  streamid[2];
0670    kXR_unt16 requestid;
0671    kXR_char  reserved[15];
0672    kXR_char  pathid;
0673    kXR_int32 dlen;
0674 // This struct followed by the read_list
0675 };
0676 
0677 namespace XrdProto  // Always use this namespace for new additions
0678 {
0679 struct read_list {
0680    kXR_char  fhandle[4];
0681    kXR_int32 rlen;
0682    kXR_int64 offset;
0683 };
0684 static const int rlItemLen = sizeof(read_list);
0685 static const int maxRvecln = 16384;               // Max read vector length
0686 static const int maxRvecsz = maxRvecln/rlItemLen; // Max number of elements
0687 static const int minRVbsz  = 2097152;             // 2MB minimum buffer size
0688 static const int maxRVdsz  = minRVbsz-rlItemLen;  // Max amount of data to xfer
0689 }
0690 
0691 /******************************************************************************/
0692 /*                        k X R _ r m   R e q u e s t                         */
0693 /******************************************************************************/
0694   
0695 struct ClientRmRequest {
0696    kXR_char  streamid[2];
0697    kXR_unt16 requestid;
0698    kXR_char  reserved[16];
0699    kXR_int32 dlen;
0700 };
0701 
0702 /******************************************************************************/
0703 /*                     k X R _ r m d i r   R e q u e s t                      */
0704 /******************************************************************************/
0705   
0706 struct ClientRmdirRequest {
0707    kXR_char  streamid[2];
0708    kXR_unt16 requestid;
0709    kXR_char  reserved[16];
0710    kXR_int32 dlen;
0711 };
0712 
0713 /******************************************************************************/
0714 /*                       k X R _ s e t   R e q u e s t                        */
0715 /******************************************************************************/
0716   
0717 struct ClientSetRequest {
0718    kXR_char  streamid[2];
0719    kXR_unt16 requestid;
0720    kXR_char reserved[15];
0721    kXR_char  modifier;  // For security purposes, should be zero
0722    kXR_int32  dlen;
0723 };
0724 
0725 /******************************************************************************/
0726 /*                    k X R _ s i g v e r   R e q u e s t                     */
0727 /******************************************************************************/
0728 
0729 // Cryptography used for kXR_sigver SigverRequest::crypto
0730 enum XSecCrypto {
0731    kXR_SHA256   = 0x01,   // Hash used
0732    kXR_HashMask = 0x0f,   // Mak to extract the hash type
0733    kXR_rsaKey   = 0x80    // The rsa key was used
0734 };
0735 
0736 // Flags for kXR_sigver
0737 enum XSecFlags {
0738    kXR_nodata   = 1  // Request payload was not hashed
0739 };
0740 
0741 // Version number
0742 enum XSecVersion {
0743    kXR_Ver_00 = 0
0744 };
0745 
0746 struct ClientSigverRequest {
0747    kXR_char  streamid[2];
0748    kXR_unt16 requestid;
0749    kXR_unt16 expectrid; // Request code of subsequent request
0750    kXR_char  version;   // Security version being used (see XSecVersion)
0751    kXR_char  flags;     // One or more flags defined in enum (see XSecFlags)
0752    kXR_unt64 seqno;     // Monotonically increasing number (part of hash)
0753    kXR_char  crypto;    // Cryptography used (see XSecCrypto)
0754    kXR_char  rsvd2[3];
0755    kXR_int32 dlen;
0756 };
0757 
0758 /******************************************************************************/
0759 /*                      k X R _ s t a t   R e q u e s t                       */
0760 /******************************************************************************/
0761 
0762 enum XStatRequestOption {
0763    kXR_vfs    = 1
0764 };
0765   
0766 struct ClientStatRequest {
0767    kXR_char  streamid[2];
0768    kXR_unt16 requestid;
0769    kXR_char  options;    // See XStatRequestOption
0770    kXR_char  reserved[11];
0771    kXR_char  fhandle[4];
0772    kXR_int32 dlen;
0773 };
0774 
0775 /******************************************************************************/
0776 /*                      k X R _ s y n c   R e q u e s t                       */
0777 /******************************************************************************/
0778   
0779 struct ClientSyncRequest {
0780    kXR_char  streamid[2];
0781    kXR_unt16 requestid;
0782    kXR_char  fhandle[4];
0783    kXR_char  reserved[12];
0784    kXR_int32 dlen;
0785 };
0786 
0787 /******************************************************************************/
0788 /*                  k X R _ t r u n c a t e   R e q u e s t                   */
0789 /******************************************************************************/
0790   
0791 struct ClientTruncateRequest {
0792    kXR_char  streamid[2];
0793    kXR_unt16 requestid;
0794    kXR_char  fhandle[4];
0795    kXR_int64 offset;
0796    kXR_char  reserved[4];
0797    kXR_int32 dlen;
0798 };
0799 
0800 /******************************************************************************/
0801 /*                     k X R _ w r i t e   R e q u e s t                      */
0802 /******************************************************************************/
0803   
0804 struct ClientWriteRequest {
0805    kXR_char  streamid[2];
0806    kXR_unt16 requestid;
0807    kXR_char  fhandle[4];
0808    kXR_int64 offset;
0809    kXR_char  pathid;
0810    kXR_char  reserved[3];
0811    kXR_int32 dlen;
0812 };
0813 
0814 /******************************************************************************/
0815 /*                    k X R _ w r i t e v   R e q u e s t                     */
0816 /******************************************************************************/
0817   
0818 struct ClientWriteVRequest {
0819    kXR_char  streamid[2];
0820    kXR_unt16 requestid;
0821    kXR_char  options;  // See static const ints below
0822    kXR_char  reserved[15];
0823    kXR_int32 dlen;
0824 // This struct followed by the write_list
0825 
0826    static const kXR_int32 doSync = 0x01;
0827 };
0828 
0829 namespace XrdProto  // Always use this namespace for new additions
0830 {
0831 struct write_list {
0832    kXR_char fhandle[4];
0833    kXR_int32 wlen;
0834    kXR_int64 offset;
0835 };
0836 static const int wlItemLen = sizeof(write_list);
0837 static const int maxWvecln = 16384;
0838 static const int maxWvecsz = maxWvecln/wlItemLen;
0839 }
0840 
0841 /******************************************************************************/
0842 /*          U n i o n   o f   a l l   C l i e n t   R e q u e s t s           */
0843 /******************************************************************************/
0844   
0845 typedef union {
0846    struct ClientRequestHdr header;
0847    struct ClientAuthRequest auth;
0848    struct ClientBindRequest bind;
0849    struct ClientChkPointRequest chkpoint;
0850    struct ClientChmodRequest chmod;
0851    struct ClientCloseRequest close;
0852    struct ClientDirlistRequest dirlist;
0853    struct ClientEndsessRequest endsess;
0854    struct ClientFattrRequest fattr;
0855    struct ClientGPfileRequest gpfile;
0856    struct ClientLocateRequest locate;
0857    struct ClientLoginRequest login;
0858    struct ClientMkdirRequest mkdir;
0859    struct ClientMvRequest mv;
0860    struct ClientOpenRequest open;
0861    struct ClientPgReadRequest pgread;
0862    struct ClientPgWriteRequest pgwrite;
0863    struct ClientPingRequest ping;
0864    struct ClientPrepareRequest prepare;
0865    struct ClientProtocolRequest protocol;
0866    struct ClientQueryRequest query;
0867    struct ClientReadRequest read;
0868    struct ClientReadVRequest readv;
0869    struct ClientRmRequest rm;
0870    struct ClientRmdirRequest rmdir;
0871    struct ClientSetRequest set;
0872    struct ClientSigverRequest sigver;
0873    struct ClientStatRequest stat;
0874    struct ClientSyncRequest sync;
0875    struct ClientTruncateRequest truncate;
0876    struct ClientWriteRequest write;
0877    struct ClientWriteVRequest writev;
0878 } ClientRequest;
0879 
0880 typedef union {
0881    struct ClientRequestHdr header;
0882    struct ClientSigverRequest sigver;
0883 } SecurityRequest;
0884 
0885 /******************************************************************************/
0886 /*                      S e r v e r   R e s p o n s e s                       */
0887 /******************************************************************************/
0888 
0889 // Nice header for the server response.
0890 // Note that the protocol specifies these values to be in network
0891 // byte order when sent
0892 //
0893 // G.Ganis: The following structures never need padding bytes:
0894 //          no need of packing options
0895 
0896 // Server response codes
0897 //
0898 enum XResponseType {
0899    kXR_ok      =   0,
0900    kXR_oksofar =   4000,
0901    kXR_attn,    // 4001
0902    kXR_authmore,// 4002
0903    kXR_error,   // 4003
0904    kXR_redirect,// 4004
0905    kXR_wait,    // 4005
0906    kXR_waitresp,// 4006
0907    kXR_status,  // 4007
0908    kXR_noResponsesYet = 10000
0909 };
0910 
0911 // All serer responses start with the same header
0912 //
0913 struct ServerResponseHeader {
0914    kXR_char  streamid[2];
0915    kXR_unt16 status;
0916    kXR_int32 dlen;
0917 };
0918 
0919 // This is a bit of wierdness held over from the very old days, sigh.
0920 //
0921 struct ServerResponseBody_Buffer {
0922    char data[4096];
0923 };
0924 
0925 /******************************************************************************/
0926 /*                     k X R _ a t t n   R e s p o n s e                      */
0927 /******************************************************************************/
0928 
0929 enum XActionCode {
0930    kXR_asyncab =     5000, // No longer supported
0931    kXR_asyncdi,   // 5001     No longer supported
0932    kXR_asyncms =     5002,
0933    kXR_asyncrd,   // 5003     No longer supported
0934    kXR_asyncwt,   // 5004     No longer supported
0935    kXR_asyncav,   // 5005     No longer supported
0936    kXR_asynunav,  // 5006     No longer supported
0937    kXR_asyncgo,   // 5007     No longer supported
0938    kXR_asynresp=     5008
0939 };
0940   
0941 struct ServerResponseBody_Attn {
0942    kXR_int32 actnum;      // See XActionCode enum
0943    char      parms[4096]; // Should be sufficient for every use
0944 };
0945 
0946 struct ServerResponseBody_Attn_asyncms  {
0947    kXR_int32            actnum;       // XActionCode::kXR_asyncms
0948    char                 reserved[4];
0949    ServerResponseHeader resphdr;
0950    char                 respdata[4096];
0951 };
0952 
0953 struct ServerResponseBody_Attn_asynresp {
0954    kXR_int32            actnum;       // XActionCode::kXR_asynresp
0955    char                 reserved[4];
0956    ServerResponseHeader resphdr;
0957    char                 respdata[4096];
0958 };
0959 
0960 /******************************************************************************/
0961 /*                 k X R _ a u t h m o r e   R e s p o n s e                  */
0962 /******************************************************************************/
0963   
0964 struct ServerResponseBody_Authmore {
0965    char data[4096];
0966 };
0967 
0968 /******************************************************************************/
0969 /*                     k X R _ b i n d   R e s p o n s e                      */
0970 /******************************************************************************/
0971   
0972 struct ServerResponseBody_Bind {
0973     kXR_char substreamid;
0974 };
0975 
0976 /******************************************************************************/
0977 /*                 k X R _ c h k p o i n t   R e s p o n s e                  */
0978 /******************************************************************************/
0979   
0980 struct ServerResponseBody_ChkPoint { // Only for kXR_ckpQMax
0981     kXR_unt32 maxCkpSize;  // Maximum number of bytes including overhead
0982     kXR_unt32 useCkpSize;  // The number of bytes already being used
0983 };
0984   
0985 /******************************************************************************/
0986 /*                    k X R _ e r r o r   R e s p o n s e                     */
0987 /******************************************************************************/
0988 
0989 enum XErrorCode {
0990    kXR_ArgInvalid =        3000,
0991    kXR_ArgMissing,      // 3001
0992    kXR_ArgTooLong,      // 3002
0993    kXR_FileLocked,      // 3003
0994    kXR_FileNotOpen,     // 3004
0995    kXR_FSError,         // 3005
0996    kXR_InvalidRequest,  // 3006
0997    kXR_IOError,         // 3007
0998    kXR_NoMemory,        // 3008
0999    kXR_NoSpace,         // 3009
1000    kXR_NotAuthorized,   // 3010
1001    kXR_NotFound,        // 3011
1002    kXR_ServerError,     // 3012
1003    kXR_Unsupported,     // 3013
1004    kXR_noserver,        // 3014
1005    kXR_NotFile,         // 3015
1006    kXR_isDirectory,     // 3016
1007    kXR_Cancelled,       // 3017
1008    kXR_ItExists,        // 3018
1009    kXR_ChkSumErr,       // 3019
1010    kXR_inProgress,      // 3020
1011    kXR_overQuota,       // 3021
1012    kXR_SigVerErr,       // 3022
1013    kXR_DecryptErr,      // 3023
1014    kXR_Overloaded,      // 3024
1015    kXR_fsReadOnly,      // 3025
1016    kXR_BadPayload,      // 3026
1017    kXR_AttrNotFound,    // 3027
1018    kXR_TLSRequired,     // 3028
1019    kXR_noReplicas,      // 3029
1020    kXR_AuthFailed,      // 3030
1021    kXR_Impossible,      // 3031
1022    kXR_Conflict,        // 3032
1023    kXR_TooManyErrs,     // 3033
1024    kXR_ReqTimedOut,     // 3034
1025    kXR_TimerExpired,    // 3035
1026    kXR_ERRFENCE,        // Always last valid errcode + 1
1027    kXR_noErrorYet = 10000
1028 };
1029   
1030 struct ServerResponseBody_Error {
1031    kXR_int32 errnum;       // See XErrorCode enu
1032    char      errmsg[4096]; // Should be sufficient for every use
1033 };
1034 
1035 /******************************************************************************/
1036 /*                    k X R _ l o g i n   R e s p o n s e                     */
1037 /******************************************************************************/
1038   
1039 struct ServerResponseBody_Login {
1040    kXR_char  sessid[16];
1041    kXR_char  sec[4096]; // Should be sufficient for every use
1042 };
1043 
1044 /******************************************************************************/
1045 /*                     k X R _ o p e n   R e s p o n s e                      */
1046 /******************************************************************************/
1047 
1048 struct ServerResponseBody_Open {
1049    kXR_char  fhandle[4];
1050    kXR_int32 cpsize;    // cpsize & cptype returned if kXR_compress *or*
1051    kXR_char  cptype[4]; // kXR_retstat is specified
1052 }; // info will follow if kXR_retstat is specified
1053   
1054 /******************************************************************************/
1055 /*                   k X R _ p g r e a d   R e s p o n s e                    */
1056 /******************************************************************************/
1057 
1058 struct ServerResponseBody_pgRead {
1059    kXR_int64 offset;    // info[]: File offset of data that follows
1060 // kXR_char  data[dlen];
1061 };
1062 
1063 /******************************************************************************/
1064 /*                  k X R _ p g w r i t e   R e s p o n s e                   */
1065 /******************************************************************************/
1066   
1067 struct ServerResponseBody_pgWrite {
1068    kXR_int64 offset;                // info[]: File offset of data written
1069 };
1070 
1071 
1072 // The following structure is appended to ServerResponseBody_pgWrite if one or
1073 // more checksum errors occurred and need to be retransmitted.
1074 //
1075 struct ServerResponseBody_pgWrCSE {
1076    kXR_unt32 cseCRC;                // crc32c of all following bits
1077    kXR_int16 dlFirst;               // Data length at first offset in list
1078    kXR_int16 dlLast;                // Data length at last  offset in list
1079 // kXR_int64 bof[(dlen-8)/8];       // List of offsets of pages in error
1080 };
1081 
1082 /******************************************************************************/
1083 /*                 k X R _ p r o t o c o l   R e s p o n s e                  */
1084 /******************************************************************************/
1085 
1086 // The following information is returned in the response body when kXR_bifreqs
1087 // is set in ClientProtocolRequest::flags. Note that the size of bifInfo is
1088 // is variable. This response will not be returned if there are no bif's.
1089 // Note: This structure is null byte padded to be a multiple of 8 bytes!
1090 //
1091 struct ServerResponseBifs_Protocol {
1092    kXR_char  theTag;      // Always the character 'B' to identify struct
1093    kXR_char  rsvd;        // Reserved for the future (always 0 for now)
1094    kXR_unt16 bifILen;     // Length of bifInfo including null bytes.
1095 // kXR_char  bifInfo[bifILen];
1096 };
1097   
1098 // The following information is returned in the response body when kXR_secreqs
1099 // is set in ClientProtocolRequest::flags. Note that the size of secvec is
1100 // defined by secvsz and will not be present when secvsz == 0.
1101 //
1102 struct ServerResponseSVec_Protocol {
1103    kXR_char  reqindx;     // Request index
1104    kXR_char  reqsreq;     // Request signing requirement
1105 };
1106 
1107 struct ServerResponseReqs_Protocol {
1108    kXR_char  theTag;      // Always the character 'S' to identify struct
1109    kXR_char  rsvd;        // Reserved for the future (always 0 for now)
1110    kXR_char  secver;      // Security version
1111    kXR_char  secopt;      // Security options
1112    kXR_char  seclvl;      // Security level when secvsz == 0
1113    kXR_char  secvsz;      // Number of items in secvec (i.e. its length/2)
1114    ServerResponseSVec_Protocol secvec;
1115 };
1116 
1117 
1118 namespace XrdProto
1119 {
1120 typedef struct ServerResponseBifs_Protocol bifReqs;
1121 typedef struct ServerResponseReqs_Protocol secReqs;
1122 }
1123 
1124 // Options reflected in protocol response ServerResponseReqs_Protocol::secopt
1125 //
1126 #define kXR_secOData 0x01
1127 #define kXR_secOFrce 0x02
1128 
1129 // Security level definitions (these are predefined but can be over-ridden)
1130 //
1131 #define kXR_secNone       0
1132 #define kXR_secCompatible 1
1133 #define kXR_secStandard   2
1134 #define kXR_secIntense    3
1135 #define kXR_secPedantic   4
1136 
1137 // Requirements one of which set in each ServerResponseReqs_Protocol::secvec
1138 //
1139 #define kXR_signIgnore    0
1140 #define kXR_signLikely    1
1141 #define kXR_signNeeded    2
1142 
1143 // Version used for kXR_sigver and is set in SigverRequest::version,
1144 // ServerResponseReqs_Protocol::secver
1145 //
1146 #define kXR_secver_0  0
1147   
1148 // KINDS of SERVERS (no longer used by new clients)
1149 //
1150 #define kXR_DataServer 1
1151 #define kXR_LBalServer 0
1152 
1153 // The below are defined for protocol version 2.9.7 or higher
1154 // These are the flag values in the kXR_protool response
1155 //
1156 #define kXR_isManager     0x00000002
1157 #define kXR_isServer      0x00000001
1158 #define kXR_attrCache     0x00000080
1159 #define kXR_attrMeta      0x00000100
1160 #define kXR_attrProxy     0x00000200
1161 #define kXR_attrSuper     0x00000400
1162 #define kXR_attrVirtRdr   0x00000800
1163 
1164 // Virtual options set on redirect
1165 //
1166 #define kXR_recoverWrts   0x00001000
1167 #define kXR_collapseRedir 0x00002000
1168 #define kXR_ecRedir       0x00004000
1169 
1170 // Things the server supports
1171 //
1172 #define kXR_anongpf       0x00800000
1173 #define kXR_supgpf        0x00400000
1174 #define kXR_suppgrw       0x00200000
1175 #define kXR_supposc       0x00100000
1176 
1177 // TLS requirements
1178 //
1179 #define kXR_haveTLS       0x80000000
1180 #define kXR_gotoTLS       0x40000000
1181 #define kXR_tlsAny        0x1f000000
1182 #define kXR_tlsData       0x01000000
1183 #define kXR_tlsGPF        0x02000000
1184 #define kXR_tlsLogin      0x04000000
1185 #define kXR_tlsSess       0x08000000
1186 #define kXR_tlsTPC        0x10000000
1187 #define kXR_tlsGPFA       0x20000000
1188 
1189 // Body for the kXR_protocol response... useful
1190 //
1191 struct ServerResponseBody_Protocol {
1192    kXR_int32 pval;
1193    kXR_int32 flags;
1194    ServerResponseReqs_Protocol secreq; // Only for V3.1.0+ && if requested
1195 };
1196 
1197 // Handy definition of the size of the protocol response when the security
1198 // information is not present.
1199 //
1200 #define kXR_ShortProtRespLen sizeof(ServerResponseBody_Protocol)-\
1201                              sizeof(ServerResponseReqs_Protocol)
1202 
1203 /******************************************************************************/
1204 /*                 k X R _ r e d i r e c t   R e s p o n s e                  */
1205 /******************************************************************************/
1206   
1207 struct ServerResponseBody_Redirect {
1208    kXR_int32 port;
1209    char host[4096]; // Should be sufficient for every use
1210 };
1211 
1212 /******************************************************************************/
1213 /*                     k X R _ s t a t   R e s p o n s e                      */
1214 /******************************************************************************/
1215 
1216 // The following bits are encoded in the "flags" token in the response
1217 //
1218 enum XStatRespFlags {
1219    kXR_file    = 0,
1220    kXR_xset    = 1,
1221    kXR_isDir   = 2,
1222    kXR_other   = 4,
1223    kXR_offline = 8,
1224    kXR_readable=16,
1225    kXR_writable=32,
1226    kXR_poscpend=64,
1227    kXR_bkpexist=128
1228 };
1229   
1230 /******************************************************************************/
1231 /*                   k X R _ s t a t u s   R e s p o n s e                    */
1232 /******************************************************************************/
1233 
1234 struct ServerResponseBody_Status { // Always preceeded by ServerResponseHeader
1235    kXR_unt32 crc32c;      // IETF RFC 7143 standard
1236    kXR_char  streamID[2]; // Identical to streamid[2]  in ServerResponseHeader
1237    kXR_char  requestid;   // requestcode - kXR_1stRequest
1238    kXR_char  resptype;    // See RespType enum below
1239    kXR_char  reserved[4];
1240    kXR_int32 dlen;
1241 // kXR_char  info[ServerResponseHeader::dlen-sizeof(ServerResponseBody_Status)];
1242 // kXR_char  data[dlen];
1243 };
1244 
1245 namespace XrdProto
1246 {
1247 enum RespType {
1248 
1249    kXR_FinalResult   = 0x00,
1250    kXR_PartialResult = 0x01,
1251    kXR_ProgressInfo  = 0x02
1252 };
1253 
1254    // This is the minimum size of ServerResponseHeader::dlen for kXR_status
1255    //
1256    static const int kXR_statusBodyLen = sizeof(ServerResponseBody_Status);
1257 }
1258 
1259 struct ServerResponseStatus {
1260    struct ServerResponseHeader      hdr;
1261    struct ServerResponseBody_Status bdy;
1262 };
1263   
1264 /******************************************************************************/
1265 /*                     k X R _ w a i t   R e s p o n s e                      */
1266 /******************************************************************************/
1267   
1268 struct ServerResponseBody_Wait {
1269    kXR_int32 seconds;
1270    char infomsg[4096]; // Should be sufficient for every use
1271 };
1272 
1273 /******************************************************************************/
1274 /*                 k X R _ w a i t r e s p   R e s p o n s e                  */
1275 /******************************************************************************/
1276   
1277 struct ServerResponseBody_Waitresp {
1278    kXR_int32 seconds;
1279 };
1280 
1281 /******************************************************************************/
1282 /*         U n i o n   o f   a l l   S e r v e r   R e s p o n s e s          */
1283 /******************************************************************************/
1284   
1285 struct ServerResponse
1286 {
1287   ServerResponseHeader hdr;
1288   union
1289   {
1290     ServerResponseBody_Attn     attn;
1291     ServerResponseBody_Authmore authmore;
1292     ServerResponseBody_Bind     bind;
1293     ServerResponseBody_Buffer   buffer;
1294     ServerResponseBody_Error    error;
1295     ServerResponseBody_Login    login;
1296     ServerResponseBody_Protocol protocol;
1297     ServerResponseBody_Redirect redirect;
1298     ServerResponseBody_Status   status;
1299     ServerResponseBody_Wait     wait;
1300     ServerResponseBody_Waitresp waitresp;
1301   } body;
1302 };
1303 
1304 // The pgread and pgwrite do not fit the union above because they are composed
1305 // of three structs not two as all the above. So, we define the exceptions here.
1306 //
1307 struct ServerResponseV2
1308 {
1309   ServerResponseStatus status; // status.bdy and status.hdr
1310   union
1311   {
1312     ServerResponseBody_pgRead   pgread;
1313     ServerResponseBody_pgWrite  pgwrite;
1314   } info;
1315 };
1316 
1317 struct ALIGN_CHECK {char chkszreq[25-sizeof(ClientRequest)];
1318    char chkszrsp[ 9-sizeof(ServerResponseHeader)];
1319 };
1320 
1321 /******************************************************************************/
1322 /*                   X P r o t o c o l   U t i l i t i e s                    */
1323 /******************************************************************************/
1324 
1325 #include <cerrno>
1326 #if defined(WIN32)
1327 #if !defined(ENOTBLK)
1328 #  define ENOTBLK 15
1329 #endif
1330 #if !defined(ETXTBSY)
1331 #define ETXTBSY 26
1332 #endif
1333 #if !defined(ENOBUFS)
1334 #define ENOBUFS 105
1335 #endif
1336 #if !defined(ENETUNREACH)
1337 #define ENETUNREACH 114
1338 #endif
1339 #endif
1340 
1341 #ifndef ENOATTR
1342 #define ENOATTR ENODATA
1343 #endif
1344 
1345 #ifndef EBADRQC
1346 #define EBADRQC EBADRPC
1347 #endif
1348 
1349 #ifndef EAUTH
1350 #define EAUTH EBADE
1351 #endif
1352 
1353 struct stat;
1354   
1355 class XProtocol
1356 {
1357 public:
1358 
1359 // mapError() is the official mapping from errno to xroot protocol error.
1360 //
1361 static int mapError(int rc)
1362       {if (rc < 0) rc = -rc;
1363        switch(rc)
1364           {case ENOENT:        return kXR_NotFound;
1365            case EINVAL:        return kXR_ArgInvalid;
1366            case EPERM:         return kXR_NotAuthorized;
1367            case EACCES:        return kXR_NotAuthorized;
1368            case EIO:           return kXR_IOError;
1369            case ENOMEM:        return kXR_NoMemory;
1370            case ENOBUFS:       return kXR_NoMemory;
1371            case ENOSPC:        return kXR_NoSpace;
1372            case ENAMETOOLONG:  return kXR_ArgTooLong;
1373            case ENETUNREACH:   return kXR_noserver;
1374            case ENOTBLK:       return kXR_NotFile;
1375            case ENOTSUP:       return kXR_Unsupported;
1376            case EISDIR:        return kXR_isDirectory;
1377            case ENOTEMPTY: [[fallthrough]];
1378            // In the case one tries to delete a non-empty directory
1379            // we have decided that until the next major release
1380            // the kXR_ItExists flag will be returned
1381            case EEXIST:
1382                 return kXR_ItExists;
1383            case EBADRQC:       return kXR_InvalidRequest;
1384            case ETXTBSY:       return kXR_inProgress;
1385            case ENODEV:        return kXR_FSError;
1386            case EFAULT:        return kXR_ServerError;
1387            case EDOM:          return kXR_ChkSumErr;
1388            case EDQUOT:        return kXR_overQuota;
1389            case EILSEQ:        return kXR_SigVerErr;
1390            case ERANGE:        return kXR_DecryptErr;
1391            case EUSERS:        return kXR_Overloaded;
1392            case EROFS:         return kXR_fsReadOnly;
1393            case ENOATTR:       return kXR_AttrNotFound;
1394            case EPROTOTYPE:    return kXR_TLSRequired;
1395            case EADDRNOTAVAIL: return kXR_noReplicas;
1396            case EAUTH:         return kXR_AuthFailed;
1397            case EIDRM:         return kXR_Impossible;
1398            case ENOTTY:        return kXR_Conflict;
1399            case ETOOMANYREFS:  return kXR_TooManyErrs;
1400            case ETIMEDOUT:     return kXR_ReqTimedOut;
1401            case EBADF:         return kXR_FileNotOpen;
1402            case ECANCELED:     return kXR_Cancelled;
1403            case ETIME:         return kXR_TimerExpired;
1404            default:            return kXR_FSError;
1405           }
1406       }
1407   
1408 static int toErrno( int xerr )
1409 {
1410     switch(xerr)
1411        {case kXR_ArgInvalid:    return EINVAL;
1412         case kXR_ArgMissing:    return EINVAL;
1413         case kXR_ArgTooLong:    return ENAMETOOLONG;
1414         case kXR_FileLocked:    return EDEADLK;
1415         case kXR_FileNotOpen:   return EBADF;
1416         case kXR_FSError:       return ENODEV;
1417         case kXR_InvalidRequest:return EBADRQC;
1418         case kXR_IOError:       return EIO;
1419         case kXR_NoMemory:      return ENOMEM;
1420         case kXR_NoSpace:       return ENOSPC;
1421         case kXR_NotAuthorized: return EACCES;
1422         case kXR_NotFound:      return ENOENT;
1423         case kXR_ServerError:   return EFAULT;
1424         case kXR_Unsupported:   return ENOTSUP;
1425         case kXR_noserver:      return EHOSTUNREACH;
1426         case kXR_NotFile:       return ENOTBLK;
1427         case kXR_isDirectory:   return EISDIR;
1428         case kXR_Cancelled:     return ECANCELED;
1429         case kXR_ItExists:      return EEXIST;
1430         case kXR_ChkSumErr:     return EDOM;
1431         case kXR_inProgress:    return EINPROGRESS;
1432         case kXR_overQuota:     return EDQUOT;
1433         case kXR_SigVerErr:     return EILSEQ;
1434         case kXR_DecryptErr:    return ERANGE;
1435         case kXR_Overloaded:    return EUSERS;
1436         case kXR_fsReadOnly:    return EROFS;
1437         case kXR_BadPayload:    return EINVAL;
1438         case kXR_AttrNotFound:  return ENOATTR;
1439         case kXR_TLSRequired:   return EPROTOTYPE;
1440         case kXR_noReplicas:    return EADDRNOTAVAIL;
1441         case kXR_AuthFailed:    return EAUTH;
1442         case kXR_Impossible:    return EIDRM;
1443         case kXR_Conflict:      return ENOTTY;
1444         case kXR_TooManyErrs:   return ETOOMANYREFS;
1445         case kXR_ReqTimedOut:   return ETIMEDOUT;
1446         case kXR_TimerExpired:  return ETIME;  // Used for 504 Gateway timeout in proxy
1447         default:                return ENOMSG;
1448        }
1449 }
1450 
1451 static const char *errName(kXR_int32 errCode);
1452 
1453 static const char *reqName(kXR_unt16 reqCode);
1454 
1455 /******************************************************************************/
1456 /*                  O b s o l e t e   D e f i n i t i o n s                   */
1457 /******************************************************************************/
1458 
1459 struct ServerResponseBody_Attn_asyncdi { // No longer supported
1460    kXR_int32 actnum;
1461    kXR_int32 wsec;
1462    kXR_int32 msec;
1463 };
1464 
1465 struct ServerResponseBody_Attn_asyncrd { // No longer supported
1466    kXR_int32 actnum;
1467    kXR_int32 port;
1468    char host[4092];
1469 };
1470 
1471 struct ServerResponseBody_Attn_asyncwt { // No longer supported
1472    kXR_int32 actnum;
1473    kXR_int32 wsec;
1474 };
1475 
1476 // Kind of error inside a XTNetFile's routine (temporary)
1477 //
1478 enum XReqErrorType {
1479    kGENERICERR = 0,    // Generic error
1480    kREAD,              // Error while reading from stream
1481    kWRITE,             // Error while writing to stream
1482    kREDIRCONNECT,      // Error redirecting to a given host
1483    kOK,                // Everything seems ok
1484    kNOMORESTREAMS      // No more available stream IDs for
1485                        // async processing
1486 };
1487 
1488 typedef kXR_int32 ServerResponseType;
1489 
1490 #define kXR_maxReqRetry 10
1491 
1492 }; // XProtocol
1493 #endif