The scenario is pretty simple:
Using TCP/IP I have a client which connects to me (server) I want to forward the data the socket sends me to another socket which I opened and the data I received from that socket backwards.Just like a proxy.
Right now I have 1 thread one who listens from incoming connection and spawns another 2 when a connection from the client is established. I must use a mechanism for communicating in the threads.
Is there anything simpler which I can use to act as a TCP/IP proxy ? Does Linux have socket forwarding or some kind of mechanism ?
You can use iptables to do port forwarding. It's not a c solution, but it is a 2-line that has good performance and which will have minimal debugging.
From the second link:
iptables -A PREROUTING -t nat -i eth1 -p tcp \
--dport 80 -j DNAT --to 192.168.1.50:80
iptables -A INPUT -p tcp -m state --state NEW \
--dport 80 -i eth1 -j ACCEPT
The first line forward from port 80 to port 80 on 192.168.1.50 and the second accepts the connection, keeping iptables from dropping it.
You can add additional constraints with other iptables flags such as -s 10.0.3.0/24 would catch all the addresses with a source of 10.0.3.0 to 10.0.3.255
One user level solution is using socat. For example, to accept connections on port 8080 and forward them to 192.168.1.50:9090 you can use:
socat TCP-LISTEN:8080,fork TCP:192.168.1.50:9090
The fork option makes socat permit multiple connections.
You don't need threads. Take a look at select(), epoll() or kqueue() in order to manage multiple sockets without any thread (if you're on Windows, it's the completion port).
This is an example of a select-based server, it will be a good start.
For simple socket forwarding, let the kernel do it. Use iptables, or one of the frontends to configure it.
If you need complicated data sniffing/mangling/forwarding for real-world use, write an iptables module.
If you need to tee (duplicate/split) the data stream, or inspect or modify the data, then read on.
Linux 2.6.17 and later, with glibc 2.5 and later, do provide a couple of nice functions: splice() and tee(). You can use these to avoid having the payload copied to and from userspace, telling the kernel to transfer a specific amount of bytes from one descriptor to another. (tee() does not consume the data, allowing you to send one or more copies of the data to other descriptors.)
You could use your two threads per connection (one per direction), and have each thread read inspect/mangle/tee the data stream as necessary. When you know you have N incoming bytes to forward to one outgoing socket, use splice(). If you have more than one outgoing socket, use nonblocking outgoing sockets, tee() small chunks at a time (but use splice() for the last outgoing socket for each chunk).
Your threads can read some/all of the incoming data to decide what to do with it, but remember that you need to write() or send() the part you already read that needs to be sent, before using splice() or tee(); they don't magically pick up already consumed data.
Related
I'm attempting to have two daemons running on the same port and IP but one is a server and the other is a client. Is there a method using socket options that would allow each socket to have a copy of the packet and let the daemons filter out the messages based on the protocol? It looks like reuse address blocks the first configured port and reuse port might just balance the packet between the two daemons.
Otherwise, I guess create another daemons to read the socket and send the packets to the correct daemon.
Thanks
You are correct at the end, you will need to have a third part that binds to the port and forwards the packets to the correct daemon.
The other way to do it would be to use three ports and use a firewall to redirect from the front end port to the backend ports; but that is a lot more complicated and not portable. But in the end you could use QOS or something. There is a wide range of possible types of use case behind the word protocol.
If the UDP packets you are receiving are multicast or broadcast packets, then you can set SO_REUSEADDR (and, for BSD-based OS's, SO_REUSEPORT) on the socket (using setsockopt()) before bind()-ing the socket, and then both sockets will receive a copy of each incoming UDP packet. (If the UDP packets are regular old unicast packets, OTOH, then doing the above will result in each received packet being received by only one of the two UDP sockets, which isn't what you want).
Note, however: You refer to the two daemons as being a "client" and a "server" -- the implication of those terms is that the two daemons are going to communicate with each other. If that is the case, then the typical approach would be to have the server-daemon bind to a well-known port number, and the client-daemon could bind to any port number (e.g. it could pass 0 as the port-number to bind(), and let the OS choose an available port-number for it). Then the client-daemon could start the conversation by sending one or more UDP packets to the server's well-known port number, and the server can find out which port the client is sending from (and therefore what port to send reply packets to) by examining the fifth argument of its recvfrom() call. In this case there is no need for the two programs to bind to the same port, and therefore no need for packet-forwarding.
I have a linux computer with a code in C that must communicate in UDP with 4 differents equipments. The computer sends differents commands to each equipment and receives responses, sometimes in parallel ...
I am a perfect beginner, and managed to communicate with one equipment using UDP socket. But now, i'm looking for a way to communicate with all these equipments, what i would like to call "multiple socket", but i don't know where to look/ what word to search to find a way ...
My linux computer is the client and all the equipment servers. I only have one eth port on the computer and will have to use a switch to have access to all the equipment. I would like to create functions like :
sendcmd(IPnumber, PORTnumber, cmd , ...)
readbuff(IPnumber, PORTnumber, buff, ...)
so i can choose which IP will received cmd ... i don't know if it's possible or if i need to open the socket, then close and redo the operation with another IP ...
So, if I ever managed to make myself understood, where should I look for a solution to my problem?
Thank you !
You can use a single UDP socket for your scenario. You can keep the socket open for the lifetime of your application.
UDP is not connection oriented. UDP sockets are also not classified into client sockets and server sockets. UDP sockets are always bound to a local port, either implicitly (typically for pure clients) or explicitly (which is usually the case for servers). In your case you do not care about the port for your UDP client.
To send to your four UDP server you can use sendto(). This lets you specify the destination IP address and port the UDP packet gets sent to.
To receive from your four UDP servers you can use recvfrom(). This will tell the IP address and port where the UDP packet came from.
You most likely want to have a receive loop of some kind. If you want to do anything else in your application you most likely want to either make recvfrom() non-blocking or you want to have the receive loop in its own thread. But this goes beyond your question.
The most important aspect of UDP is that it is not a protocol (despite its name which is misleading). It is one puzzle piece for a protocol. It is a tool to develop your own protocol. But I assume you already have a specific protocol at hand defined by your peripherals.
I'm testing SSH connection under Linux.
With using tcpdump I noticed that TCP FIN flag is set in common SSH packet data.
For testing purposes I'd like to achieve the situation where packet with TCP FIN flag is sent as a separate packet, so it would be a packet with no data, but with FIN flag set.
I've been looking for such a possibility in "man 7 socket" but didn't find.
My question is - how to achieve such a functionality in Linux? Any ideas?
Tuning a TCP connection this way can not be done and it would not make really sense to control it. If you need to produce traffic with this behavior you cannot use normal TCP sockets but need to use raw sockets where you can set the header like you want. You would of course need to re-implement all the parts of the TCP connection you need in your application just to achieve this feature.
I need to queue all tcp packets sent out from the local device programmatically so that the application I implemented using libnetfilter_queue and libpcap would start capturing packets within the queue. But the current solution I have is to manually type in,
sudo iptables -A OUTPUT -p tcp -j NFQUEUE
In the terminal before I run my application which is not acceptable as the application should queue all tcp packets and capture and show them automatically.
I would be really grateful if you experts could provide a solution so that sudo iptables -A OUTPUT -p tcp -j NFQUEUE coud be done within the application itself without the need of user typing it in the terminal every time the program is run.
Thank you :)
EDIT
Reason I am seekiing a solution to this programatically is because : until I type in iptables -F the device will hold on to the data without releasing. I want to capture the packets, which is happening now, modify it and send it without it being held in the queue :) the current code modifies the packets but it is kept in the queue until the -F command is given. I want the modified packets to be sent out to its destination without being held in the queue :)
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.