There are several class of interest here: SocksQueue, Socks5, Socks5Sender, Socks5Listener, and Socks5Receiver
Socks5Listener is the class in charge of binding to a port and accepting connections. SocksQueue manages the file transfer, it keeps track of when a transfer is completed or canceled.
Socks5Sender and Socks5Receiver, are in charge of sending and receiving the file, both of them are derived from the class Socks5. So, they are basically the same object with some minor differences.
As it can be seen from this picture, both objects are fairly similar, except for the receiver having the connect, do_connect, is_connected methods and the sender having the send_file method.
Those objects are also in charged of the socks5 negotiation and they keep track of it by using this state machine:
|0||About to connect|
|1||send version and auth types / initial read|
|2||read auth response / reply with desired auth type|
|3||send 'connect' request / read connect request|
|4||get approve of our request / approve connect|
|5||????? / read file|
|6||retrieve file / ????|
There are more states, but these are the most important. What I have been doing so far is that have been modifying the objects so that they can emulate each other. Each object, for every state, will only do the thing that's after the "/" or before it. As I wrote the table, the operation in the left side of the "/" is what the receiver does and in the the right side of it, is what the sender does.
So far in my code, the receiver and the sender, do the operations in from state 0-2 . But then I realized that my approach was wrong all along. Instead of making the objects do both operations, Socks5 should be able to do both operations, and then the receiver and the sender can just inherit that behavior.