first - it's not a question of "how to bind to port of another software".
now, i have a client-server app, based on TCP and i'd like to make it UDP, but i'm missing something..
i have 2 rules (which i put) to this app:
1) the "server" can stay behind router without any port forwarding configuration.
2) the "client" can listen to only one port.
in TCP i do it like this:
1) the server opens initial connection to the client on port X.
2) when the client wants to open communication channel to the server it uses the initial socket to ask the server for a new one.
3) the server creates a new socket and connect to the client on port X.
4) the client accept this new connection on port X, and now the client talk with the server on this new socket.
this way i can have multiple connections on the same port.
in UDP, i have a little problem..
1) the server sends the initial connection dgram to the client on port X.
2) when the client wants to open communication channel to the server it sends request for a new socket to the initial socket's addr.
3) the server receives the message, creates a new udp socket, and use it to send data to the client on port X.
4) the client receives the new dgram, and ....?
basically what i want to happen now is to "accept" this connection. meaning: to create a new UDP socket, to bind it also to port X and receive data only from that specific incoming socket addr (ip,port). but i cannot do that because i can't bind multiple socket to same port.
so what is the way to create multiple udp connections on one port? (in networking way, not just create a ring buffer of dgrams and send to the right socket)
thanks :)
As UDP is connectionless protocol, on step 4 you check the contents of UDP message and decide how to handle it. In other words, the type of message is defined only by it's contents.
However, I have a feeling that your whole design is a bit wrong. It's much more common for the client to be behind firewall (just because there exist more clients, than servers). If you need to put the server behind firewall, you just configure the firewall to allow connections to the set of ports. Even when you have just one more port opened, nothing prevents the client from connecting to the same server port several times in parallel.
Related
I have created the Delphi application with TIdUDPServer. It listens on a specific port. I forwarded this port on the router programmatically, but I want to make sure my server is accessible from the Internet (from the outside).
Is it correct to use TIdUDPClient with the external IP address (I get it from a special website) and send "hello" to my server, which is in the same application?
I mean, what if the router will return this packet back without actually sending it to the Internet when it will see that the target IP of the packet is its own IP address?
In C++ (I didn't include code because this is more of a protocol understanding matter) I am creating a SOCKS5 server and had a few questions because the client terminates the connection after I send it the approved message. In the RFC it says BND.ADDR and BND.PORT are used for: RFC 1928
o BND.ADDR server bound address
o BND.PORT server bound
port in network octet order`
In the reply to a CONNECT, BND.PORT contains the port number that the
server assigned to connect to the target host, while BND.ADDR
contains the associated IP address.
Here are my questions,
What is BND.PORT and what should I specify for it?.
What does it mean by "server assigned to connect to the target host" Is target host the "Client"?
I've read the RFC front to back like 5 times and I have yet to understand it, can someone go into more detail about the BND.PORT and what it means?
I was sniffing around in Wireshark and I found that BND.PORT was different for each request made. (I am not sure what port to enter because everything I tried resulted in Proxifer (The socks client) says "The server gave an unexpected replay - Connection terminated"
Wireshark connection hex-dump from an actual SOCKS5 server (not mine):
Just to make sure we're on the same page... This is the relationship between client, server and host. Notice that the client and host can't talk to each other directly.
CLIENT <-> SERVER <-> HOST
What does it mean by "server assigned to connect to the target host" Is target host the "Client"?
No. The "host" is the device the client is trying to connect to via the SOCKS5 server. The "client" is on the other side of the SOCKS5 server, furthest away from the host.
What is BND.PORT and what should I specify for it?.
BND.PORT is the source port of packets leaving the SOCKS5 server, bound for a host. You have no control over what port the server chooses. Think about it. Where does a host see packets coming from? It certainly isn't the client. From the perspective of the host, packets are all coming from the server, it doesn't know about the client. Additionally the BND.ADDR is the IP of the server.
What I've said is true under the condition that CONNECT is being used. I have no experience with BIND or UDP ASSOCIATE yet.
I am working with D5 ( thats a fact ). I have Indy9 installed.
I'm trying to receive data of IdMappedPortTCP on port 8041 (SSL) and redirect the data to a Tserversocket on port 8040. So I will have support of SSL over Tserversocket.
I use the following code:
var
masterdir:String;
begin
masterdir:=Extractfilepath(paramstr(0));
IdMappedPortTCP1.Active:=false;
datamodule2.IdMappedPortTCP1.MappedHost:='192.168.0.3';
datamodule2.IdMappedPortTCP1.MappedPort:=8041;
datamodule2.IdMappedPortTCP1.DefaultPort:=8040;
IdServerIOHandlerSSL1.SSLOptions.RootCertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.CertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.KeyFile:=masterdir+'key.pem';
IdMappedPortTCP1.IOHandler:=IdServerIOHandlerSSL1;
IdMappedPortTCP1.Active:=true;
end;
If I don't use SSL everything is fine. But when I use SSL teh request never comes to the port 8040 encrypted and I need it not encrypted so I can proccess it.
It is not clear from your description whether TServerSocket is using SSL on port 8040 or not. It makes a big difference in how you set up TIdMappedPortTCP. However, from your description, you have the MappedPort and DefaultPort property assignments backwards, at least. DefaultPort is the port that TIdMappedPortTCP listens on, so it should be 8041. MappedPort is the port that TIdMappedPortTCP connects to, so it should be 8040.
It is not common to have unencrypted and encrypted connections on the same port. Most protocols use separate ports. Is that the case here? Is port 8040 unencrypted, and port 8041 encrypted?
If you want TIdMappedPortTCP to accept encrypted and unencrypted clients on separate ports, you need to add 2 entries to the TIdMappedPortTCP.Bindings collection, one for each port, and not use the DefaultPort property at all. In the TIdMappedPortTCP.OnConnect event, you can detect which port the client connected to, and then configure the AThread.OutboundClient accordingly before it connects to TServerSocket.
It is not wise to have unencrypted and encrypted clients connect to the same port. In that scenario, you have to sniff the first few bytes to know if the client is sending an SSL handshake or not, and then act accordingly. It is easier to just use separate ports instead. However, some protocols do allow a client to connect to an unencrypted port and then send a command to activate encryption when needed. In that scenario, you would only need 1 port in TIdMappedPortTCP, so you can either define 1 Binding or use DefaultPort.
TIdMappedPortTCP is primarily intended to be a straight passthrough of raw bytes back and forth between the client and the target server. If TServerSocket is using SSL and you want the client to talk to TServerSocket using SSL properly, you should not be using TIdServerIOHandlerSSL at all. Let TIdMappedPortTCP pass the client's raw encrypted data as-is to TServerSocket, and vice versa. They should establish a secure session with each other, not with you. This is especially important if either one of them performs peer identity validation.
If you need to process encrypted data that is being exchanged between the client and TServerSocket, you have to decrypt and re-encrypt the data as it passes through TIdMappedPortTCP (which means you are acting as a man-in-the-middle attacker, which peer validation is meant to prevent). To do that, you have to establish separate SSL sessions between the client and TIdMappedPortTCP, and between TIdMappedPortTCP and TServerSocket. Assigning a TIdServerIOHandlerSSL to TIdMappedPortTCP only facilitates the session with the client. You have to manually setup a session with TServerSocket. To do that, you have to manually assign a new TIdSSLIOHandlerSocket object to the AThread.OutboundClient.IOHandler property in the OnConnect event. TIdMappedPortTCP will not handle that for you.
If, however, TServerSocket is not using SSL, and you are using TIdMappedPortTCP as an SSL gateway into TServerSocket, then you can skip the OutboundClient.IOHandler assignment, since you would only need 1 SSL session, between TIdMappedPortTCP and the client.
Now, with that said, there are some problems in Indy 9. The TIdSSLIOHandlerOpenSSL.PassThrough property is False by default (thus assuming encryption is initially active), and TIdServerIOHandlerSSL assumes that every accepted client connection is using SSL, even if it really is not. If an unencrypted client connects to TIdMappedPortTCP with TIdServerIOHandlerSSL assigned, the client will not be handled correctly. These issues were fixed in Indy 10. But in Indy 9, you will not be able to handle encrypted and unencrypted clients in the same TIdMappedPortTCP component. If you are only dealing with encrypted clients though, you won't run into a problem. Otherwise, create 2 TIdMappedPortTCP components, one listening on an unencrypted port, the other listening on an encrypted port. They can share the same event handlers. If needed, you can use the AThread.Connection.Socket.Binding.Port property to know which port the client is connected to.
I have a TCP connection (proxy) that connects through socks4-5 and sends http / https / DNS traffic through it.
I need something to share, something to http / https etc. went through tcp connection 1 and dns resolve through tcp connection 2
I tried to create IdTCPServer1 (But I'm not sure on the right track), it connects but nothing sends him.
In addition, he hangs on until ReadLn it will not be recorded data, and it is not permissible.
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var str_str:String;
begin
str_str:=AContext.Connection.Socket.ReadLn();
if(str_str<>'') then Memo1.Lines.Add('#TCP_SERVER: EXECUTE: '+str_str);
You need to handle (implement) the socks4/5 server side protocol (See http://tools.ietf.org/rfc/rfc1928.txt). The in the request, you can intercept to port number to see if it is http, dns or whatever. Then you forward the connection according to it.
If you have two browser windows open and you use each to navigate to a different website, then how does the software know which HTTP response belongs to which browser instance?
Update
It seems that the distinction is made by the inbound TCP port numbers. But what about network messages that don't involve TCP/UDP? For example, if you open two terminal applications and use both send a ping message to the same remote server, how does the reply find its way to its terminal instance?
Typically, each browser instance creates its own socket to communicate with the server. Though the outbound port of all the sockets is the same (usually TCP 80 or 443), their inbound ports are different. Thus, there are no conflicts when the server responds to the requests, since the responses are sent to different inbound ports.
Tools like ping use ICMP packets, which provide their own way to uniquely identify the calling application (a unique identifier and a sequence number).
They're usually associated with different TCP connections, which between them have used different ports on the client end. This means that the TCP stack at the client end knows the different and passes them via the sockets API the client used in an easily distinguishable way. (Typically different file descriptors)
The exception to this is pipelining where multiple http request can be sent over one connection, as an optimisation. Requests sent like this are received in the order they were sent however, making it trivial to match them to the requests.