AD 2004, September, 16th The RDCC CTCP extension for automatic mIRC dccserver reverse-dcc handshaking =r========================================================================6= In the document, /CTCP and /CTCPREPLY will be used to describe the syntax as required by the Client-To-Client Protocol: /CTCP Target REQUEST data means to send out a lowlevel message in the form of PRIVMSG Target :\001REQUEST data\001 Similarily, /CTCPREPLY Origin REQUEST atad results in NOTICE Origin :\001REQUEST atad\001 mIRC's /DCC command initiates a connection according to the dccserver protocol if the second argument is an ip (possibly with port). More information about the mIRC dccserver protocol can be found in the mIRC help file. Why? ---- mIRC () provides a so-called "dccserver" in order to allow for reverse DCC connections that are necessary when the initiator of a connection is behind a firewall/router/NAT that wouldn't allow him/her to open listening connections to the internet. Quite some filesharing and chatting scripts implement this in order allow such people to participate in sharing their personal documents. However, the currently implemented way looks almost always like this: - The file-offering script asks the potential receiver to enable his dccserver on a port specified by the offering script - That same script tries to use the hostmask of the receiver to find out his/her IP address - if successful, a connection is established to IP:port according to the mIRC dccserver protocol specification This implementation has some annoying flaws which should get fixed: - as the port to use is dictated by the offering script, the receiver might not be able to follow the request: - the "default" port is 59, which is usually a problem for *nix users that don't chat as root - users that are behind routers etc. that require port-forwarding ("half-firewalled") might only have a limited choice of ports to use freely. It is likely that the port requested by the offering script isn't in their range of usuable ports. Changing the port forwarding is impractical as it often requires the user to restart his/her router, or he/she might not have physical access to that device - these days many servers apply hostmask "masking" or "hiding" in order to protect the users from DoS or similar attacks. This voids the automatic IP retrieval attempted by the offering script. - The current suggestion to the receivers is to disable their hostmasking, but some servers don't even permit that. It is clear that an automatic handshake protocol is necessary where the receiver tells the sender which IP and port it should connect to. Although this could lead to unwanted IP retrieval and defeats the purpose of hostmasking more or less, it would improve the situation greatly for those that wish to establish dcc(server) connections with firewalled mIRC users. Clients that support this protocol can implement security measures like a trusted-users list of people that are allowed to use the dccserver or similar means. Protocol -------- The sender (S) that wishes to use a dccserver on the receiver (R) side issues the following command: S: /CTCP Receiver RDCC [text/url] where - is specified by one of 's', 'c' or 'f' (without the '' marks), corresponding to the modes of dccserver provided by mIRC, and indicating which mode the sender would like to access. (s - send, c - chat, f - fserve) - [text/url] a text message information about this protocol, possibly pointing to a website with more information and a sample implementation The receiver then replies to this inquiry in either of the following ways: If the receiver accepts the inquiry, it sends R: /CTCPREPLY Sender RDCC 0 where - is the receiver's IP address as an integer - is the port where the dccserver is running Of course, the receiver should have done a R: /DCCSERVER + on before (this is a mIRC builtin command) or have set up a dccserver in any other mean so that it is compatible according to the dccserver protocol as specified by mIRC. If the receiver wants to reject the request or there was an error, it should reply in this way R: /CTCPREPLY Sender RDCC [additional info] where - is a numeric representation of the problem that occured: - 0 indicates that *no* error occured and that the receiver accepts the request - the syntax changes as explained above - 1 indicates that an invalid (unknown to the receiver) was specified by the server - 2 indicates that the receiver does not have his dccserver running or does not want to accept this dccserver request - 3 indicates that there was a problem on the client side - anything else isn't defined in the current protocol version - [additional info] could be any additional information on the error, for example a text describing the problem in human language The sender should have a timeout on the reply from the receiver; not every client speaks the protocol so a reply can't be expected. A default timeout of 45 seconds is assumed. The sender may inform the receiver about the protocol using e.g. a NOTICE in case the request times out. Alternatively, the sender might wish to fall back to any other or older protocol. Notes to scripters ------------------ It must be expected that certain implementations of the protocol choose ports for the dccserver randomly, or that the dccserver port gets changed between requests. As such, any script has to use rdcc again and mustn't cache ports for consecutive requests. For example, a fileserving script must not reuse the port that was used for the chat session for the queued send. A script *may* cache that another user supports the rdcc protocol (e.g. if the script attempts another reverse dcc transfer method first before trying rdcc, it might want to cache this information so it can go into rdcc directly for any further request). It may *not* cache that another user does *not* support rdcc, as this user might install an rdcc script into his client during runtime. Examples -------- A chat is to be held: S: /CTCP Receiver RDCC c RDCC-Protocol for mIRC DCCSERVER. See (Receiver has his/her dccserver running on port 59 and wishes to accept) R: /CTCPREPLY Sender RDCC 0 1234567890 59 S: /DCC CHAT 73.150.2.210:59 (this is a mIRC extension to the dccchat command, that is, it uses the dccserver protocol if you "send" to a port/ip) Now the chat is established using the receiver's dccserver. A file is to be sent: S: /CTCP Receiver RDCC s RDCC-Protocol for mIRC DCCSERVER. See (Receiver has the server running on port 4095) R: /CTCPREPLY Sender RDCC 0 1234567890 4095 S: /DCC SEND 73.150.2.210:4095 "E:\My Documents\My Homework.sxw" Now the file is transfered. An error occurs: S: /CTCP Receiver RDCC x This is an invalid RDCC function R: /CTCPREPLY Sender RDCC 1 error: invalid rdcc service Wishes ------ There are already a bunch of different reverse dcc protocols used by other clients: REVERSE by ircii, RSEND by kvirc, PORT0 by virc, ... I truly wish that even though I yet added to this chaos, that at least the mIRC-scripters can unitedly refer to this proposal - it's not about fighting who can invent the best protocol, but rather to ease the life of our users; regardless of script. Sample implementation --------------------- To follow soon(ish). By KyD. Nei ()