How to apply DSCP fields on SYNC-ACK packets using setsocketopt function - c

I have a TCP client and server running on Linux platform. Basically using setsocketopt I am able to mark SYNC packets. But I don't know how to apply DSCP priority to SYNC-ACK packet. I can set correct DSCP once socket is accepted on server but SYNC-ACK packet goes before application receives connected socket.
FYI, I also tried to apply DSCP on server listener socket. But Linux doesn't use that value for SYNC-ACK packets.

from this page, the SYNC_ACK is the same as SYNC which from client.

Related

How to duplicate UDP packets to two or more sockets

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.

Configuring multiple UDP sockets on a single port

I'm trying to implement a peer-to-peer chat application using UDP and I was wondering about how to scale the program to multiple users.
As I understand it, UDP needs only one socket to send and receive data using the recvfrom and sendto functions. Using the data from the address fields passed to these functions, I can determine which user I'm communicating with.
I was wondering if I could create multiple UDP sockets on the same port for each peer that I'm talking to. That way, if data comes from a peer X, then the data goes to the UDP port and gets passed to the appropriate socket that is 'bound' to X's address.
Is there anyway I could do this while still using UDP?
Yes, you can specify SO_REUSEADDR (SO_REUSEPORT on Linux) before binding the UDP socket (all sockets including the first), and then connect each socket to the appropriate target, but it's really not necessary. Just dispatch each message arriving on a single socket according to its source-address.

Cant Get Broadcasting to work in C

I used the broadcaster.c from Beej's Guide to Network Programing as well as the listner.c but am unable to make have a Broadcast packet send to the server. I have checked in Wireshark and it does send. But I cannot get the listener to receive the connection. It only seems to work for localhost and 192.168.1.56 and not for 255.255.255.255 or 192.168.1.255.
If you bound the socket to the broadcast address (either manually or INADDR_BROADCAST) or INADDR_ANY on the server part, then it would receive the broadcast, otherwise Linux will not receive the packets.
Btw, routers do not forward 255.255.255.255 broadcast. Therefore, don't use it on the infrastracture mode.

Binding 40 Sockets to 40 different IP addresses

I am writing on UDP server/client application.
I want my single server to handle 40 clients at a time. For this, I want to create 40 dedicated threads, each dedicated for one single client. Since there are 40 threads one for each client, I want to create 40 dedicated sockets as well.
But the problem that:
I don't know what will be the 40 IP addresses to which I shall bind() my sockets. (since as far as I now, I have to bind() to my Server\s IP address.) Normally I bind() to "INADDR_ANY" when there is only single socket.
But what should be the IP addresses at which I should bind() each of my 40 sockets?
Please help me. Any comment/ help is appreciated.
One common way to do this with UDP is:
Server bind() to a well known port.
Client sends the initial packet to that well known port
Server receive the first packet from a client on the well known port.
Server creates a new socket with a random port
Server replies to the client from this new socket.
Client receives the reply, notices it comes from another port than the well known
server port, and uses that port as the destination for further communication.
You'll use the getpeername() call to learn the remote address.
Keep in mind that UDP is connection-less, you'll need some way to signal the end or time out you sockets.
bind only needs the local address, not the remote address.
If you want one socket for each client, then you'll need to use different ports for each (using bind). That way, each client can send its traffic to a dedicated port, and you can have a thread for each socket/port.
It's probably a better idea to only have one socket (and one port) though, and have logic in your code to assign traffic to a thread based on the remote address (retrieved using recvfrom eg.).
The usual way is to bind a single socket and accept incoming connections. Each connection will be assigned a unique socket by accept.
As you are using UDP, I would simply use TCP as described above to let the clients know of their respective server UDP addresses.
Create a single listening socket in a dedicated listening thread.
When it receives a new packet, use the packet's remote addr/port, or put a unique clientID in the packet payload, to uniquely identify the client.
Create a new thread for that client if one does not already exist, pass the packet to that thread for further processing, and go back to listening.
If a given client thread does not receive any packets for awhile, it can terminate itself.

UDP Multicast: received by computer but not by application

I'm trying to set up an application on Linux to receive MIDI data over UDP multicast via WiFi.
Wireshark shows that the packets sent from the MIDI controller are received by my machine (paste from wireshark).
The source code from the utility I'm using to listen for network traffic and produce ALSA midi events (called multimidicast) sets up listening sockets like this. Basically it sets up 20 sockets, binds them to ports 21928-21948, calls setsockopt() with IP_ADD_MEMBERSHIP to the group for "225.0.0.37", and then starts listening. This is, as far as I can see, in line with all tutorials and advice on how to listen for UDP multicast traffic.
However, the utility does not receive data.
If, from my PC, I send packets to the relevant ports on "225.0.0.37" (s.sendto("hello", ("225.0.0.37", 21928)) in Python), the tool still doesn't receive the data. If I send to the ports on localhost (s.sendto("hello", ("", 21928))), it does receive the data.
I've been reading and experimenting quite a lot, but I can't work out what it is I'm missing. I'm not even sure whether it's an error in the code I'm using or in my box's configuration.
Could anybody shine any light on this?

Resources