How to properly transfer TCP traffic between sockets?

I am trying to write Python code that will set an invisible relay between two TCP sockets. My current technique is to configure two streams, each of which reads and subsequently writes 1kb of data at a time in a certain direction (i.e. 1 stream for AB, 1 stream for BA).

This works for some applications and protocols, but is not reliable - sometimes individual applications will behave differently when working through this Python relay. Some even crash.

I think this is due to the fact that when I finish reading on socket A, the program running there believes that its data has already reached B, when in fact I am an insidious person in the middle - it has not yet been sent to B. B situations where B is not ready to receive data (while send() blocks for a while), we are in a state where A considers that it successfully sent data to B, but I still keep data waiting for send() to be called fulfillment. I think this is the reason for the difference in behavior that I found in some applications using my current relay code. Am I missing something, or does it sound right?

If so, my real question is: is there a way to solve this problem? Is it possible to read only socket A, when we know that B is ready to receive data? Or is there another method that I can use to establish a truly "invisible" two-way relay between [already open and installed] TCP sockets?

+4
source share
3 answers

Is it possible to read only from socket A when we know that B is ready to receive data?

Of course: use select.select in both sockets A and B (if it returns, says that only one of them is ready, use it on the other), and only read from A and write to B when you know that they are both ready . For instance:.

 import select def fromAtoB(A, B): r, w = select.select([A], [B], []) if not r: select.select([A], [], []) elif not w: select.select([], [B], []) B.sendall(A.recv(4096)) 
+5
source

I do not think this may be your problem.

In general, the sending application cannot tell when the receiving application actually calls recv () to read the data: the send () sender can be completed, but TCP implementations in the source and destination OS will perform buffering, flow control, retransmission, etc. d.

Even without your relay in the middle, the only way for A to โ€œthink its data has already reached Bโ€ is to get a response from B saying โ€œyes, I got it.โ€

+1
source

Perhaps the application you are connecting the proxy to is poorly written.

For example, if I call recv(fd, buf, 4096, 0); , I was not promised 4096 bytes. The system is working hard to provide it.

If 1k is not a multiple of your recv or send application sizes, and the application is broken, then grouping the data sent in 1k blocks will ruin the application.

+1
source

Source: https://habr.com/ru/post/1306435/


All Articles