udp - client to multiple servers - c

I have looked through many pages and forums, but still am unsure about this. I am writing a project where the client reads in a txt file of numbers and sends the numbers to the server who will do some computation and send the result back to the client. Is it possible to connect a client to multiple servers using udp? and if so, an explanation would be nice. I don't think I quite understand udp fully yet. I am writing this in c also. The reason for connecting to multiple servers from one client is because I need to run the client using 1, 2, 4, and 8 servers (distributing numbers to each server until none are left) and compare the run time. Any quick help would be appreciated.

You can use UDP to multiple servers with the same socket. Probably the simplest way to do it is to have the client assign a session ID to each connection, include the session ID in each datagram it sends, and have the server return that session ID in each reply datagram it sends. Don't use the IP address to distinguish which server the packet is from because a server can have more than one IP address, making it unreliable.
Just remember that if you use UDP, you don't get any of the things TCP adds. If you need any of them, you need to do them yourself. If you need all or most of them, TCP is a much better choice. TCP does:
Session establishment
Session teardown
Retransmissions
Transmit pacing
Backoff and retry
Out of order detection and rearrangement
Sliding windows
Acknowledgments
If you need any of these things and choose to use UDP, you need to do them yourself.

Related

Deny a client's TCP connect request before accept()

I'm trying code TCP server in C language. I just noticed accept() function returns when connection is already established.
Some clients are flooding with random data some clients are just sending random data for one time, after that I want to close their's current connection and future connections for few minutes (or more, depends about how much load program have).
I can save bad client IP addresses in a array, can save timings too but I cant find any function for abort current connection or deny future connections from bad clients.
I found a function for windows OS called WSAAccept that allows you deny connections by user choice, but I don't use windows OS.
I tried code raw TCP server which allows you access TCP packet from begin including all TCP header and it doesn't accept connections automatically. I tried handle connections by program side including SYN ACK and other TCP signals. It worked but then I noticed raw TCP server receiving all packets in my network interface, when other programs using high traffic it makes my program laggy too.
I tried use libnetfilter which allows you filter whole traffic in your network interface. It works too but like raw TCP server it also receiving whole network interface's packets which is making it slow when there is lot of traffic. Also I tried compare libnetfilter with iptables. libnetfilter is slower than iptables.
So in summary how I can abort client's current and future connection without hurt other client connections?
I have linux with debian 10.
Once you do blacklisting on packet level you could get very fast vulnerable to very trivial attacks based on IP spoofing. For a very basic implementation an attacker could use your packet level blacklisting to blacklist anyone he wants by just sending you many packets with a fake source IP address. Usually you don't want to touch these filtering (except you really know what you are doing) and you just trust your firewall etc. .
So I recommend really just to close the file descriptor immediately after getting it from accept.

How do apps like LogMeIn and TeamViewer work?

There's already a question How exactly does a remote program like team viewer work which gives a basic description, but I'm interested in how the comms works once the client has registered with the server. If the client is behind a NAT then it won't have its own IP address so how can the server (or another client) send a message to it? Or does the client just keep polling the server to see if its got any requests?
Are there any open source equivalents of LogMeIn or TeamViewer?
The simplest and most reliable way (although not always the most efficient) is to have each client make an outgoing TCP connection to a well-known server somewhere and keep that connection open. As long as the TCP connection is open, data can pass over that TCP connection in either direction at any time. It appears that both LogMeIn and TeamViewer use this method, at least as a fall-back. The main drawbacks for this technique are that all data has to pass through a TeamViewer/LogMeIn company server (which can become a bottleneck), and that TCP doesn't handle dropped packets very well -- it will stall and wait for the dropped packets to be resent, rather than giving up on them and sending newer data instead.
The other technique that they can sometimes use (in order to get better performance) is UDP hole-punching. That technique relies on the fact that many firewalls will accept incoming UDP packets from remote hosts that the firewalled-host has recently sent an outgoing UDP packet to. Given that, the TeamViewer/LogMeIn company's server can tell both clients to send an outgoing packet to the IP address of the other client's firewall, and after that (hopefully) each firewall will accept UDP packets from the other client's Internet-facing IP address. This doesn't always work, though, since different firewalls work in different ways and may not include the aforementioned UDP-allowing logic.

Trying to get sockets with the same address and different ports to pass data back and forth

