FtpRelay.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /* DEBUG: section 09 File Transfer Protocol (FTP) */
10 
11 #include "squid.h"
12 #include "anyp/PortCfg.h"
13 #include "client_side.h"
14 #include "clients/forward.h"
15 #include "clients/FtpClient.h"
16 #include "ftp/Elements.h"
17 #include "ftp/Parsing.h"
18 #include "http/Stream.h"
19 #include "HttpHdrCc.h"
20 #include "HttpRequest.h"
21 #include "sbuf/SBuf.h"
22 #include "servers/FtpServer.h"
23 #include "SquidTime.h"
24 #include "Store.h"
25 #include "wordlist.h"
26 
27 namespace Ftp
28 {
29 
33 class Relay: public Ftp::Client
34 {
36 
37 public:
38  explicit Relay(FwdState *const fwdState);
39  virtual ~Relay();
40 
41 protected:
42  const Ftp::MasterState &master() const;
45  void serverState(const Ftp::ServerState newState);
46 
47  /* Ftp::Client API */
48  virtual void failed(err_type error = ERR_NONE, int xerrno = 0, ErrorState *ftperr = nullptr);
49  virtual void dataChannelConnected(const CommConnectCbParams &io);
50 
51  /* Client API */
52  virtual void serverComplete();
53  virtual void handleControlReply();
54  virtual void processReplyBody();
55  virtual void handleRequestBodyProducerAborted();
56  virtual bool mayReadVirginReplyBody() const;
57  virtual void completeForwarding();
58  virtual bool abortOnData(const char *reason);
59 
60  /* AsyncJob API */
61  virtual void start();
62  virtual void swanSong();
63 
64  void forwardReply();
65  void forwardError(err_type error = ERR_NONE, int xerrno = 0);
66  void failedErrorMessage(err_type error, int xerrno);
67  HttpReply *createHttpReply(const Http::StatusCode httpStatus, const int64_t clen = 0);
68  void handleDataRequest();
69  void startDataDownload();
70  void startDataUpload();
71  bool startDirTracking();
72  void stopDirTracking();
73  bool weAreTrackingDir() const {return savedReply.message != NULL;}
74 
75  typedef void (Relay::*PreliminaryCb)();
79 
80  typedef void (Relay::*SM_FUNC)();
81  static const SM_FUNC SM_FUNCS[];
82  void readGreeting();
83  void sendCommand();
84  void readReply();
85  void readFeatReply();
86  void readPasvReply();
87  void readDataReply();
88  void readTransferDoneReply();
89  void readEpsvReply();
90  void readCwdOrCdupReply();
91  void readUserOrPassReply();
92 
94 
96  void stopOriginWait(int code);
97 
98  static void abort(void *d); // TODO: Capitalize this and FwdState::abort().
99 
101 
105 
106  struct {
108  char *lastCommand;
109  char *lastReply;
110  int replyCode;
111  } savedReply;
112 };
113 
114 } // namespace Ftp
115 
117 
119  &Ftp::Relay::readGreeting, // BEGIN
120  &Ftp::Relay::readUserOrPassReply, // SENT_USER
121  &Ftp::Relay::readUserOrPassReply, // SENT_PASS
122  NULL,/* &Ftp::Relay::readReply */ // SENT_TYPE
123  NULL,/* &Ftp::Relay::readReply */ // SENT_MDTM
124  NULL,/* &Ftp::Relay::readReply */ // SENT_SIZE
125  NULL, // SENT_EPRT
126  NULL, // SENT_PORT
127  &Ftp::Relay::readEpsvReply, // SENT_EPSV_ALL
128  &Ftp::Relay::readEpsvReply, // SENT_EPSV_1
129  &Ftp::Relay::readEpsvReply, // SENT_EPSV_2
130  &Ftp::Relay::readPasvReply, // SENT_PASV
131  &Ftp::Relay::readCwdOrCdupReply, // SENT_CWD
132  NULL,/* &Ftp::Relay::readDataReply, */ // SENT_LIST
133  NULL,/* &Ftp::Relay::readDataReply, */ // SENT_NLST
134  NULL,/* &Ftp::Relay::readReply */ // SENT_REST
135  NULL,/* &Ftp::Relay::readDataReply */ // SENT_RETR
136  NULL,/* &Ftp::Relay::readReply */ // SENT_STOR
137  NULL,/* &Ftp::Relay::readReply */ // SENT_QUIT
138  &Ftp::Relay::readTransferDoneReply, // READING_DATA
139  &Ftp::Relay::readReply, // WRITING_DATA
140  NULL,/* &Ftp::Relay::readReply */ // SENT_MKDIR
141  &Ftp::Relay::readFeatReply, // SENT_FEAT
142  NULL,/* &Ftp::Relay::readPwdReply */ // SENT_PWD
143  &Ftp::Relay::readCwdOrCdupReply, // SENT_CDUP
144  &Ftp::Relay::readDataReply,// SENT_DATA_REQUEST
145  &Ftp::Relay::readReply, // SENT_COMMAND
146  NULL
147 };
148 
149 Ftp::Relay::Relay(FwdState *const fwdState):
150  AsyncJob("Ftp::Relay"),
151  Ftp::Client(fwdState),
155 {
156  savedReply.message = NULL;
157  savedReply.lastCommand = NULL;
158  savedReply.lastReply = NULL;
159  savedReply.replyCode = 0;
160 
161  // Nothing we can do at request creation time can mark the response as
162  // uncachable, unfortunately. This prevents "found KEY_PRIVATE" WARNINGs.
164  // TODO: Convert registerAbort() to use AsyncCall
166 }
167 
169 {
170  closeServer(); // TODO: move to clients/Client.cc?
171  if (savedReply.message)
172  wordlistDestroy(&savedReply.message);
173 
174  xfree(savedReply.lastCommand);
175  xfree(savedReply.lastReply);
176 }
177 
178 void
180 {
181  if (!master().clientReadGreeting)
183  else if (serverState() == fssHandleDataRequest ||
186  else
187  sendCommand();
188 }
189 
190 void
192 {
193  stopOriginWait(0);
195 }
196 
199 void
201 {
203 
205  if (mgr.valid()) {
206  if (Comm::IsConnOpen(ctrl.conn)) {
207  debugs(9, 7, "completing FTP server " << ctrl.conn <<
208  " after " << ctrl.replycode);
210  if (ctrl.replycode == 221) { // Server sends FTP 221 before closing
211  mgr->unpinConnection(false);
212  ctrl.close();
213  } else {
214  CallJobHere1(9, 4, mgr,
216  notePinnedConnectionBecameIdle,
218  ctrl.forget();
219  }
220  }
221  }
223 }
224 
229 {
231  if (mgr.valid()) {
232  if (Ftp::Server *srv = dynamic_cast<Ftp::Server*>(mgr.get()))
233  return *srv->master;
234  }
235  // this code will not be necessary once the master is inside MasterXaction
236  debugs(9, 3, "our server side is gone: " << mgr);
237  static Ftp::MasterState Master;
238  Master = Ftp::MasterState();
239  return Master;
240 }
241 
243 const Ftp::MasterState &
245 {
246  return const_cast<Ftp::Relay*>(this)->updateMaster(); // avoid code dupe
247 }
248 
250 void
252 {
254  debugs(9, 3, "client state was " << cltState << " now: " << newState);
255  cltState = newState;
256 }
257 
266 void
268 {
271  return;
272  forwardingCompleted = true;
274 }
275 
276 void
278 {
279  if (!doneWithServer())
281 
282  // TODO: we need to customize ErrorState instead
283  if (entry->isEmpty())
284  failedErrorMessage(error, xerrno); // as a reply
285 
286  Ftp::Client::failed(error, xerrno, ftpErr);
287 }
288 
289 void
291 {
292  const Http::StatusCode httpStatus = failedHttpStatus(error);
293  HttpReply *const reply = createHttpReply(httpStatus);
294  entry->replaceHttpReply(reply);
295  fwd->request->detailError(error, xerrno);
296 }
297 
298 void
300 {
301  debugs(9, 3, status());
302 
304  /*
305  * probably was aborted because content length exceeds one
306  * of the maximum size limits.
307  */
308  abortOnData("entry aborted after calling appendSuccessHeader()");
309  return;
310  }
311 
312  if (master().userDataDone) {
313  // Squid-to-client data transfer done. Abort data transfer on our
314  // side to allow new commands from ftp client
315  abortOnData("Squid-to-client data connection is closed");
316  return;
317  }
318 
319 #if USE_ADAPTATION
320 
322  debugs(9, 3, "returning due to adaptationAccessCheckPending");
323  return;
324  }
325 
326 #endif
327 
328  if (data.readBuf != NULL && data.readBuf->hasContent()) {
329  const mb_size_t csize = data.readBuf->contentSize();
330  debugs(9, 5, "writing " << csize << " bytes to the reply");
332  data.readBuf->consume(csize);
333  }
334 
335  entry->flush();
336 
338 }
339 
340 void
342 {
344  debugs(9, 5, "client connection gone");
345  closeServer();
346  return;
347  }
348 
350  if (ctrl.message == NULL)
351  return; // didn't get complete reply yet
352 
353  assert(state < END);
354  assert(this->SM_FUNCS[state] != NULL);
355  (this->*SM_FUNCS[state])();
356 }
357 
358 void
360 {
362 
364 }
365 
366 bool
368 {
369  // TODO: move this method to the regular FTP server?
370  return Comm::IsConnOpen(data.conn);
371 }
372 
373 void
375 {
376  assert(entry->isEmpty());
377 
379  reply->sources |= Http::Message::srcFtp;
380 
381  setVirginReply(reply);
383 
384  serverComplete();
385 }
386 
387 void
389 {
390  debugs(9, 5, "forwarding preliminary reply to client");
391 
392  // we must prevent concurrent ConnStateData::sendControlMsg() calls
394  thePreliminaryCb = cb;
395 
397 
398  // the Sink will use this to call us back after writing 1xx to the client
399  typedef NullaryMemFunT<Relay> CbDialer;
400  const AsyncCall::Pointer call = JobCallback(11, 3, CbDialer, this,
402 
405 }
406 
407 void
409 {
410  debugs(9, 5, "proceeding after preliminary reply to client");
411 
413  const PreliminaryCb cb = thePreliminaryCb;
415  (this->*cb)();
416 }
417 
418 void
420 {
421  failed(error, xerrno);
422 }
423 
424 HttpReply *
425 Ftp::Relay::createHttpReply(const Http::StatusCode httpStatus, const int64_t clen)
426 {
427  HttpReply *const reply = Ftp::HttpReplyWrapper(ctrl.replycode, ctrl.last_reply, httpStatus, clen);
428  if (ctrl.message) {
429  for (wordlist *W = ctrl.message; W && W->next; W = W->next)
431  // no hdrCacheInit() is needed for after Http::HdrType::FTP_PRE addition
432  }
433  return reply;
434 }
435 
436 void
438 {
439  data.addr(master().clientDataAddr);
441 }
442 
443 void
445 {
447 
448  debugs(9, 3, "begin data transfer from " << data.conn->remote <<
449  " (" << data.conn->local << ")");
450 
451  HttpReply *const reply = createHttpReply(Http::scOkay, -1);
452  reply->sources |= Http::Message::srcFtp;
453 
454  setVirginReply(reply);
456 
459 }
460 
461 void
463 {
465 
466  debugs(9, 3, "begin data transfer to " << data.conn->remote <<
467  " (" << data.conn->local << ")");
468 
469  if (!startRequestBodyFlow()) { // register to receive body data
470  failed();
471  return;
472  }
473 
475 }
476 
477 void
479 {
480  assert(!master().clientReadGreeting);
481 
482  switch (ctrl.replycode) {
483  case 220:
485  if (serverState() == fssBegin)
487 
488  // Do not forward server greeting to the user because our FTP Server
489  // has greeted the user already. Also, an original origin greeting may
490  // confuse a user that has changed the origin mid-air.
491 
492  start();
493  break;
494  case 120:
495  if (NULL != ctrl.message)
496  debugs(9, DBG_IMPORTANT, "FTP server is busy: " << ctrl.message->key);
498  break;
499  default:
500  failed();
501  break;
502  }
503 }
504 
505 void
507 {
509  abortAll("Internal error: FTP relay request with no command");
510  return;
511  }
512 
513  HttpHeader &header = fwd->request->header;
515  const String &cmd = header.findEntry(Http::HdrType::FTP_COMMAND)->value;
517  const String &params = header.findEntry(Http::HdrType::FTP_ARGUMENTS)->value;
518 
519  if (params.size() > 0)
520  debugs(9, 5, "command: " << cmd << ", parameters: " << params);
521  else
522  debugs(9, 5, "command: " << cmd << ", no parameters");
523 
524  if (serverState() == fssHandlePasv ||
525  serverState() == fssHandleEpsv ||
526  serverState() == fssHandleEprt ||
527  serverState() == fssHandlePort) {
528  sendPassive();
529  return;
530  }
531 
532  SBuf buf;
533  if (params.size() > 0)
534  buf.Printf("%s %s%s", cmd.termedBuf(), params.termedBuf(), Ftp::crlf);
535  else
536  buf.Printf("%s%s", cmd.termedBuf(), Ftp::crlf);
537 
538  writeCommand(buf.c_str());
539 
540  state =
548  SENT_COMMAND;
549 
550  if (state == SENT_DATA_REQUEST) {
552  if (mgr.valid()) {
553  if (Ftp::Server *srv = dynamic_cast<Ftp::Server*>(mgr.get())) {
554  typedef NullaryMemFunT<Ftp::Server> CbDialer;
555  AsyncCall::Pointer call = JobCallback(11, 3, CbDialer, srv,
557  ScheduleCallHere(call);
558  originWaitInProgress = true;
559  }
560  }
561  }
562 }
563 
564 void
566 {
569 
570  if (Is1xx(ctrl.replycode))
572  else
573  forwardReply();
574 }
575 
576 void
578 {
580 
581  if (Is1xx(ctrl.replycode))
582  return; // ignore preliminary replies
583 
584  forwardReply();
585 }
586 
587 void
589 {
591 
592  if (Is1xx(ctrl.replycode))
593  return; // ignore preliminary replies
594 
595  if (handlePasvReply(updateMaster().clientDataAddr))
596  forwardReply();
597  else
598  forwardError();
599 }
600 
601 void
603 {
604  if (Is1xx(ctrl.replycode))
605  return; // ignore preliminary replies
606 
607  if (handleEpsvReply(updateMaster().clientDataAddr)) {
608  if (ctrl.message == NULL)
609  return; // didn't get complete reply yet
610 
611  forwardReply();
612  } else
613  forwardError();
614 }
615 
616 void
618 {
621 
622  if (ctrl.replycode == 125 || ctrl.replycode == 150) {
625  else if (fwd->request->forcedBodyContinuation /*&& serverState() == fssHandleUploadRequest*/)
626  startDataUpload();
627  else // serverState() == fssHandleUploadRequest
629  } else
630  forwardReply();
631 }
632 
633 bool
635 {
636  if (!fwd->request->clientConnectionManager->port->ftp_track_dirs)
637  return false;
638 
639  debugs(9, 5, "start directory tracking");
640  savedReply.message = ctrl.message;
641  savedReply.lastCommand = ctrl.last_command;
642  savedReply.lastReply = ctrl.last_reply;
643  savedReply.replyCode = ctrl.replycode;
644 
646  ctrl.last_reply = NULL;
647  ctrl.message = NULL;
648  ctrl.offset = 0;
649  writeCommand("PWD\r\n");
650  return true;
651 }
652 
653 void
655 {
656  debugs(9, 5, "got code from pwd: " << ctrl.replycode << ", msg: " << ctrl.last_reply);
657 
658  if (ctrl.replycode == 257)
660 
664 
665  ctrl.message = savedReply.message;
666  ctrl.last_command = savedReply.lastCommand;
667  ctrl.last_reply = savedReply.lastReply;
668  ctrl.replycode = savedReply.replyCode;
669 
670  savedReply.message = NULL;
671  savedReply.lastReply = NULL;
672  savedReply.lastCommand = NULL;
673 }
674 
675 void
677 {
680 
681  debugs(9, 5, "got code " << ctrl.replycode << ", msg: " << ctrl.last_reply);
682 
683  if (Is1xx(ctrl.replycode))
684  return;
685 
686  if (weAreTrackingDir()) { // we are tracking
687  stopDirTracking(); // and forward the delayed response below
688  } else if (startDirTracking())
689  return;
690 
691  forwardReply();
692 }
693 
694 void
696 {
697  if (Is1xx(ctrl.replycode))
698  return; //Just ignore
699 
700  if (weAreTrackingDir()) { // we are tracking
701  stopDirTracking(); // and forward the delayed response below
702  } else if (ctrl.replycode == 230) { // successful login
703  if (startDirTracking())
704  return;
705  }
706 
707  forwardReply();
708 }
709 
710 void
712 {
713  debugs(9, 3, status());
714 
715  if (ctrl.replycode != 226 && ctrl.replycode != 250) {
716  debugs(9, DBG_IMPORTANT, "got FTP code " << ctrl.replycode <<
717  " after reading response data");
718  }
719 
720  debugs(9, 2, "Complete data downloading");
721 
722  serverComplete();
723 }
724 
725 void
727 {
728  debugs(9, 3, status());
729  data.opener = NULL;
730 
731  if (io.flag != Comm::OK) {
732  debugs(9, 2, "failed to connect FTP server data channel");
734  return;
735  }
736 
737  debugs(9, 2, "connected FTP server data channel: " << io.conn);
738 
739  data.opened(io.conn, dataCloser());
740 
741  sendCommand();
742 }
743 
744 void
746 {
748 }
749 
750 bool
751 Ftp::Relay::abortOnData(const char *reason)
752 {
753  debugs(9, 3, "aborting transaction for " << reason <<
754  "; FD " << (ctrl.conn != NULL ? ctrl.conn->fd : -1) << ", Data FD " << (data.conn != NULL ? data.conn->fd : -1) << ", this " << this);
755  // this method is only called to handle data connection problems
756  // the control connection should keep going
757 
758 #if USE_ADAPTATION
759  if (adaptedBodySource != NULL)
761 #endif
762 
764  dataComplete();
765 
766  return !Comm::IsConnOpen(ctrl.conn);
767 }
768 
769 void
771 {
772  if (originWaitInProgress) {
774  if (mgr.valid()) {
775  if (Ftp::Server *srv = dynamic_cast<Ftp::Server*>(mgr.get())) {
776  typedef UnaryMemFunT<Ftp::Server, int> CbDialer;
777  AsyncCall::Pointer call = asyncCall(11, 3, "Ftp::Server::stopWaitingForOrigin",
778  CbDialer(srv, &Ftp::Server::stopWaitingForOrigin, code));
779  ScheduleCallHere(call);
780  }
781  }
782  originWaitInProgress = false;
783  }
784 }
785 
786 void
788 {
789  Ftp::Relay *ftpClient = (Ftp::Relay *)d;
790  debugs(9, 2, "Client Data connection closed!");
791  if (!cbdataReferenceValid(ftpClient))
792  return;
793  if (Comm::IsConnOpen(ftpClient->data.conn))
794  ftpClient->dataComplete();
795 }
796 
798 Ftp::StartRelay(FwdState *const fwdState)
799 {
800  return AsyncJob::Start(new Ftp::Relay(fwdState));
801 }
802 
void(Relay::* PreliminaryCb)()
Definition: FtpRelay.cc:75
virtual void closeServer()
Definition: FtpClient.cc:217
void scheduleReadControlReply(int buffered_ok)
Definition: FtpClient.cc:309
virtual ~Relay()
Definition: FtpRelay.cc:168
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
Definition: AsyncJobCalls.h:68
#define assert(EX)
Definition: assert.h:17
virtual bool doneWithServer() const
Definition: FtpClient.cc:240
int replyCode
the reply status
Definition: FtpRelay.cc:110
ServerState
Definition: FtpServer.h:20
void startDataUpload()
Definition: FtpRelay.cc:462
bool handleEpsvReply(Ip::Address &remoteAddr)
Definition: FtpClient.cc:475
AsyncCall::Pointer dataCloser()
creates a data channel Comm close callback
Definition: FtpClient.cc:786
void writeCommand(const char *buf)
Definition: FtpClient.cc:806
CBDATA_NAMESPACED_CLASS_INIT(Ftp, Relay)
bool startRequestBodyFlow()
Definition: Client.cc:215
void adaptOrFinalizeReply()
Definition: Client.cc:944
Definition: SBuf.h:86
static const SM_FUNC SM_FUNCS[]
Definition: FtpRelay.cc:81
const char *const crlf
Definition: FtpClient.cc:35
HttpHeaderEntry * findEntry(Http::HdrType id) const
Definition: HttpHeader.cc:617
void consume(mb_size_t sz)
removes sz bytes and "packs" by moving content left
Definition: MemBuf.cc:171
void serverComplete()
Definition: Client.cc:156
virtual bool abortOnData(const char *reason)
Definition: FtpRelay.cc:751
void error(char *format,...)
StoreEntry * entry
Definition: Client.h:164
Transaction information shared among our FTP client and server jobs.
Definition: FtpServer.h:39
FTP client functionality shared among FTP Gateway and Relay clients.
Definition: FtpClient.h:92
virtual void maybeReadVirginBody()
read response data from the network
Definition: FtpClient.cc:889
void startDataDownload()
Definition: FtpRelay.cc:444
#define safe_free(x)
Definition: xalloc.h:73
CtrlChannel ctrl
FTP control channel state.
Definition: FtpClient.h:124
void wordlistDestroy(wordlist **list)
destroy a wordlist
Definition: wordlist.cc:16
SBuf workingDir
estimated current working directory for URI formation
Definition: FtpServer.h:47
Definition: Flag.h:16
bool forcedBodyContinuation
whether we have responded with HTTP 100 or FTP 150 already
Definition: HttpRequest.h:195
Ftp::MasterState & updateMaster()
Definition: FtpRelay.cc:228
virtual void flush()
Definition: store.cc:1652
HttpRequest * request
Definition: FwdState.h:157
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
char * key
Definition: wordlist.h:33
void sendCommand()
Definition: FtpRelay.cc:506
const Ftp::MasterState & master() const
A const variant of updateMaster().
Definition: FtpRelay.cc:244
bool originWaitInProgress
Definition: FtpRelay.cc:104
const char * UnescapeDoubleQuoted(const char *quotedPath)
parses an FTP-quoted quote-escaped path
Definition: Parsing.cc:90
MemBuf * readBuf
Definition: FtpClient.h:85
bool clientReadGreeting
Definition: FtpServer.h:49
void startWaitingForOrigin()
Definition: FtpServer.cc:1762
void replaceHttpReply(HttpReply *, bool andStartWriting=true)
Definition: store.cc:1788
ftp_port or FTP server
Definition: Message.h:40
void forget()
Definition: FtpClient.cc:98
bool forwardingCompleted
completeForwarding() has been called
Definition: FtpRelay.cc:100
void stopOriginWait(int code)
Inform Ftp::Server that we are done if originWaitInProgress.
Definition: FtpRelay.cc:770
AsyncCall * asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:156
virtual const char * status() const
internal cleanup; do not call directly
Definition: AsyncJob.cc:159
static Pointer Start(AsyncJob *job)
starts a freshly created job (i.e., makes the job asynchronous)
Definition: AsyncJob.cc:23
parameters for the async notePinnedConnectionBecameIdle() call
Definition: client_side.h:168
Manages a control connection from an FTP client.
Definition: FtpServer.h:55
Comm::ConnectionPointer conn
Definition: CommCalls.h:85
DataChannel data
FTP data channel state.
Definition: FtpClient.h:125
char * last_command
Definition: FtpClient.h:65
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:24
char * lastCommand
the command caused the reply
Definition: FtpRelay.cc:108
StatusCode
Definition: StatusCode.h:20
AsyncCall::Pointer opener
Comm opener handler callback.
Definition: FtpClient.h:48
void scheduleReadControlReply()
Definition: FtpRelay.cc:745
void readEpsvReply()
Definition: FtpRelay.cc:602
virtual void sendControlMsg(HttpControlMsg)
called to send the 1xx message and notify the Source
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
virtual bool mayReadVirginReplyBody() const
whether we may receive more virgin response body bytes
Definition: FtpRelay.cc:367
#define DBG_IMPORTANT
Definition: Debug.h:46
void handleDataRequest()
Definition: FtpRelay.cc:437
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
virtual void handleControlReply()
Definition: FtpRelay.cc:341
FwdState::Pointer fwd
Definition: Client.h:165
void unpinConnection(const bool andClose)
Undo pinConnection() and, optionally, close the pinned connection.
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
virtual void handleRequestBodyProducerAborted()=0
Definition: Client.cc:327
SBuf & Printf(const char *fmt,...)
Definition: SBuf.cc:224
wordlist * message
Definition: FtpClient.h:64
void readCwdOrCdupReply()
Definition: FtpRelay.cc:676
int xerrno
The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
Definition: CommCalls.h:88
HttpReply * createHttpReply(const Http::StatusCode httpStatus, const int64_t clen=0)
Definition: FtpRelay.cc:425
virtual void handleRequestBodyProducerAborted()
Definition: FtpRelay.cc:359
void readDataReply()
Definition: FtpRelay.cc:617
void stopWaitingForOrigin(int status)
Definition: FtpServer.cc:1772
bool isEmpty() const
Definition: Store.h:60
virtual void start()
called by AsyncStart; do not call directly
Definition: FtpClient.cc:199
bundles HTTP 1xx reply and the "successfully forwarded" callback
bool sendPassive()
Definition: FtpClient.cc:637
char * lastReply
last line of reply: reply status plus message
Definition: FtpRelay.cc:109
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:230
virtual void processReplyBody()
Definition: FtpRelay.cc:299
void releaseRequest(const bool shareable=false)
Definition: store.cc:452
bool startDirTracking()
Definition: FtpRelay.cc:634
const char * c_str()
Definition: SBuf.cc:526
uint16_t flags
Definition: Store.h:210
#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1)
Definition: AsyncJobCalls.h:62
virtual void completeForwarding()
Definition: Client.cc:206
void stopDirTracking()
Definition: FtpRelay.cc:654
void forwardError(err_type error=ERR_NONE, int xerrno=0)
Definition: FtpRelay.cc:419
void forwardPreliminaryReply(const PreliminaryCb cb)
Definition: FtpRelay.cc:388
void addVirginReplyBody(const char *buf, ssize_t len)
Definition: Client.cc:977
char * content()
start of the added data
Definition: MemBuf.h:41
virtual void handleControlReply()
Definition: FtpClient.cc:403
unsigned char code
Definition: html_quote.c:20
void const char * buf
Definition: stub_helper.cc:16
void readGreeting()
Definition: FtpRelay.cc:478
Ip::Address local
Definition: Connection.h:135
HttpHeader header
Definition: Message.h:75
void close()
planned close: removes the close handler and calls comm_close
Definition: FtpClient.cc:87
void readTransferDoneReply()
Definition: FtpRelay.cc:711
void addr(const Ip::Address &addr)
import host and port
Definition: FtpClient.cc:153
char * last_reply
Definition: FtpClient.h:66
void readReply()
Definition: FtpRelay.cc:565
int has(Http::HdrType id) const
Definition: HttpHeader.cc:977
Ip::Address remote
Definition: Connection.h:138
void putStr(Http::HdrType id, const char *str)
Definition: HttpHeader.cc:1038
#define ScheduleCallHere(call)
Definition: AsyncCall.h:166
Relay(FwdState *const fwdState)
Definition: FtpRelay.cc:149
HttpRequestPointer request
Definition: Client.h:166
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
virtual void dataChannelConnected(const CommConnectCbParams &io)
Definition: FtpRelay.cc:726
bool Is1xx(const int sc)
whether this is an informational 1xx response status code
Definition: Elements.h:53
void connectDataChannel()
Definition: FtpClient.cc:746
void detailError(err_type aType, int aDetail)
sets error detail if no earlier detail was available
Definition: HttpRequest.cc:476
HttpReply * setVirginReply(HttpReply *r)
Definition: Client.cc:117
void failedErrorMessage(err_type error, int xerrno)
Definition: FtpRelay.cc:290
Comm::Flag flag
comm layer result status.
Definition: CommCalls.h:87
PreliminaryCb thePreliminaryCb
Definition: FtpRelay.cc:78
void readUserOrPassReply()
Definition: FtpRelay.cc:695
void opened(const Comm::ConnectionPointer &conn, const AsyncCall::Pointer &aCloser)
called after the socket is opened, sets up close handler
Definition: FtpClient.cc:71
ssize_t mb_size_t
Definition: MemBuf.h:17
virtual void completeForwarding()
Definition: FtpRelay.cc:267
static void abort(void *d)
Definition: FtpRelay.cc:787
virtual void serverComplete()
Definition: FtpRelay.cc:200
void stopConsumingFrom(RefCount< BodyPipe > &)
Definition: BodyPipe.cc:118
BodyPipe::Pointer adaptedBodySource
Definition: Client.h:175
Definition: forward.h:27
int cbdataReferenceValid(const void *p)
Definition: cbdata.cc:412
bool adaptationAccessCheckPending
Definition: Client.h:177
virtual Http::StatusCode failedHttpStatus(err_type &error)
Definition: FtpClient.cc:295
void registerAbort(STABH *cb, void *)
Definition: store.cc:1520
bool weAreTrackingDir() const
Definition: FtpRelay.cc:73
AsyncJobPointer StartRelay(FwdState *const fwdState)
A new FTP Relay job.
Definition: FtpRelay.cc:798
Ftp::ServerState serverState() const
Definition: FtpRelay.cc:44
virtual void failed(err_type error=ERR_NONE, int xerrno=0, ErrorState *ftperr=nullptr)
handle a fatal transaction error, closing the control connection
Definition: FtpRelay.cc:277
virtual void swanSong()
Definition: Client.cc:69
virtual void failed(err_type error=ERR_NONE, int xerrno=0, ErrorState *ftperr=nullptr)
handle a fatal transaction error, closing the control connection
Definition: FtpClient.cc:246
void proceedAfterPreliminaryReply()
Definition: FtpRelay.cc:408
SBuf httpHeaderQuoteString(const char *raw)
quotes string using RFC 7230 quoted-string rules
wordlist * message
reply message, one wordlist entry per message line
Definition: FtpRelay.cc:107
ServerState serverState
what our FTP server is doing
Definition: FtpServer.h:48
#define xfree
CBDATA_CLASS(Relay)
bool hasContent() const
Definition: MemBuf.h:54
Comm::ConnectionPointer conn
channel descriptor
Definition: FtpClient.h:39
void readPasvReply()
Definition: FtpRelay.cc:588
#define EBIT_TEST(flag, bit)
Definition: defines.h:107
void(Relay::* SM_FUNC)()
Definition: FtpRelay.cc:80
virtual void swanSong()
Definition: FtpRelay.cc:191
#define NULL
Definition: types.h:166
struct Ftp::Relay::@42 savedReply
set and delayed while we are tracking using PWD
void dataComplete()
Definition: FtpClient.cc:991
uint32_t sources
The message sources.
Definition: Message.h:100
#define false
Definition: GnuRegex.c:233
err_type
Definition: err_type.h:12
virtual void abortAll(const char *reason)
abnormal transaction termination; reason is for debugging only
Definition: FtpClient.cc:1020
HttpReply * HttpReplyWrapper(const int ftpStatus, const char *ftpReason, const Http::StatusCode httpStatus, const int64_t clen)
Create an internal HttpReply structure to house FTP control response info.
Definition: Elements.cc:30
virtual void start()
called by AsyncStart; do not call directly
Definition: FtpRelay.cc:179
void readFeatReply()
Definition: FtpRelay.cc:577
void unregister(Comm::ConnectionPointer &conn)
Definition: FwdState.cc:466
void forwardReply()
Definition: FtpRelay.cc:374
wordlist * next
Definition: wordlist.h:34
bool handlePasvReply(Ip::Address &remoteAddr)
Definition: FtpClient.cc:439

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors