Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for DCC file transfers #206

Open
Kabouik opened this issue Jun 5, 2020 · 10 comments · Fixed by trevarj/tiny#2 · May be fixed by #209
Open

Support for DCC file transfers #206

Kabouik opened this issue Jun 5, 2020 · 10 comments · Fixed by trevarj/tiny#2 · May be fixed by #209

Comments

@Kabouik
Copy link

Kabouik commented Jun 5, 2020

Some IRC servers with search bots are based on DCC transfers to send search results in the .txt format to the user, such as #bookz or #ebooks and others.

tiny sends a notification about the DCC transfer being initiated, but can't actually receive anything. I am afraid it would be a lot of work to implement, but it is worth asking. For reference, this is how irssi handles DCC transfers: https://irssi.org/documentation/help/dcc/

@osa1
Copy link
Owner

osa1 commented Jun 6, 2020

I have no objection to supporting IRC extensions.

@trevarj
Copy link
Contributor

trevarj commented Jun 6, 2020

Going to start building this because it is something that I really want too. Right now I only need receiving files, so I don't think I will try and implement anything more than handling DCC SEND and then a command to DCC GET a file. I'm going to keep it as simple as possible.

Overview:

  • PRIVMSG is already parsing CTCP messages, so I will add DCC to the wire:CTCP enum.
  • I believe I will have to store a DCCRecord that holds the address:port, filename, etc. I think I'll store these on state.rs for now, but @osa1 probably has a better idea.
  • Then if the client wants to accept this file, they type /DCC GET sender filename and the file just downloads to some configurable directory, or ignores it (and the DCCRecord times out?).

Spec: https://modern.ircdocs.horse/dcc.html

@Kabouik
Copy link
Author

Kabouik commented Jun 6, 2020

Actually I just need receive too to be able to receive those .zip or .txt files from search bots, so just receive would be perfect for me already, but I assume some would expect send/receive in the future.

@trevarj
Copy link
Contributor

trevarj commented Jun 9, 2020

Just want to comment that I have the client accepting DCC SEND and I have /dcc GET <sender> <file> working, and I'm excited so I wanted to tell someone. I have never used tokio before, so this is a pretty fun learning experience for me.

Next steps:

  • Add download directory to config
  • Add support for client-side SEND (so you can send files to people)
  • Add support for /dcc CLOSE [send|get] <sender/receiver> <filename> to cancel a download?
  • Add ability to rename file (maybe?)
  • Clean up my messy code and add comments

@Kabouik
Copy link
Author

Kabouik commented Jun 9, 2020

I'm excited so I wanted to tell someone

I'm looking forward to trying it too now.

@trevarj
Copy link
Contributor

trevarj commented Jun 11, 2020

@osa1 Hey, if/when you get the time, I would like your opinion on how to handle caching DCC records and then expiring them after a duration...
What I have now is as follows:

  • Receive DCC message
  • Store DCCRecord on each Client's State in a hashmap

It does not expire the records, only removes them when they're accessed.

I'm finding it difficult to spawn a task that expires the records, so I'm thinking that I might need to create another task just for handling DCC stuff in main.rs.

Do you have any expert advice? 😃

@osa1
Copy link
Owner

osa1 commented Jun 12, 2020

@trevarj What do you mean by "DCC record" exactly? Open DCC connections? Or something else?

@trevarj
Copy link
Contributor

trevarj commented Jun 12, 2020

@osa1 When the client receives a DCC command (someone wants to send you a file) you should store the record of it. So, when the user decides to accept the request (file or private chat) then you can go retrieve the record, which has the IP and port to connect to. If the user doesn't want to accept, the record should expire and get freed from memory.

Basically, when you get a CTCP message for DCC (Version is already there) in conn.rs it will push a DCCRecord into the cache. When the user wants to do a 'GET' in cmd.rs it will try to read from the cache.

I've been looking into using tokio::time::DelayQueue and building a custom cache with that, but maybe it is overkill and there's a simpler way we add a cache like this.

@osa1
Copy link
Owner

osa1 commented Jun 12, 2020

Hmm, so for every connection we need a HashMap<Nick, (Ip, Port)> for file send requests. The questions are:

  • Where to store this hash map
  • How to remove entries

For (1) I think we should put it in Client, because it's not shared between servers, and I think we'll need some support from Client anyway to start file download or upload.

We already have a similar state in Client: StateInner::chans. You could add one more field there, I think.

For (2) I think it's fine to not remove entries for now. I think 99.9% of users will never use DCC so the HashMap will always be empty (I've been using IRC for more than 10 years and never used DCC). For the rare cases where you use it, size of the hash map will be bounded by the number of unique nicks you receive a DCC message from. I think this will be a tiny number (e.g. not more than 10 in the worst case). It seems like removing entries is not worth adding any more code.

@trevarj does this make sense? Let me know if my assumptions about DCC are wrong.

@trevarj
Copy link
Contributor

trevarj commented Jun 12, 2020

@osa1 Ok, great, this is pretty much what I have already. Thanks for the help!

trevarj added a commit to trevarj/tiny that referenced this issue Jun 12, 2020
Does not yet support sending files.
Closes osa1#206
trevarj added a commit to trevarj/tiny that referenced this issue Jun 12, 2020
Does not yet support sending files.
Closes osa1#206
@trevarj trevarj linked a pull request Jun 12, 2020 that will close this issue
trevarj added a commit to trevarj/tiny that referenced this issue Jul 14, 2020
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
trevarj added a commit to trevarj/tiny that referenced this issue Aug 13, 2020
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
trevarj added a commit to trevarj/tiny that referenced this issue Aug 13, 2020
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
@osa1 osa1 changed the title [Feature request] Support for DCC file transfers Support for DCC file transfers Nov 10, 2020
trevarj added a commit to trevarj/tiny that referenced this issue Mar 21, 2021
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
trevarj added a commit to trevarj/tiny that referenced this issue Mar 21, 2021
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
trevarj added a commit to trevarj/tiny that referenced this issue Mar 21, 2021
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
trevarj added a commit to trevarj/tiny that referenced this issue Aug 3, 2021
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
trevarj added a commit to trevarj/tiny that referenced this issue Aug 29, 2021
Does not yet support sending files.
Closes osa1#206

Added connection timeout

Fixed NOTICE format which was causing an issue. Spawn regular task instead of local for file download.

Only read number of bytes read.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants