I have multiple TCP Socket servers waiting for connection (one per machine). On another machine is a client which connects to these servers in order to perform some configuration.
Is there a way for me to see which hosts are on the network waiting for connection (preferably without knowing their IPs). Is there some way for the host to 'announce' that it is there and waiting for a connection?
All clients/hosts are on the same subnet.
Each server could certainly broadcast/multicast its listening info to the subnet at regular intervals. But that is a lot of redundant traffic.
An alternative is to have the client broadcast a request to the subnet that the servers all listen for, and then they can reply directly to the client with their listening info.
Otherwise, the client could just calculate the available IPs for the subnet and then attempt a connection to each IP/port to see which ones succeed or fail (typical port scanning scenario).
Related
If I am building a WebRTC app and using a Selective Forwarding Unit media server, does this mean that I will have no need for STUN / TURN servers?
From what I understand, STUN servers are used for clients to discover their public IP / port, and TURN servers are used to relay data between clients when they are unable to connect directly to each other via STUN.
My question is, if I deploy my SFU media server with a public address, does this eliminate the need for STUN and TURN servers? Since data will always be relayed through the SFU and the clients / peers will never actually talk to each other directly?
However, I noticed that the installation guide for Kurento (a popular media server with SFU functionality) contains a section about configuring STUN or TURN servers. Why would STUN or TURN servers be necessary?
You should still use a TURN server when running an SFU. To understand diving into ICE a little bit will help. All SFUs work a little differently, but this is true for most.
For each PeerConnection the SFU will listen on a random UDP (and sometimes TCP port)
This IP/Port combination is giving to each peer who then attempts to contact the SFU.
The SFU then checks the incoming packets if they contain a valid hash (determined by upwd). This ensures there is no attacker connecting to this port.
A TURN server works by
Provides a single allocation port that peers can connect to. You can use UDP, DTLS, TCP or TLS. You need a valid username/password.
Once authenticated you send packets via this connection and the TURN server relays them for you.
The TURN server will then listen on a random port so that others can then send stuff back to the Peer.
So a TURN server has a few nice things that an SFU doesn't
You only have to listen on a single public port. If you are communicating with a service not on the internet you can just have your clients only connect to the allocation
You can also make your service available via UDP, DTLS, TCP and TLS. Most ICE implementations only support UDP.
These two factors are really important in government/hospital situations. You have networks that only allow TLS traffic over port 443. So a TURN server is your only solution (you run your allocation on TLS 443)
So you need to design your system to your needs. But IMO you should always run a well configured TURN server in real world environments.
My task is to determine the connectivity of a single browser client. I was wondering if the emitted Local ICE Candidates are any indication to the client's connectivity. So examining a candidate originating from google's STUN server:
mid: audio, candidate: a=candidate:941443129 2 udp 1845501695 2.84.19.92 49669 typ srflx raddr 192.168.1.2 rport 49669 generation 0
I can see my public ip 2.84.19.32 and i can also view my local, behind the NAT, ip 192.168.1.2. At this point i also know that the browser is listening on UDP port 49669 and waiting for connections. Can i infer at this point that the STUN client has made a successful connection to my public ip and port?
I understand it is ICE's job to determine if a connection is possible to that Candidate, but is it possible to determine connectivity with a single client (browser)?
My ultimate question / task, is to tap into the ICE process and know for a fact if the [single] client is behind a NAT and what type of NAT that is. Is that possible?
The presence of candidates doesn't give the information that you have connectivity. But if you analyze the content of them, you can conclude some things.
You need to take into account what STUN/TURN servers you are using.
If nothing is defined you can still have candidates, if the device is connected in a network and has an IP attributed (even if the network has no access to the Internet), you will only have candidates with local IP address.
If you define a server, and you get candidates with other types than host, it means that you have connection (at least connection to the defined STUN/TURN server, that is supposed to be outside of your machine).
To know if you are behind a NAT, you can check the presence of host candidates with local IP's.
After you get a candidate, it means that that host:ip is accessible from the internet. That's the whole idea of contacting a external STUN/TURN server. Is to open that ports... But, the fact that they are accessible, doesn't mean that you will receive attacks. You can in fact receive, but that is where the key negotiation enters and checks that only other peer (the ones with the keys) can "establish a connection" to that host:port
There are two ways to get this data out of the webRTC connection object:
pc.iceConnectionState, this tells you the connection process
pc.iceGatheringState, this is about the 'getting' of the ice candidates
But both don't really seem to work, as I am behind a firewall which blocks the RTC, but pc.iceConnectionState still gives me connected, but you might give it a go and see if it works for you.
I want to create a Console Application in VB that broadcasts to all IPs on Local Area Network his own Ip.
So a Timer that broadcasts the IP of the server every second. Every client that connects, receives the IP of the Server.
Then, a client logs in to the Application and sends 2 strings to the Servers IP:
Username
Password
The server checks the validity of the 2 strings, and either allows or restricts access to the Server.
How should I proceed?
I have found TcpClient and TcpListener, but I am unable to broadcast an IP to 255.255.255.255...
Mainly, what I want to achieve, is broadcast (255.255.255.255) my Local Ip (192.168.1.1), so I would broadcast the String "192.168.1.1"
You should take a look at the UDP classes instead of the TCP classes. UDP will allow you to broadcast small messages on your LAN. One the IP address is received, then you can use TCP to connect to the server.
How does a web-server serve its client using the same port(80) for a TCP connection. For a UDP connection, i understand that there is no connection, per se, so we can have multiple clients send packets to same port. If i try to use an already used port on my localhost, i get BindException.
One solution i see to this is starting a thread for each connection, but wouldnt this be cumbersome for site like google/yahoo where there a >100000 connections in each server?
What solutions do web servers employ for this problem?
Server listens on a well-known port (80) and delegate the request to a worker socket once it receive the request. That way it can serve the next request. You can write your own simple server to understand whats going on. Oracle site has a nice example code. [1]
[1] http://java.sun.com/developer/technicalArticles/Networking/Webserver/WebServer.java
first it creates a server socket;
ServerSocket ss = new ServerSocket(port);
then it listnes on the specified port and create a new socket once it accepts the request;
Socket s = ss.accept();
As shown in the code, it has a worker thread pool, so at a given moment you can control the number of request get served by the server at a given time. Others wait in a Queue may be.
You only have one port for listening, but a connection has two ports, one on each side of the connection. This pare must be unique.
So, say you connect to google.com port 80, then your connection will have some port on your machine, say 42312 and port 80 at google.com. You can see your connections with netstat -a. To get a shorter list: netstat -an| grep ESTABLISHED" Which shows all established connections without resolving their IPs to names.
AFAIK, Apache will start a new thread for every request, which is a big reason that event driven servers like Node.js are a little faster. Google and Yahoo also have TONS of servers and spread this large processing load among them. What Roger says also makes sense, although I'm not 100% sure on the details of how exactly google doing output on port 42312 would reach your computer at port 80 :P
Is it not possible to specify the local client port used for server calls via NetTcpBinding?
NetPeerTcpBinding support this - I find it hard to believe there's no way to specify the local port (and IP Address for that matter) on clients.
I need to be able to use port sharing and I can't do this if I don't know what port the client is listening on. I won't be able to share the port (and IP) with another client so it can connect.
The only work-around I found is something like this:
Client A opens a connection to Server
Server logs the IP and Port of Client A
Server shares this info. with
Client B
Client B should be able to
connect to Client A on specified IP
and Port (in theory)
This is known as TCP/IP NAT hole punching I believe. Anyone with experience in this?
You probably don't understand the communication pattern with NetTcpBinding. It works this way:
The client opens connection to the server
Two-way communication: The client calls the server and gets the response over the same connection.
Duplex communication: The client calls the server. The server stores reference to the channel somewhere (you must implement this). Once the server wants to notify client about anything it takes stored channel and calls the client on the connection established by the client during its first call.
The server never opens connection to the client. The client doesn't expose any address with port for incomming communication. If you want to do that you must implement service on the client in the same way you did it on the server and you must manully send the address and port to the service exposed by the server.
The difference with NetPeerTcpBinding is that there is no real server and any client must be able to get incomming request. NetTcpBinding is for client-server scenarios where the server is the only peer able to process incomming requests. Because of that only the server needs to define an address and a port.