I am writing an application in C using socket programming. I wish to send the data from the server node to the client node. I use the read and write commands on the socket descriptor to get and send the data over the network respectively. Since, the underlying protocol used is TCP/IP, finally I receive the correct data. Is it possible to check on the client side that to receive the data correctly, how many packets were actually lost and re-transmitted? I am writing this application in Linux (debian) environment.
Any help is highly appreciated !
-Rahulkumar
/proc/net/tcp has a field retrnsmt, you simply need to find your socket in this list.
An alternative would be to use the TCP_INFO sockopt. The current layout of struct tcp_info can be found in linux/tcp.h. The field you want to use is probably tcpi_retrans.
Related
I need to write a proxy server in C language on Linux (Ubuntu 20.04). The purpose of this proxy server is as follows. There're illogical governmental barriers in accessing the free internet. Some are:
Name resolution: I ping telegram.org and many other sites which the government doesn't want me to access. I ask 8.8.8.8 to resolve the name, but they response of behalf of the server that the IP may be resolved to 10.10.34.35!
Let's concentrate on this one, because when this is solved many other problems will be solved too. For this, I need to setup such a configuration:
A server outside of my country is required. I prepared it. It's a VPS. Let's call it RS (Remote Server).
A local proxy server is required. Let's call it PS. PS runs on the local machine (client) and knows RS's IP. I need it to gather all requests going to be sent through the only NIC available on client, process them, scramble them, and send them to RS in a way to be hidden from the government.
The server-side program should be running on RS on a specific port to get the packet, unscramble it, and send it to the internet on behalf of the client. After receiving the response from the internet, it should send it back to the client via the PS.
PS will deliver the response to the client application which originates the request. Of course this happens after it will unscramble and will find the original response from the internet.
This is the design and some parts is remained gloomy for me. Since I'm not an expert in network programming context, I'm going to ask my questions in the parts I'm getting into trouble or are not clear for me.
Now, I'm in part 2. See whether I'm right. There're two types of sockets, a RAW socket and a stream socket. A RAW socket is opened this way:
socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
And a stream socket is opened this way:
socket(AF_INET, SOCK_STREAM, 0);
For RAW sockets, we use sockaddr_ll and for stream sockets we use sockaddr_in. May I use stream sockets between client applications and PS? I think not, because I need the whole RAW packet. I should know the protocol and maybe some other info of the packet, because the whole packet should be retrieved transparently in RS. For example, I should know whether it has been a ping packet (ICMP) or a web request (TCP). For this, I need to have packet header in PS. So I can't use a stream socket, because it doesn't contain the packet header. But until now, I've used RAW sockets for interfaces and have not written a proxy server to receive RAW packets. Is it possible? In another words, I've the following questions to go to next step:
Can a RAW socket be bound to localhost:port instead of an interface so that it may receive all low-level packets containing packet headers (RAW packets)?
I may define a proxy server for browser. But can I put the whole system behind the proxy server so that packets of other apps like PING may route automatically via it?
Do I really need RAW sockets in PS? Can't I change the design to suffice the data I got from the packets payload?
Maybe I'm wrong in some of the concepts and will appreciate your guidance.
Thank you
Can a RAW socket be bound to localhost:port instead of an interface so that it may receive all low-level packets containing packet headers (RAW packets)?
No, it doesn't make sense. Raw packets don't have port numbers so how would it know which socket to go to?
It looks like you are trying to write a VPN. You can do this on Linux by creating a fake network interface called a "tun interface". You create a tun interface, and whenever Linux tries to send a packet through the interface, instead of going to a network cable, it goes to your program! Then you can do whatever you like with the packet. Of course, it works both ways - you can send packets from your program back to Linux through the tun interface, and Linux will act like they just arrived on a network cable.
Then, you can set up your routing table so that all traffic goes to the tun interface, except for traffic to the VPN server ("RS"), which goes to your real ethernet/wifi interface. Otherwise you'd have an endless loop where your VPN program PS tried to send packets to RS but they just went back to PS.
(I'm new to network programming, and I am working on C in Linux)
I followed Beej's guide for a simple UDP listener-talker and I know how to create a socket and send that to a destination (with calls to getaddrinfo() and socket() using SOCK_DGRAM)
See http://beej.us/guide/bgnet/output/html/multipage/clientserver.html#datagram.
In my distributed app, I will need to send a message to multiple peers (reliable multicast).
My question is: do I need to create a socket for each of the peers? I'm worried about scalability. Or should I create the socket, use it and destroy it (close it) after each message?
In summary, is there a good way to send a UDP packet to multiple destinations, periodically?
Thanks for the help!
For UDP, you need but one local socket. You can send a packet to any destination you like from that one, single socket.
Also, you don't need to destroy and recreate the socket after each message. Just keep the socket open, and keep sending messages.
I am writing a C program where for every new request to be processed by server, I need to open a new TCP connection? That is every request from client needs to be handled by a separate TCP connection to a server listening on a particular port.
Can someone help me in code pointers?
How to maintain array of this socket identifiers (multiple sockets that needs to be opened)
How will I be able to read (Need to scroll through all open sockets and see if something interesting is to be read upon that socket)
Any code snippet will be highly useful?
You can use the select() function (assuming you are working with <sys/socket.h>), "gives you the power to monitor several sockets at the same time. It'll tell you which ones are ready for reading, which are ready for writing, and which sockets have raised exceptions" from http://beej.us/guide/bgnet/ (here you can download a pretty good book on network programming basics).
For a server example using select check http://beej.us/guide/bgnet/examples/selectserver.c
Hope it helps
If you need to save state with the socket, put it in a struct together with the data you need, and link the structures together as a list. For checking which sockets are ready see Maluchi's answer.
I want to send the two different packets in different port numbers parallely using UDP.
Can I achive this using single socket() or should I create another socket??
Can anbody give me some idea on this.
Thanks in advance
You can use a single socket, you will be using the system calls sendto(2) and recvfrom(2) to send and receive data over the datagram sockets.
Take a look at https://beej.us/guide/bgnet/html/multi/syscalls.html for more information (the entire guide is definitely worth the read).
Beej's guide on socket programming
I've not a clear idea about when I have to use the bind() function.
I guess it should be used whenever I need to receive data (i.e. recv() or recvfrom() functions) whether I'm using TCP or UDP, but somebody told me this is not the case.
Can anyone clarify a bit?
EDIT I've read the answers but actually I'm not so clear. Let's take an example where I have an UDP client which sends the data to the server and then has to get a response. I have to use bind here, right?
This answer is a little bit long-winded, but I think it will help.
When we do computer networking, we're really just doing inter-process communication. Lets say on your own computer you had two programs that wanted to talk to each other. You might use pipe to send the data from one program to another. When you say ls | grep pdf you are taking the output of ls and feeding it into grep. In this way, you have unidirectional communication between the two separate programs ls and grep.
When you do this, someone needs to keep track of the Process ID (PID) of each process. That PID is a unique identifier for each process and it helps us track who the "source" and "destination" processes are for the data we want to transfer.
So now lets say you have data from a webserver than you want to transfer to a browser. Well, this is the same scenario as above - interprocess communication between two programs, the "server" and "browser".
Except this time those two programs are on different computers. The mechanism for interprocess communication across two computers are called "sockets".
So great. You take some data, lob it over the wire, and the other computer receives it. Except that computer doesn't know what to do with that data. Remember we said we need a PID to know which processes are communicating? The same is true in networking. When your computer receives HTML data, how does it know to send it to "firefox" rather than "pidgin"?
Well when you transmit network data, you specify that it goes on a specific "port". Port 80 is usually used for web, port 25 for telnet, port 443 for HTTPS, etc.
And that "port" is bound to a specific process ID on the machine. This is why we have ports. This is why we use bind(). In order to tell the sender which process should receive our data.
This should explain the answers people have posted. If you are a sender, you don't care what the outgoing port is, so you usually don't use bind() to specify that port. If you are a receiver, well, everyone else has to know where to look for you. So you bind() your program to port 80 and then tell everyone to make sure to transmit data there.
To answer your hw question, yes, your probably want to use bind() for your server. But the clients don't need to use bind() - they just need to make sure they transmit data to whatever port you've chosen.
After reading your updated question. I would suggest not to use bind() function while making client calls. The function is used, while writing your own server, to bind the socket (created after making a call to socket()) to a physical address.
For further help look at this tutorial
bind() is useful when you are writing a server which awaits data from clients by "listening" to a known port. With bind() you are able to set the port on which you will listen() with the same socket.
If you are writing the client, it is not needed for you to call bind() -- you can simply call recv() to obtain the data sent from the server. Your local port will be set to an "ephemeral" value when the TCP connection is established.
You use bind whenever you want to bind to a local address. You mostly use this for opening a listening socket on a specific address/port, but it can also be used to fix the address/port of an outgoing TCP connection.
you need to call bind() only in your server. It's needed especially for binding a #port to your socket.