These are chat archives for IndySockets/Indy

5th
May 2017
irawancepu
@irawancepu
May 05 2017 00:37
@Remy I'm already doing NAT on my RB1100AHX2. Everything work fine but on this cheap DVR. However, AFTER testing it using web service from site like portchecker.co, yougetsignal.com or canyouseeme.org then it works again. Usually it will work for two or three days before did not work again. Here i need to use one of these web services again. So i think that there are some magic packets this site sends to my router. My router delivers these packet to this cheap DVR. The DVR works again after receiving these magic packets. Here i want to emulate/replicate these magic packets sent by website like portchecker.co by using Indy. Sorry for disturbing you so far. It is a real problem from a network guy facing cheap DVR.
Remy Lebeau
@rlebeau
May 05 2017 01:02
@irawancepu there is no "magic packet" being sent by those sites through the router to the DVR, that is not how those sites work. You apparently don't understand what port scanning does, because there is no actually data sent at all. The sites are merely establishing a TCP connection to the chosen IP/port and then reporting success or failure. If successful, and if the IP/Port happens to be on a NAT router, the router just passes through the connection to the specified LAN server based on its port forwarding rules. That's it. The only thing the DVR sees (if anything) is an inbound TCP connection. You could just connect a TIdTCPClient directly to the DVR to do the same thing. If you want to check the router's port status, use uPNP for that. Or, just connect TIdTCPClient to the desired public IP/port on the router.
irawancepu
@irawancepu
May 05 2017 01:21
@rlebeau Yup. I never touch port scanning in my life. I will try TCP Connection directly to ip:port on this cheap DVR periodically. I will back after two or three day, report back then. Thx for your explanation.
Sergey
@icegood
May 05 2017 08:22

@rlebeau ,
your comment makes sense in case if it hangs while calling Readable (ATimeout) in TIdIOHandler.ReadFromSource. But in reality it hangs inside call
LByteCount := ReadDataFromSource(LBuffer); a few lines below. I can imagine next multithread scenario:
1) first thread actively does IO over socket
2) second thread checks for connection and for this moment due activity of first thread Readable returns true.
3) Second thread calls ReadDataFromSource, but for this moment first thread fully has processed data => second thread hangs there.

Remobject's SuperTCPServer depends on Indy library and assumes that Indy10 supports multithread processing.

As for me fix should be in calling of just Readable inside TIdIOHandlerStack.Connected instead of ReadFromSource

Remy Lebeau
@rlebeau
May 05 2017 15:43
@icegood It is not safe for multiple threads to read from a socket at the same time. That includes calling Connected(). For exactly the reason you mentioned - it gets the socket state out of sync. I/O must be synchronized across threads. It is safe for 1 thread to write while another thread reads, that does not need to be synchronized. But having 2+ threads reading, or 2+ threads writing, must be synchronized. On the other hand, 99% of the time there is no need to call Connected() directly, just let Indy raise an exception during normal I/O operations. That being said, having Connected() call Readable() instead of ReadFromSource() is not good enough, since a socket is marked as readable during a graceful disconnect, an actual read is needed to discover the disconnect.
Sergey
@icegood
May 05 2017 22:26
Tnx, Remy!