I was surprised by the connect() function for UDP. I read online and realized that it enables the send() function which does not require a destination address.
I would like to know what exactly does a UDP connect do in the kernel.
I found a similar question here
UDP "Connect"-Speed in C#
but maybe some detail was left out in the answer
There is nothing real fancy with connected udp sockets. It just means that socket name will include destination address, and as such, kernel will use this name when destination address is not provided. No more than typing shortcut for all intents and purposes.
Related
I am working on making a port scanner . I can check whether ports are open or not by trying to make a connection with the port but, how I will check the open port is udp or tcp?
... how I will check the open port is udp or tcp?
What you seem to have in mind is a single street where the ports are house numbers and in each house TCP and/or UDP might live. And you knock on the door and then need to figure out if UDP or TCP opened the door. But this view is wrong.
It is more like two separate streets which just have the same house numbers. There is one street for TCP and another for UDP and you decide which street to walk by choosing the type of socket. No need to check who is living in there since in the TCP street only TCP can live and in the UDP street only UDP.
A TCP socket gets created with AF_INET (or AF_INET6) and SOCK_STREAM. A UDP socket uses SOCK_DGRAM instead of SOCK_STREAM. So you know by creating the socket what you expect, i.e. which street to walk.
Apart from that UDP does not have the concept of an actual connection: while one can connect a UDP socket this will set the destination address on the local socket. It does not actually send any data to the peer to establish a connection like done with TCP. Thus a connect on a UDP socket will basically always succeed, no matter if something is expecting traffic on the destination (i.e port is "open") or not.
A single port can have any number of services running on it, using different protocols. Connecting only means that you connected with a specific protocol, and you'll need to check the other(s).
So, while it's probably unsatisfying as an answer, if you've been probing with TCP, you've probably never found a UDP service, and vice versa. And if you've been probing with XTP or something similarly obscure you've probably never found an open port.
Of course, be careful. "Connection" has different meanings under different protocols, particularly the stream-oriented protocols like TCP. You might have "connected" in an informal sense (provoked the server to acknowledge you), but you may not be "connected" in the sense of establishing a connection where the you definitely have the server's attention.
I'm writing a network program using SFML, and as my understanding was, UDP sockets are utterly connection-less
When i try read from my socket, I'm getting a "Disconnected" error code, but the documentation doesn't seem to mention UDP sockets being able to return this kind of error (only TCP ones being able to)
What could a UDP socket being Disconnected possibly mean?
While UDP as a protocol is "connectionless", the socket APIs support virtual connections to allow connection oriented functions to continue to work. When you call connect on a UDP socket, the OS remembers the connection data you set just as it normally would and it filters things that are not consistent with the virtual connection, this allows you to use interfaces like recv, send and getpeername because the peer is implicit. If you don't use connect, then you need to use interfaces like sendmsg. sendto, recvmsg and recvfrom where the peer is being communicated on a per packet basis.
In the case of SFML, it isn't necessarily using something that needs a connection, though, it is remapping other errors such as timeouts to Disconnected.
I'm just reading about TCP and UDP and from what I've read when the packet gets encapsulated in the IP protocol and the header gets added is it not possible to create a false IP address at this stage?
Granted, the response will never be received on your connection, but is this possible?
I do not want to do this btw. I'm in no way associated with immoral ethics. It's just something that I had to ask whilst reading about TCP and UDP. I'm actually learning how to use sockets in C++ for a game I'm working on.
Yes, this is possible.
Use raw sockets and craft your own packets
Use scapy, hping, etc
Search for "packet crafting"
EDIT
A nice scapy tutorial that teaches you to send lots of valid and invalid stuff is here.
I'm trying to find a way for client to know socket server ip:port, without explicitly defining it. Generally I have a socket server running on portable device that's connect to network over DHCP (via WiFi), and ideally clients should be able to find it automaticaly.
So I guess a question is whether socket server can somehow broadcast it's address over local network? I think UPnP can do this, but I'd rather not get into it.
I'm quite sure that this question was asked on Stack lot's of times, but I could find proper keywords to search for it.
One method of doing this is via UDP broadcast packets. See beej's guide if you're using BSD sockets. And here is Microsoft's version of the same.
Assuming all the clients of the application are on the same side of a router then a broadcast address of 255.255.255.255 (or ff02::1 for IPv6) should be more than adequate.
Multicast is another option, but if this is a LAN-only thing I don't think that's necessary.
Suggestion
Pick a UDP port number (say for the sake of an example we pick 1667). The client should listen to UDP messages on 255.255.255.255:1667 (or whatever the equivalent is. e.g.: IPEndPoint(IPAddress.Any, 1667)). The server should broadcast messages on the same address.
Format Suggestion
UDP Packet: First four bytes as a magic number, next four bytes an IPv4 address (and you might want to add other things like a server name).
The magic number is just in case there is a collision with another application using the same port. Check both the length of the packet and the magic number.
Server would broadcast the packet at something like 30 second time intervals. (Alternatively you could have the server send a response only when a client sends a request via broadcast.)
Some options are:
DNS-SD (which seems to translate to "Apple Bonjour"): it has libraries on macOS, but it needs to install the Bonjour service on Windows. I don't know the Linux situation for this. So, it's multi-platform but you need external libraries.
UDP broadcast or multicast
Some other fancy things like Ethernet broadcast, raw sockets, ...
For your case (clients on a WiFi network), a UDP broadcast packet would suffice, it's multi-platform, and not too difficult to implement from the ground up.
Choosing this option, the two main algorithms are:
The server(s) send an "announce" broadcast packet, with clients listening to the broadcast address. Once clients receive the "announce" packet, they know about the server address. Now they can send UDP packets to the server (which will discover their addresses for sending a reply), or connect using TCP.
The client(s) send a "discover" broadcast packet, with the server(s) listening to the broadcast address. Once the server(s) receive the "discover" packet, it can reply directly to it with an "announce" UDP packet.
One or the other could be better for your application, it depends.
Please consider these arguments:
Servers usually listen to requests and send replies
A server that sends regular "announce" broadcast packets over a WiFi network, for a client that may arrive or not, wastes the network bandwidth, while a client knows exactly when it needs to poll for available servers, and stop once it's done.
As a mix of the two options, a server could send a "gratuitous announce" broadcast packet once it comes up, and then it can listen for "discover" broadcast requests from clients, replying directly to one of them using a regular UDP packet.
From here, the client can proceed as needed: send direct requests with UDP to the server, connect to a TCP address:port provided in the "announce" packet, ...
(this is the scheme I used in an application I am working on)
For an UDP server architecture that will have long-lived connections, one architecture is to have one socket that listens to all incoming UDP traffic, and then create separate sockets for each connection using connect() to set the remote address. My question is whether it is possible to do this atomically similar to what accept() does for TCP.
The reason for creating a separate socket and using connect() is that this makes it easy to spread the packet-processing across multiple threads, and also make it easier to have the socket directly associated with the data structures that are needed for processing.
The demultiplexing logic in the networking stack will route the incoming packets to the most specific socket.
Now my question is basically what happens when one wants to emulate accept() for UDP like this:
Use select() with a fd-set that includes the UDP server-socket.
Then read a packet from the UDP server-socket.
Then create a new UDP socket which is then connect()ed to the remote address
I call select() with a fd-set that includes both sockets.
What is returned?
given that a packet arrives to the OS somewhere between 1 and 3.
Will the packet be demultiplexed to the UDP server-socket, or will it be demultiplexed to the more specific socket created in 3. That is, at what point does demultiplexing take place? When the packet arrives, or must it happen "as if" it arrived at point 4?
Follow-up question in case the above does not work: What's the best way to do this?
I see that this discussion is from 2009, but since it keeps popping up when I search, I thought I should share my approach. Both to get some feedback and because I am curios about how the author of the question solved the problem.
The way I chose emulate UDP-accept was a combination of number one and two in nik's answer. I have a root thread which listens on a given socket. I have chosen to use TCP for simplicity, but changing this socket to UDP is not very hard. When a client wants to "connect" to my server using UDP, it first connects to the TCP socket and requests a new connection.
The root thread then proceeds by creating a UDP socket, binds it to a local interface, does connect and sets up data structures. This file descriptor is then passed to the thread that will be responsible for the connection. The IP/port information of the new UDP socket is passed back to the client, which creates a new UDP socket and sends data to the provided IP/port.
This approach works well for my use, but the additional steps for setting up a flow introduces an overhead. In some cases, this overhead might not be acceptable.
I found this question after asking it myself here...
UDP server and connected sockets
Since connect() is available for UDP to specify the peer address, I wonder why accept() wasn't made available to effectively complete the connected UDP session from the server side. It could even move the datagram (and any others from the same client) that triggered the accept() over to the new descriptor.
This would enable better server scalability (see the rationale behind SO_REUSEPORT for more background), as well as reliable DTLS authentication.
This will not work.
You have two simple options.
Create a multi-threaded program that has a 'root' thread listening on the UDP socket and 'dispatching' received packets to the correct thread based on the source. This is because you want to segregate processing by source.
Extend your protocol so the the sources accept an incoming connection on some fixed port and then continue with the protocol communication. In this case you would let the source request on the standard UDP port (of your choice), then your end will respond from a new UDP socket to the sources' UDP port. This way you have initiated a new UDP path from your end backwards to the known UDP port of each source. That way you have different UDP sockets at your end.