Firstly, please excuse my probable butchering the technical terminology. I've been thrown into socket IO with little formal education and I know that I am bungling words left and right.
I'm trying to build a client and server in C that enables multiple clients to connect to one another. The general procedure goes something like this:
1) Server has one port that is constantly listening and accepting connections
2) A client connects on that port
3) Server creates a new socket (same address, different port number), tells the client to connect to that socket, and closes the connection with the client.
4) The client connects to the designated socket and provides the server with a channel it would like to be on
5) Server places that socket on the designated channel
6) Repeat steps 2 through 5 for each client that connects to the server
/* all of the above has been coded already */
7) Once a channel has 2 or more members, I'd like to have each member port be able to broadcast to all other ports in the same channel (and thus the clients communicate with each other)
In this situation, all involved sockets on the same channel have the same address and DIFFERENT port numbers. Everything I've read and researched about broadcasting and multicasting revolves around each communicator having the same port number and different addresses.
Is there a way to do the communication that I'm hoping to do, in C?
I would think you want to use the listen() and accept() functions for TCP. You can do what you describe and have clients talk to each other, but all traffic will run through the server as a hub.
If you want all clients to be able to talk to every other client, you have a few options:
Server is the hub for all data and passes it between clients for you
Clients maintain direct connections to the other clients and pass data to each other in order to facilitate the hub. This means lots of data copying.
Broadcast or multicast (UDP). This is only possible over a local network, as internet routers will block multicast and broadcast traffic.
I would probably go with #1.
Remember that each client has it's own IP address, so for a client to communicate with another client, and not involving the server, it would need to open a new connection with the other client, send data and then close the connection. While doable, I do not think this idea would scale very well.
I do agree with Syplex that having the server act as a relay hub is probably the best, and certainly has the potential to scale well. So the data-flow would be something like this:
a client receives a message that is to be retransmitted to all the other clients.
this message is passed to all other instances of your server process
each of these instances of your server process sends out the message.
The issue becomes how you are implementing you server, and you do have two models that fit what you describe:
(1) you are using a multi-treaded server, in which each new connection causes a thread to be spawned to handle the communication between the client and the server.
(2) you are using a forking server, in which the server forks a new process to communicate with the client.
In case (1) you would be interested in intra-process communication (message queue for example) while in case (2) you would be interested in inter-process communication (named pipes or shared memory for example).
At this point there are two many variables to give a concise answer. I hope this helps gets you started and at least gives you somewhere to start looking.

Build a DNS Proxy in C

I want to build a simple DNS Proxy in C, which accepts DNS Queries from UDP Port 53, forwards the query to Google's DNS server TCP port 53 to do the lookup, and then returns the answer offered by Google.
Yes, this is a school project and I'm so confused that I don't know where to get started.
Thanks for helping!!
You've struck lucky with the requirements - because you're going from UDP -> TCP, it's actually a lot simpler than doing UDP -> UDP.
Specifically, what I mean is that because the outward facing side is using a connection orientated socket, you know straight away that the response you receive must pertain to the query you just sent, so long as you use a new TCP socket for each query.
If the outward facing side had been UDP it becomes a lot harder to figure out which query each response relates to - there's no guarantee in the protocol that responses arrive in the same order as the queries.
If multithreading isn't a requirement, then (in pseudo-code)
"open" a UDP socket
"bind" that socket to port 53
while (true) {
"recvfrom" a packet from the UDP socket
... and remember the address it was received from
"open" a TCP socket
"connect" it to Google's DNS
"write" the length of the original query (two bytes, network order - RFC 1035)
"write" the contents of the original query
"read" a two byte length header
"read" that many bytes from the TCP socket
"close" the TCP socket
"sendto" those bytes back over the UDP socket to the original client address
}
first of all you need to chose an API for writing messages on to a network.
For windows, you have Winsock API.
For unix-like systems you have the BSD Sockets API.
Although most of the courses use the BSD API.
Now your steps may be:
have a look at rfc for DNS implementation. You can only focus on format of request and response messages, as you may need to change some fields.
Now write a client server code which consists of two modules:
Server side code to receive a DNS query request, may need to change some fields.
Pass it on to the Module that interacts with Google's DNS server.
Capture the response and forward it back to requesting client. (again you may need to change some fields)

Multiple Sockets on the same port vs Multiple Sockets on multiple ports

Let me explain my scenario before asking the question.
I am in creation phase of 17 different multiplayer games that can be played online, directly from browser.
To accomplish this, I have choosed Silverlight.
Communication will be done using Sockets.
Image 17 different type of games like Chess, Backgammon, Pool and hundred of online users communicating between client app and server app using Sockets binded to the same PORT number.
Wouldn't be faster (for my server) if every different type of game will use another PORT number ? Chess will use 4502, Backgammon will use 4503, Pool 4504.
Will this make a difference ? Or should I use the same PORT number 4502 for all games with no fear that something bad can happen ?
A socket that has been established as a server can accept connection requests from multiple clients. The original server socket does not become part of the connection. The accept method makes a new socket which participates in the connection and returns this socket. The server's original socket remains available for listening for further connection requests.
So it has no advantage to use different server ports. After all web servers get all their requests on port 80 and handle this very well.
As far as speed of processing on your server goes it will most likely make very little difference whether you receive all your communications on one socket or 17. The one socket approach would be a tiny bit faster since your server application will probably have fewer threads to switch between. However there will be other things that will have a higher overhead such as actually processing the game moves or authorising client requests etc.
As for the question of whether to use one or multiple sockets the bigest thing you should think about is deployment constraints. The TCP port numbers that Silverlight is allowed to use a non-standard (i.e not 80 or 443) and if there is a firewall or proxy between your client and server you may be better sticking to a single port to make the access control list on the firewall simpler.

Resources