PDA

View Full Version : Issues of post command events & connection transfer count


SysOp
10-26-2009, 08:38 AM
ioFTPd Version: 7.0.0

Here is part of the ioFTPD.ini file:
[FTP_Pre-Command_Events]
user = TCL ..\scripts\test.itcl pre_user
pass = TCL ..\scripts\test.itcl pre_pass

[FTP_Post-Command_Events]
user = TCL ..\scripts\test.itcl post_user
pass = TCL ..\scripts\test.itcl post_pass

And here is "..\scripts\test.itcl":
iputs -nobuffer $args

But this's what I get when I log in:
220 FTP Server ready.
user ioFTPD
pre_user user ioFTPD
331 Password required for ioFTPD.
pass ioFTPD
pre_pass pass ioFTPD
post_pass pass ioFTPD
230-User ioFTPD from 127.0.0.1, welcome to our FTP server.
...

The question is, where is the "post_user" command? I've noticed that it said "These are called after the real command successfully completed." in [FTP_Post-Command_Events].
Is that because the error code (ioPrefix) is 3xx- instead of 2xx-, so that the "user" command never returns success?

==========
Another question:

How can I do if I want to count the total transfer amount of one specified connection (CID) in an ioFTPd iTCL script? I have browsed the iTCL commands list reference by Yil, but it turned out to be nothing. Finally, I tried to modify the source file: commented out Line 469 in MessageHandler.c can make "client who(OnlineData)>>TransferSize" not to be zeroed when a new transfer begins. (What is commented is: "lpClient->Static.i64TotalBytesTransfered = 0;") But there still remains a problem, which is, when the transfer speed is high, "TransferSize" will be quite smaller than the actual transferred size. I think there's a good chance the reason is when the transfer is completed, the rest amount won't been counted. But I have no idea how to do to fix this.

==========
Thank Yil and any others who finish reading my post.

p.s. I've made two changes to ioFTPD v7. One is adding "Deny_Encrypted_Data" to [FTP_Service] to choose not to allow ssl data transfer while ssl auth and list are permitted; Another one is adding ClientType data to OnlineData in iTCL. And do not allow ClientType change, i.e. deny the second CLNT request. I wish Yil could add these features to newer ioFTPD versions, and I can provide the modified source file if needed.

Yil
10-26-2009, 11:49 PM
Hmm, I'll have to get back to you about the post user event after examining the code.

Modifying the OnlineData structure or what each field means is walking into a minefield because that's the shared memory structure used by EXEC scripts so I wouldn't recommend that unless you know you aren't going to use 3rd party compiled scripts... I would dearly love to update the structure with additional information but it would break a lot of stuff that I'm not willing to break yet.

Now that I think about it, there really isn't an easy solution to getting the total file transferred byte count for a session because the On[Upload|Download][Complete|Error] style events don't tell you if the file was resumed or not which means you'd have to track that yourself which is annoying. I'll have to see if I can't provide that information via a TCL call/variable during transfer event callbacks. I would expect that to only cover data transfers though and not directory listings, if you want listings as well let me know... Though you might be able to look at the userfile transfer stats in the callback if you're careful to handle the case of multiple user transfers.

ClientType can be retrieved via a TCL call. Do you need this for an EXEC script? If so I can probably add a cookie so you can use it on the EXEC line in the .ini file along with the CID to let a script keep track of that info...

SysOp
10-27-2009, 08:39 AM
Hmm, I'll have to get back to you about the post user event after examining the code.
Okay and thank you very much.

Modifying the OnlineData structure or what each field means is walking into a minefield because that's the shared memory structure used by EXEC scripts so I wouldn't recommend that unless you know you aren't going to use 3rd party compiled scripts... I would dearly love to update the structure with additional information but it would break a lot of stuff that I'm not willing to break yet.
hmmm... I don't quite understand this. In fact, I added "CHAR szClientType[MAX_IDENT];" into "struct _ONLINEDATA" and its relevant codes. It was compiled okay and it keeps running fine without any error. So, I have never modified any existing variables of OnlineData struct. I don't see why it's bad. But yes, I haven't use any EXEC scripts, all scripts are in TCL language.

Now that I think about it, there really isn't an easy solution to getting the total file transferred byte count for a session because the On[Upload|Download][Complete|Error] style events don't tell you if the file was resumed or not which means you'd have to track that yourself which is annoying. I'll have to see if I can't provide that information via a TCL call/variable during transfer event callbacks. I would expect that to only cover data transfers though and not directory listings, if you want listings as well let me know... Though you might be able to look at the userfile transfer stats in the callback if you're careful to handle the case of multiple user transfers.
Firstly I think what I did probably is the easiest change to current codes to partially do this. Can you give me a hint that how to modify the source to let ioFTPd to update i64TotalBytesTransfered's value when a transfer is aborted or completed.
In theory, stats will do this. But when the user is on two or more concurrent sessions, stats are useless.
Any yes, i'll really appreciate it if you could offically add this variable, and I don't really care whether listings count or not in this variable. They are all okay.

ClientType can be retrieved via a TCL call. Do you need this for an EXEC script? If so I can probably add a cookie so you can use it on the EXEC line in the .ini file along with the CID to let a script keep track of that info...
Nope, I don't need this to be added to cookies. A TCL call that I can get the CLNT of a specified CID will work fine.

And finally, I believe that "Deny_Encrypted_Data" is an important switch to save server's CPU resource.

p.s. I've noticed that I can upload attachments here. So anyway, I uploaded my modified source files. Every parts I've modified have their comments.
===
it keeps telling me exceeding quota even ultra compression level is used. So I used .7z and renamed .7z to .zip.

Yil
10-27-2009, 09:02 PM
Look in FTPDataChannel.c. I believe most of what you need to modify can be found there. In particular look for the On* event callbacks after the transfer is complete. You should have access to all the details about the transfer around there including what byte range was sent/received, quota charged, etc. It should be easy to add an extra field to the On* callbacks to pass the bytes transferred and then you can track these in TCL manually using an ioVar to keep state.

Alternatively you could add a new variable in the FTP_VARIABLES structure included by the FTP_USER structure which is used to store per-connection information and is probably the only safe structure to modify as it has no other uses. The tricky part will be how you want to get access to that total as the cookie logic is really messed up, so adding a TCL function might be the easiest way since you don't care about EXEC scripts...

I'll probably add something similar to the next release for you so if the need isn't urgent just wait a bit :)

disclaimer: I didn't design this thing, I'm just maintaining it...

SysOp
10-29-2009, 08:47 PM
Thank you so much. I've successfully added a variable called "i64SessionBytesTransfered" to OnlineData struct and added "SESSTRANSFERSIZE" to "client who init" in iTCL. However, I still look forward to your official version...

And I've resolved the issue of post command events I mentioned in #1 post. I think this is probably a typo bug in "./src/FtpBaseCommands.c", line 2117, the function "FTP_LoginUser" should not return TRUE but return FALSE.

SysOp
10-30-2009, 03:26 AM
And there's another question: in line 2226 of "./src/FtpBaseCommands.c", what's "Remove OOB" (\xFF\xF4\xFF\xFF) for?

Yil
10-30-2009, 04:53 AM
OOB = out-of-band data, i.e. stuff that isn't supposed to be part of the data stream. In this case that's a unicode-header which is a clue on how to decode UTF streams. Evidently at some point an FTP client was caught sending that when it shouldn't and it's being stripped out.