I have an FPGA device with which my code needs to talk. The protocol is as follows:
I send a single non-zero byte (UDP) to turn on a feature. The FPGA board then begins spewing data on the port from which I sent.
Do you see my dilemma? I know which port I sent the message to, but I do not know from which port I sent (is this port not typically chosen automatically by the OS?).
My best guess for what I'm supposed to do is create a socket with the destination IP and port number and then reuse the socket for receiving. If I do so, will it already be set up to listen on the port from which I sent the original message?
Also, for your information, variations of this code will be written in Python and C#. I can look up specific API's as both follow the BSD socket model.
This is exactly what connect(2) and getsockname(2) are for. As a bonus for connecting the UDP socket you will not have to specify the destination address/port on each send, you will be able to discover unavailable destination port (the ICMP reply from the target will manifest as error on the next send instead of being dropped), and your OS will not have to implicitly connect and disconnect the UDP socket on each send saving some cycles.
You can bind a socket to a specific port, check man bind
you can bind the socket to get the desired port.
The only problem with doing that is that you won't be able to run more then one instance of your program at a time on a computer.
You're using UDP to send/receive data. Simply create a new UDP socket and bind to your desired interface / port. Then instruct your FPGA program to send UDP packets back to the port you bound to. UDP does not require you to listen/set up connections. (only required with TCP)
Related
I'm working on simple traffic tunneling solution (Linux).
Client side creates tun interface, routes all traffic on it, packages all arrived packets and sends to the server side via udp or tcp connection.
Server side expected to work like NAT. Change source ip address, source port (for tcp/udp) put packet on external network interface via sock_raw, listen for response via sock_raw, keep map of original-source-port <-> replaced-source-port and send responses back to the client.
The question is: how should I choose replaced-source-port ? OS chooses them from ephemeral ports. I can't choose it by myself, it would cause conflicts. OS kernel chooses port after I send packet via sock_raw and I have no chance to build original-source-port <-> replaced-source-port map. Even if I choose port by myself – OS kernel will reply with tcp rst to all incoming tcp packets with dst port not associated with particular app.
P.S. I'm not sure on the overall solution for tunneling too. Your suggestions would be highly appreciated.
How do we know port is listening?
Is there possible to know that port is listening, even if they do not respond?
i.e. when I just bind socket in some programs, but I really do not send ACK back.
1: Packet is received and analyzed.
2: If packet fit meets, ACK is send back.
Like if I can program this thing, or it's networks card HW that is responsible for ACK.
How do we know port is listening?
Your local stack knows. An application needs to register the port.
Is there possible to know that port is listening, even if they do not respond?
If there's no reponse to a SYN sent out the host may be unreachable, the destination port not listening, or the SYN filtered.
i.e. when I just bind socket in some programs, but I really do not send ACK back.
You don't have to worry about SYN and ACK, that's handled by the OS's IP stack. Just set up a listener on destination and then connect the socket from source. If the socket opens you can start talking through the pipe.
Like if I can program this thing, or it's networks card HW that is responsible for ACK.
ACKs are part of the TCP transport protocol handled by the OS's IP stack.
You can find out the list of sockets and connections using netstat command. Use netstat -a and grep for the port in question. You can find out if there is a socket listening on the port you want.
I'm on Windows 7, using bind before connect with SO_REUSEADDR, and setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.
Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid. But the port is selected before the connection, so is there a way to get it? (getsockname() looks like to not work).
Secondly, about the source IP, is there a way to get it before a packet is sent to the server? I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake. The connect() function dominates the both.
I'm on Windows 7, using bind before connect with SO_REUSEADDR
Why are you using SO_REUSEADDR in this situation? You don't need it, and it makes no sense for what you are attempting. SO_REUSEADDR should typically only be used for a listening socket, not a connecting socket.
setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.
It is meaningless to bind() a client socket to INADDR_ANY:0. You can (and should) omit such a bind() completely and leave the socket unbound until connect() is called. The only time you should ever bind() a client socket is if you want to bind it to a specific local IP and/or Port. But you are not doing that in this situation, so get rid of it.
Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid.
Correct, unless you bind() to a specific source IP.
But the port is selected before the connection
Both source IP and source port are selected by connect() if the socket is unbound, or bound to source IP INADDR_ANY and/or source port 0. So you have no opportunity to query either value before connect() has selected them.
so is there a way to get it? (getsockname() looks like to not work).
getsockname() is exactly what you need. Just make sure you are not calling it until connect() has successfully connected to the server first. This is stated in the getsockname() documentation:
This call is especially useful when a connect call has been made without doing a bind first; the getsockname function provides the only way to determine the local association that has been set by the system.
...
The getsockname function does not always return information about the host address when the socket has been bound to an unspecified address, unless the socket has been connected with connect or accept (for example, using ADDR_ANY). A Windows Sockets application must not assume that the address will be specified unless the socket is connected. The address that will be used for the socket is unknown unless the socket is connected when used in a multihomed host. If the socket is using a connectionless protocol, the address may not be available until I/O occurs on the socket.
Secondly, about the source IP, is there a way to get it before a packet is sent to the server?
For TCP, you can retrieve the selected source IP using getsockname() immediately after connect() has successfully connected to the server. Not before.
I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake.
It is not possible to determine that detail. No socket application should ever need that detail. Why do you need it?
I'm on Windows 7, using bind before connect with SO_REUSEADDR, and setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.
Why? That's exactly what happens if you don't call bind() at all, during connect(). Binding a client socket to INADDR_ANY isn't correct in any case. Setting SO_REUSEADDR doesn't make sense either without specifying a non-zero port number. Just remove all this.
Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid.
Correct.
But the port is selected before the connection, so is there a way to get it?
Yes. getsockname().
(getsockname() looks like to not work)
Doesn't work how?
Secondly, about the source IP, is there a way to get it before a packet is sent to the server?
You can get it with getsockname() as soon as connect() has succeeded, but this involves sending packets to the server.
I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake. The connect() function dominates the both.
Bad luck.
I'm studying socket programming, and the server socket accept() is confusing me. I wrote two scenarios for server socket accept(), please take a look:
When the server socket does accept(), it creates a new (client) socket that is bound to a port that is different from the port the server socket is bound. So socket communication is done via newly bound port, and the server socket (for accept() only) is waiting for another client connection on the originally bound port.
I think this is not quite correct, because (1) a port matches to a single process and (2) socket accept is inside-process matter and single process can have multiple sockets. So thought of a second scenario, based on some of stackoverflow answers:
When a server socket does accept(), it creates a new (client) socket that is not bound to any specific port. When a client communicates with the server, it uses the port that is bound to the server socket (who accept()s connections) and which client socket to actually communicate is resolved by (sourceIP, sourcePort, destIP, destPort) tuple from TCP header(?) at Transmission level (this is also suspicious because I thought socket is somewhat of an application-level object)
This scenario also raises some questions. If the socket communications still use server socket's port, i.e. client sends some messages to the server socket port, doesn't it use the server socket's backlog queue? I mean, how can messages from a client be distinguished between connect() and read() or write()? And how can they be resolved to each client socket in the server, without any port binding?
If one of my scenarios is correct, would that answer to the questions following? Or perhaps, both of my scenarios are wrong. I'd be very thankful if you could guide me to correct answers, or at least, towards some relevant texts to study.
When you create a socket and do a bind on that socket and then a listen, what you have is what is called a listening socket.
When a connection is establised this socket is basically cloned to a new socket, and this socket is called the servicing socket the port to which it bound is still the same as the original port.
But there is an important distinction between this socket and the listening socket from before. Namely it is part of a socket pair.
It is the socket pair that uniquely identifies the connection. so as there are 2 sockets in the picture for a socket pair, there are 2 IP adresses and 2 ports for both ends of the TCP communication channel. During the cloning of the servicing socket, the TCP kernel will allocate what is called a TCB and in it it will store those 2 IP# and 2 ports. The TCB also contains the socket number that belongs to the TCB.
Each time a TCP segment comes in , the TCP header is checked and whether or not it is a SYN, for a SYN you would have connection establishment so that you passed already, but then the kernel is going through its list of listening sockets. If it is a normal TCP packet, not a SYN, both port numbers are in the TCP header and the IP# are part of the IP header, so using this information the kernel is able to find the TCP that belongs to this TCP connection. (For a SYN, this information is also there, but as I said, for a SYN you have to process only the listening sockets)
That is in a nutshell how it works.
This information can be found in UNIX Network Programming: the sockets networking API. In there the link to the sockets is described whereas in other reference material it is usually not described that much in detail, rather the nitty grits of TCP are usually highlighted.
When server socket do accept(), it creates a new (client) socket that is bind to port that is different from the port server socket is bind. So socket communication is done via newly bind port, and server socket (for accept() only) is waiting for another client connection on originally bind port.
No.
I think this is not quite proper answer
It is a wrong answer.
because (1) port matches to a single process
That doesn't mean anything relevant.
and (2) socket accept is inside-process matters
Nor does that. It doesn't appear to mean anything at all actually.
and single process can have multiple sockets.
That's true but it doesn't have any bearing on why your answer is wrong. The reason your answer is wrong is because no second port is used.
When server socket do accept(), it creates a new (client) socket that is not bind to any specific port
No. It creates a second socket that inherits everything from the server socket: port number, buffer sizes, socket options, ... everything except the file descriptor and the LISTENING state, and maybe I forgot something else. It then sets the remote IP:port of the socket to that of the client and puts the socket into ESTABLISHED state.
and when client communicates with the server
The client has already communicated with the server. That's why we are creating this socket.
it uses the port that is bind to server socket (who accept()s connections) and which client socket to actually communicate is resolved by (sourceIP, sourcePort, destIP, destPort) tuple from TCP header(?) at Transmission level
This has already happened.
This is also suspicious because I thought socket is somewhat application-level object)
No it isn't. A socket is a kernel-level object with an application-level file descriptor to identity it.
If the socket communications still use server socket's port, i.e. client sends some messages to server socket port, doesn't it uses server socket's backlog queue?
No. The backlog queue is for incoming connect requests, not for data. Incoming data goes into the socket receive buffer.
I mean, how can messages from client be distinguished between connect() and read() or write()?
Because a connect() request sets special bits in the TCP header. The final part of it can be combined with data.
And how can they be resolved to each client sockets in server, WITHOUT any port binding?
Port binding happens the moment the socket is created in the call to accept(). You invented this difficulty yourself. It isn't real.
If one of my scenario is correct, would answer to the questions following?
Neither of them is correct.
Or possibly I'm making two wrong scenarios, so it would be very thankful for you to provide right answers, or at least some relevant texts to study.
Surely you already have relevant texts to study? If you don't, you should read RFC 793 or W.R. Stevens, TCP/IP Illustrated, volume I, relevant chapters. You have several major misunderstandings here.
From the Linux programmer's manual, as found via man 2 accept. Link
The accept() system call is used with connection-based socket
types (SOCK_STREAM, SOCK_SEQPACKET). It extracts the first connection
request on the queue of pending connections for the listening socket,
sockfd, creates a new connected socket, and returns a new file
descriptor referring to that socket. The newly created socket is not
in the listening state. The original socket sockfd is unaffected by
this call.
So what happens is that you have a listening TCP socket. Someone requests to connect().
You then call accept(). The old listening socket remains in listening mode, while a new socket is created in connected mode. Port is the original listening port.
That does not interfere with the listening socket, because the new socket does not listen for incoming connections.
After many hours, I have discovered that the given udp server needs the following steps for a successful communication:
1- Send "Start Message" on a given port
2- Wait to receive from server on any port
3- Then the port dedicated to you to send further data to the server equals the port you have received on it + 1
So I am asking if this kind is a known protocol/handshaking, or it is only special to this server??
PS: All above communication were in udp sockets in C#
PS: Related to a previous question: About C# UDP Sockets
Thanks
There's no special "handshake" for UDP -- each UDP service, if it needs one, specifies its own. Usually, though, a server doesn't expect the client to be able to listen on all of its ports simultaneously. If you mean that the client expects a message from any port on the server, to the port the client sent the start message from, then that makes a lot more sense -- and is very close to how TFTP works. (The only difference i'm seeing so far, is that TFTP doesn't do the "+ 1".)
The server is, effectively, listening on a 'well known port' and then switching subsequent communications to a dedicated port per client. Requiring the client to send to the port + 1 is a little strange
Client 192.168.0.1 - port 12121 ------------------------> Server 192.168.0.2 - port 5050
Client 192.168.0.1 - port 12121 <------------------------ Server 192.168.0.2 - port 23232
Client 192.168.0.1 - port 12121 ------------------------> Server 192.168.0.2 - port 23232 + 1
<------------------------ Server 192.168.0.2 - port 23232
------------------------> Server 192.168.0.2 - port 23232 + 1
The server probably does this so that it doesn't have to demultiplex the inbound client data based on the client's address/port. Doing it this way is a little more efficient (generally) and also has some advantages, depending on the design of the server, as on the server there's a 'dedicated' socket for you which means that if they're doing overlapped I/O then the socket stays the same for the whole period of communications with you which can make it easier and more efficient to associate data with the socket (this way they can probably avoid any lookups or locking to process each datagram). Anyway, enough of that (see here, if you want to know why I do it that way).
From your point of view as a client (and I'm assuming async sockets here) you need to first Bind() your local socket (just use INADDR_ANY and 0 to allow the OS to pick the port for you) then issue a RecvFrom() on the socket (so there's no race between you sending data to the server on this socket and it sending you data back before you issue a recv). Then issue a SendTo() to the 'well known port' of the server. The server will then send you back some data and your RecvFrom() will return you the data and the address that the server sent to you from. You can then take that address, add one to the port, store that address and from then on issue SendTo()s to that new sending address whilst continuing to issue RecvFrom()s for reading the server's data; or you could do something clever with Connect() to bind the remote end of the socket to the server's 'send to address' and simply use Write() and RecvFrom() from then on.