-
Notifications
You must be signed in to change notification settings - Fork 149
/
XrdClXRootDTransport.hh
363 lines (309 loc) · 18.3 KB
/
XrdClXRootDTransport.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
//------------------------------------------------------------------------------
// Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN)
// Author: Lukasz Janyst <ljanyst@cern.ch>
//------------------------------------------------------------------------------
// This file is part of the XRootD software suite.
//
// XRootD is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// XRootD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//
// In applying this licence, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
//------------------------------------------------------------------------------
#ifndef __XRD_CL_XROOTD_TRANSPORT_HH__
#define __XRD_CL_XROOTD_TRANSPORT_HH__
#include "XrdCl/XrdClPostMaster.hh"
#include "XProtocol/XProtocol.hh"
#include "XrdSec/XrdSecInterface.hh"
#include "XrdOuc/XrdOucEnv.hh"
class XrdSysPlugin;
class XrdSecProtect;
namespace XrdCl
{
class Tls;
class Socket;
struct XRootDChannelInfo;
struct PluginUnloadHandler;
//----------------------------------------------------------------------------
//! XRootD related protocol queries
//----------------------------------------------------------------------------
struct XRootDQuery
{
static const uint16_t SIDManager = 1001; //!< returns the SIDManager object
static const uint16_t ServerFlags = 1002; //!< returns server flags
static const uint16_t ProtocolVersion = 1003; //!< returns the protocol version
};
//----------------------------------------------------------------------------
//! XRootD transport handler
//----------------------------------------------------------------------------
class XRootDTransport: public TransportHandler
{
public:
//------------------------------------------------------------------------
//! Constructor
//------------------------------------------------------------------------
XRootDTransport();
//------------------------------------------------------------------------
//! Destructor
//------------------------------------------------------------------------
~XRootDTransport();
//------------------------------------------------------------------------
//! Read a message header from the socket, the socket is non-blocking,
//! so if there is not enough data the function should return suRetry
//! in which case it will be called again when more data arrives, with
//! the data previously read stored in the message buffer
//!
//! @param message the message buffer
//! @param socket the socket
//! @return stOK & suDone if the whole message has been processed
//! stOK & suRetry if more data is needed
//! stError on failure
//------------------------------------------------------------------------
virtual Status GetHeader( Message *message, Socket *socket );
//------------------------------------------------------------------------
//! Read the message body from the socket, the socket is non-blocking,
//! the method may be called multiple times - see GetHeader for details
//!
//! @param message the message buffer containing the header
//! @param socket the socket
//! @return stOK & suDone if the whole message has been processed
//! stOK & suRetry if more data is needed
//! stError on failure
//------------------------------------------------------------------------
virtual Status GetBody( Message *message, Socket *socket );
//------------------------------------------------------------------------
//! Initialize channel
//------------------------------------------------------------------------
virtual void InitializeChannel( AnyObject &channelData,
bool encrypted );
//------------------------------------------------------------------------
//! Finalize channel
//------------------------------------------------------------------------
virtual void FinalizeChannel( AnyObject &channelData );
//------------------------------------------------------------------------
//! HandShake
//------------------------------------------------------------------------
virtual Status HandShake( HandShakeData *handShakeData,
AnyObject &channelData );
//------------------------------------------------------------------------
// @return true if handshake has been done and stream is connected,
// false otherwise
//------------------------------------------------------------------------
virtual bool HandShakeDone( HandShakeData *handShakeData,
AnyObject &channelData );
//------------------------------------------------------------------------
//! Check if the stream should be disconnected
//------------------------------------------------------------------------
virtual bool IsStreamTTLElapsed( time_t time,
AnyObject &channelData );
//------------------------------------------------------------------------
//! Check the stream is broken - ie. TCP connection got broken and
//! went undetected by the TCP stack
//------------------------------------------------------------------------
virtual Status IsStreamBroken( time_t inactiveTime,
AnyObject &channelData );
//------------------------------------------------------------------------
//! Return the ID for the up stream this message should be sent by
//! and the down stream which the answer should be expected at.
//! Modify the message itself if necessary.
//! If hint is non-zero then the message should be modified such that
//! the answer will be returned via the hinted stream.
//------------------------------------------------------------------------
virtual PathID Multiplex( Message *msg,
AnyObject &channelData,
PathID *hint = 0 );
//------------------------------------------------------------------------
//! Return the ID for the up substream this message should be sent by
//! and the down substream which the answer should be expected at.
//! Modify the message itself if necessary.
//! If hint is non-zero then the message should be modified such that
//! the answer will be returned via the hinted stream.
//------------------------------------------------------------------------
virtual PathID MultiplexSubStream( Message *msg,
AnyObject &channelData,
PathID *hint = 0 );
//------------------------------------------------------------------------
//! Return a number of substreams per stream that should be created
//------------------------------------------------------------------------
virtual uint16_t SubStreamNumber( AnyObject &channelData );
//------------------------------------------------------------------------
//! Return the information whether a control connection needs to be
//! valid before establishing other connections
//------------------------------------------------------------------------
virtual bool NeedControlConnection()
{
return true;
}
//------------------------------------------------------------------------
//! Marshal the outgoing message
//------------------------------------------------------------------------
static Status MarshallRequest( Message *msg );
//------------------------------------------------------------------------
//! Unmarshall the request - sometimes the requests need to be rewritten,
//! so we need to unmarshall them
//------------------------------------------------------------------------
static Status UnMarshallRequest( Message *msg );
//------------------------------------------------------------------------
//! Unmarshall the body of the incoming message
//------------------------------------------------------------------------
static Status UnMarshallBody( Message *msg, uint16_t reqType );
//------------------------------------------------------------------------
//! Unmarshall the header incoming message
//------------------------------------------------------------------------
static void UnMarshallHeader( Message *msg );
//------------------------------------------------------------------------
//! Log server error response
//------------------------------------------------------------------------
static void LogErrorResponse( const Message &msg );
//------------------------------------------------------------------------
//! Number of currently connected data streams
//------------------------------------------------------------------------
static uint16_t NbConnectedStrm( AnyObject &channelData );
//------------------------------------------------------------------------
//! The stream has been disconnected, do the cleanups
//------------------------------------------------------------------------
virtual void Disconnect( AnyObject &channelData,
uint16_t subStreamId );
//------------------------------------------------------------------------
//! Query the channel
//------------------------------------------------------------------------
virtual Status Query( uint16_t query,
AnyObject &result,
AnyObject &channelData );
//------------------------------------------------------------------------
//! Get the description of a message
//------------------------------------------------------------------------
static void SetDescription( Message *msg );
//------------------------------------------------------------------------
//! Check if the message invokes a stream action
//------------------------------------------------------------------------
virtual uint32_t MessageReceived( Message *msg,
uint16_t subStream,
AnyObject &channelData );
//------------------------------------------------------------------------
//! Notify the transport about a message having been sent
//------------------------------------------------------------------------
virtual void MessageSent( Message *msg,
uint16_t subStream,
uint32_t bytesSent,
AnyObject &channelData );
//------------------------------------------------------------------------
//! Get signature for given message
//------------------------------------------------------------------------
virtual Status GetSignature( Message *toSign, Message *&sign,
AnyObject &channelData );
//------------------------------------------------------------------------
//! Wait until the program can safely exit
//------------------------------------------------------------------------
virtual void WaitBeforeExit();
//------------------------------------------------------------------------
//! @return : true if encryption should be turned on, false otherwise
//------------------------------------------------------------------------
virtual bool UseEncryption( HandShakeData *handShakeData,
AnyObject &channelData );
private:
//------------------------------------------------------------------------
// Hand shake the main stream
//------------------------------------------------------------------------
Status HandShakeMain( HandShakeData *handShakeData,
AnyObject &channelData );
//------------------------------------------------------------------------
// Hand shake a parallel stream
//------------------------------------------------------------------------
Status HandShakeParallel( HandShakeData *handShakeData,
AnyObject &channelData );
//------------------------------------------------------------------------
// Generate the message to be sent as an initial handshake
// (handshake + kXR_protocol)
//------------------------------------------------------------------------
Message *GenerateInitialHSProtocol( HandShakeData *hsData,
XRootDChannelInfo *info,
kXR_char expect );
//------------------------------------------------------------------------
// Process the server initial handshake response
//------------------------------------------------------------------------
Status ProcessServerHS( HandShakeData *hsData,
XRootDChannelInfo *info );
//-----------------------------------------------------------------------
// Process the protocol response
//------------------------------------------------------------------------
Status ProcessProtocolResp( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Generate the bind message
//------------------------------------------------------------------------
Message *GenerateBind( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Generate the bind message
//------------------------------------------------------------------------
Status ProcessBindResp( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Generate the login message
//------------------------------------------------------------------------
Message *GenerateLogIn( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Process the login response
//------------------------------------------------------------------------
Status ProcessLogInResp( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Do the authentication
//------------------------------------------------------------------------
Status DoAuthentication( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Get the initial credentials using one of the protocols
//------------------------------------------------------------------------
Status GetCredentials( XrdSecCredentials *&credentials,
HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Clean up the data structures created for the authentication process
//------------------------------------------------------------------------
Status CleanUpAuthentication( XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Clean up the data structures created for the protection purposes
//------------------------------------------------------------------------
Status CleanUpProtection( XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Get the authentication function handle
//------------------------------------------------------------------------
XrdSecGetProt_t GetAuthHandler();
//------------------------------------------------------------------------
// Generate the end session message
//------------------------------------------------------------------------
Message *GenerateEndSession( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Process the end session response
//------------------------------------------------------------------------
Status ProcessEndSessionResp( HandShakeData *hsData,
XRootDChannelInfo *info );
//------------------------------------------------------------------------
// Get a string representation of the server flags
//------------------------------------------------------------------------
static std::string ServerFlagsToStr( uint32_t flags );
//------------------------------------------------------------------------
// Get a string representation of file handle
//------------------------------------------------------------------------
static std::string FileHandleToStr( const unsigned char handle[4] );
XrdSecGetProt_t pAuthHandler;
friend struct PluginUnloadHandler;
PluginUnloadHandler *pSecUnloadHandler;
};
}
#endif // __XRD_CL_XROOTD_TRANSPORT_HANDLER_HH__